vue - vue实现移动端固定头部和首列的table表格
vue实现移动端固定头部和首列的table表格
·
vue实现移动端固定表格表头和左侧的table表格;
效果图如下:用到的模拟数据放到文章的最后面了;
主要实现的功能:
1,固定表格表头和左侧,可以进行上滑和左滑;
2,高亮显示合计行;
3,排序功能,点击实时切换正序和倒序;

1,vue组件代码如下:
<template>
<div class="organizationTrend">
<div class="main">
<table cellspacing="0">
<thead>
<tr>
<th v-for="item in titleList" :key="item.key" :style="{ background: item.backgroundColor }">
<div class="thDis" @click="sortTap(item)">
<span> {{ item.name }}</span>
<div v-if="item.sort" class="o">
<span :class="{ sa: sortKey === item.key && sortCls === 'sa' }" class="s"></span>
<span :class="{ xa: sortKey === item.key && sortCls === 'xa' }" class="x"></span>
</div>
</div>
</th>
</tr>
</thead>
<tbody>
<!-- 合计行数据 -->
<tr class="count">
<td>{{ totalList[0].comname2 }}</td>
<td>{{ totalList[0].noCarPremium }}</td>
<td>{{ totalList[0].premium }}</td>
<td>{{ totalList[0].premiumHuanbi }}</td>
<td>{{ totalList[0].premiumPer }}</td>
<td>{{ totalList[0].premiumRate }}</td>
<td>{{ totalList[0].premiumTargetM }}</td>
<td>{{ totalList[0].premiumTongbi }}</td>
</tr>
<!-- 列表数据 -->
<tr v-for="item in dataList" :key="item.comname2">
<td>{{ item.comname2 }}</td>
<td>{{ item.noCarPremium }}</td>
<td>{{ item.premium }}</td>
<td>{{ item.premiumHuanbi }}</td>
<td>{{ item.premiumPer }}</td>
<td>{{ item.premiumRate }}</td>
<td>{{ item.premiumTargetM }}</td>
<td>{{ item.premiumTongbi }}</td>
</tr>
</tbody>
</table>
</div>
</div>
</template>
<script>
// 引入数据
import { totalList, dataList, titleList } from './data/dataList.js';
export default {
components: {},
props: {},
data() {
return {
sortKey: '', // 排序key值
sortCls: 'xa', // 排序验收
lastX: 0,
// 头部列表
titleList: [],
// 合计数据 头部数据
totalList: null,
// 列表数据
dataList: null,
opstOpenFlag: false, // 展开更多标志 false - 加载更多 true - 收起s
};
},
created() {
// 引入数据
this.totalList = totalList;
this.dataList = dataList;
this.titleList = titleList;
},
methods: {
// 点击排序
sortTap(item) {
if (!item.sort) {
return console.warn('没有排序字段');
}
// sa表示正序 xa表示倒叙 进行互相切换
this.sortCls === 'sa' ? (this.sortCls = 'xa') : this.sortCls === 'xa' ? (this.sortCls = 'sa') : (this.sortCls = 'xa');
// 排序字段
this.sortKey = item.key;
// 开始排序
this.dataList.sort((a, b) => {
// 先转字符串处理
let aval = a[item.key] + '';
let bval = b[item.key] + '';
// 去除数据中的百分号
if (aval.includes('%')) {
aval = aval.split('%')[0] || 0;
}
if (bval.includes('%')) {
bval = bval.split('%')[0] || 0;
}
// 去除数据中的逗号
if (aval.includes(',')) {
aval = aval.split(',').join('') || 0;
}
if (bval.includes(',')) {
bval = bval.split(',').join('') || 0;
}
return this.sortCls === 'sa' ? aval - bval : bval - aval;
});
}
},
};
</script>
<style scoped lang="scss" src="./organizationTrend.scss"></style>
2,css如下:
/* ===================================公共样式=============================== */
//定义样式混合 使用@include调用该mixin 参数和默认值
@mixin flex_layout($direction: column, $justify-content: flex-start, $align-items: flex-start, $flex-wrap: nowrap) {
display: flex;
flex-direction: $direction;
justify-content: $justify-content;
align-items: $align-items;
flex-wrap: $flex-wrap;
}
@mixin layout_init_base {
position: absolute;
top: 0;
width: 100%;
height: 100%;
//-webkit-overflow-scrolling: touch;
overflow: hidden;
}
// 上三角
@mixin triangle-up($color: red, $size: 0.1) {
width: 0;
height: 0;
border-left: $size + px solid transparent;
border-right: $size + px solid transparent;
border-bottom: $size * 1.2 + px solid $color;
}
// 下三角
@mixin triangle-down($color: red, $size: 0.1) {
width: 0;
height: 0;
border-left: $size + px solid transparent;
border-right: $size + px solid transparent;
border-top: $size * 1.2 + px solid $color;
}
//
@mixin border-base($color: #000, $left: 0) {
content: ' ';
position: absolute;
left: $left;
z-index: 2;
color: $color;
}
// 添加下边框
@mixin border-bottom($color: #dbdbdb, $left: 0) {
position: relative;
&:after {
@include border-base($color, $left);
box-sizing: border-box;
bottom: 0;
right: 0;
height: 1px;
border-bottom: 1px solid $color;
transform-origin: 0 100%;
transform: scaleY(0.5);
}
}
/* 添加右边框 */
@mixin border-right($color: #dbdbdb, $top: 0) {
position: relative;
&:before {
@include border-base($color, $top);
box-sizing: border-box;
right: 0;
top: 0;
width: 1px;
bottom: 0;
border-right: 1px solid $color;
transform-origin: 100% 0;
transform: scaleX(0.5);
}
}
/* ===================================表格的主要样式=============================== */
h3 {
margin-bottom: 10px;
}
// 最大容器
.organizationTrend {
overflow: hidden;
}
.main {
// width: 1000px;
overflow: auto;
font-size: 13px;
height: 416px;
}
table {
table-layout: fixed;
width: 720px;
}
// 设置头部的所有单元格为粘性定位 以及其它属性
thead tr th {
position: sticky;
left: 0;
top: 0;
background-color: #f2f5f7;
min-width: 100px;
height: 30px;
border-right: 1px solid #dbdbdb;
text-align: center;
}
// 设置头部的第一个单元格
thead tr th:first-child {
z-index: 2;
background-color: lightblue;
}
// 设置内容区的第一列单元格
tbody {
tr {
text-align: center;
}
tr td:first-child {
position: sticky;
left: 0;
z-index: 0;
height: 27px;
background-color: #ffffff;
}
// 设置下边框线
td {
border-bottom: 1px solid #f4f4f4;
}
// 合计数据需要蓝色加粗
.count {
td {
height: 27px;
color: #146aff;
font-weight: 600;
}
}
}
/* ==================================== 排序三角的样式==================================== */
.thDis {
@include flex_layout($direction: row, $align-items: center, $justify-content: center);
.o {
margin: 0 5px;
@include flex_layout($direction: column, $align-items: center, $justify-content: flex-start);
.s {
@include triangle-up($color: #7b7b7b, $size: 4);
margin-bottom: 1px;
}
.sa {
@include triangle-up($color: #6bb5ff, $size: 4);
margin-bottom: 1px;
}
.x {
@include triangle-down($color: #7b7b7b, $size: 4);
margin-top: 1px;
}
.xa {
@include triangle-down($color: #6bb5ff, $size: 4);
margin-top: 1px;
}
}
}
3,用到的数据:dataList.js
// 第一行合计数据
export const totalList = [
{ comname2: '合计', noCarPremium: '2,902.1', premium: '16,474.7', premiumHuanbi: '-0.2%', premiumPer: '100%', premiumRate: '94.9%', premiumTargetM: '17,368.0', premiumTongbi: '+14.6%' },
];
// 常用的表头数据
export const titleList = [
{ name: '机构', sumKey: 'comname2', key: 'comname2', width: '1.4rem', fix: true, backgroundColor: '#f2f5f7' },
{ name: '目标', key: 'premiumTargetM', width: '1.5rem', sort: true, backgroundColor: '#fdeeee' },
{ name: '达成率', key: 'premiumRate', width: '1.5rem', sort: true, backgroundColor: '#fdeeee' },
{ name: '总保费', key: 'premium', width: '1.5rem', sort: true, backgroundColor: '#cde3fb' },
{ name: '机构保费占比', key: 'premiumPer', width: '2rem', sort: true, backgroundColor: '#cde3fb' },
{ name: '环比', key: 'premiumHuanbi', width: '1.4rem', sort: true, backgroundColor: '#cde3fb' },
{ name: '同比', key: 'premiumTongbi', width: '1.4rem', sort: true, backgroundColor: '#fdeeee' },
{ name: '非车保费', key: 'noCarPremium', width: '1.5rem', sort: true, backgroundColor: '#fdeeee' },
];
// 列表数据
export const dataList = [
{
comname2: '山东',
noCarPremium: '388.9',
premium: '2,394.8',
premiumHuanbi: '+6%',
premiumPer: '14.5%',
premiumRate: '114.6%',
premiumTargetM: '2,090.0',
premiumTongbi: '+44.2%',
},
{
comname2: '吉林',
noCarPremium: '90.2',
premium: '1,067.6',
premiumHuanbi: '-25.9%',
premiumPer: '6.5%',
premiumRate: '64.5%',
premiumTargetM: '1,654.0',
premiumTongbi: '+13.7%',
},
{
comname2: '辽宁',
noCarPremium: '132.1',
premium: '805.8',
premiumHuanbi: '+12.8%',
premiumPer: '4.9%',
premiumRate: '71.1%',
premiumTargetM: '1,134.0',
premiumTongbi: '-3.9%',
},
{
comname2: '河北',
noCarPremium: '309.8',
premium: '1,310.6',
premiumHuanbi: '+0%',
premiumPer: '8%',
premiumRate: '116%',
premiumTargetM: '1,130.0',
premiumTongbi: '+33.8%',
},
{
comname2: '内蒙古',
noCarPremium: '198.3',
premium: '1,142.6',
premiumHuanbi: '+12.7%',
premiumPer: '6.9%',
premiumRate: '131.9%',
premiumTargetM: '866.0',
premiumTongbi: '-7.6%',
},
{
comname2: '浙江',
noCarPremium: '135.6',
premium: '1,006.7',
premiumHuanbi: '-8.9%',
premiumPer: '6.1%',
premiumRate: '125.8%',
premiumTargetM: '800.0',
premiumTongbi: '+17.7%',
},
{
comname2: '陕西',
noCarPremium: '45.0',
premium: '374.5',
premiumHuanbi: '-28.7%',
premiumPer: '2.3%',
premiumRate: '46.8%',
premiumTargetM: '800.0',
premiumTongbi: '-27.8%',
},
{
comname2: '湖南',
noCarPremium: '74.1',
premium: '356.5',
premiumHuanbi: '+1.1%',
premiumPer: '2.2%',
premiumRate: '45%',
premiumTargetM: '793.0',
premiumTongbi: '-21.5%',
},
{
comname2: '四川',
noCarPremium: '183.9',
premium: '769.2',
premiumHuanbi: '-2%',
premiumPer: '4.7%',
premiumRate: '100.9%',
premiumTargetM: '762.0',
premiumTongbi: '+10.1%',
},
{
comname2: '贵州',
noCarPremium: '127.9',
premium: '1,005.0',
premiumHuanbi: '+36.6%',
premiumPer: '6.1%',
premiumRate: '143.6%',
premiumTargetM: '700.0',
premiumTongbi: '+56%',
},
{
comname2: '江苏',
noCarPremium: '60.1',
premium: '238.2',
premiumHuanbi: '+6%',
premiumPer: '1.4%',
premiumRate: '34%',
premiumTargetM: '700.0',
premiumTongbi: '+31.2%',
},
{
comname2: '河南',
noCarPremium: '124.2',
premium: '512.1',
premiumHuanbi: '+11%',
premiumPer: '3.1%',
premiumRate: '88.3%',
premiumTargetM: '580.0',
premiumTongbi: '-6.2%',
},
{
comname2: '甘肃',
noCarPremium: '38.8',
premium: '393.6',
premiumHuanbi: '-22.7%',
premiumPer: '2.4%',
premiumRate: '69.3%',
premiumTargetM: '568.0',
premiumTongbi: '-35.5%',
},
{
comname2: '福建',
noCarPremium: '60.8',
premium: '514.5',
premiumHuanbi: '-18.4%',
premiumPer: '3.1%',
premiumRate: '93.5%',
premiumTargetM: '550.0',
premiumTongbi: '+16.1%',
},
{
comname2: '黑龙江',
noCarPremium: '46.6',
premium: '286.2',
premiumHuanbi: '-1.1%',
premiumPer: '1.7%',
premiumRate: '54%',
premiumTargetM: '530.0',
premiumTongbi: '+6.2%',
},
{
comname2: '广东',
noCarPremium: '57.5',
premium: '265.9',
premiumHuanbi: '-16.6%',
premiumPer: '1.6%',
premiumRate: '57.8%',
premiumTargetM: '460.0',
premiumTongbi: '-11.6%',
},
{
comname2: '安徽',
noCarPremium: '99.0',
premium: '398.7',
premiumHuanbi: '+14.2%',
premiumPer: '2.4%',
premiumRate: '102.2%',
premiumTargetM: '390.0',
premiumTongbi: '+42.8%',
},
{
comname2: '江西',
noCarPremium: '187.5',
premium: '748.8',
premiumHuanbi: '+33%',
premiumPer: '4.5%',
premiumRate: '213.9%',
premiumTargetM: '350.0',
premiumTongbi: '+52.7%',
},
{
comname2: '湖北',
noCarPremium: '46.9',
premium: '336.5',
premiumHuanbi: '+19.6%',
premiumPer: '2%',
premiumRate: '98.1%',
premiumTargetM: '343.0',
premiumTongbi: '+29.9%',
},
{
comname2: '海南',
noCarPremium: '45.1',
premium: '341.3',
premiumHuanbi: '-8.9%',
premiumPer: '2.1%',
premiumRate: '103.7%',
premiumTargetM: '329.0',
premiumTongbi: '+16.6%',
},
{
comname2: '云南',
noCarPremium: '83.6',
premium: '643.0',
premiumHuanbi: '+41.3%',
premiumPer: '3.9%',
premiumRate: '213.6%',
premiumTargetM: '301.0',
premiumTongbi: '+25.8%',
},
{
comname2: '山西',
noCarPremium: '45.1',
premium: '214.9',
premiumHuanbi: '-35%',
premiumPer: '1.3%',
premiumRate: '75.1%',
premiumTargetM: '286.0',
premiumTongbi: '+34.5%',
},
{
comname2: '重庆',
noCarPremium: '55.6',
premium: '240.6',
premiumHuanbi: '-17.3%',
premiumPer: '1.5%',
premiumRate: '88.5%',
premiumTargetM: '272.0',
premiumTongbi: '+4.7%',
},
{
comname2: '青岛',
noCarPremium: '105.0',
premium: '289.0',
premiumHuanbi: '-10.9%',
premiumPer: '1.8%',
premiumRate: '111.1%',
premiumTargetM: '260.0',
premiumTongbi: '+18.7%',
},
{
comname2: '广西',
noCarPremium: '11.2',
premium: '108.7',
premiumHuanbi: '-19.9%',
premiumPer: '0.7%',
premiumRate: '63.9%',
premiumTargetM: '170.0',
premiumTongbi: '+11.4%',
},
{
comname2: '宁夏',
noCarPremium: '36.0',
premium: '144.1',
premiumHuanbi: '+87.1%',
premiumPer: '0.9%',
premiumRate: '87.9%',
premiumTargetM: '164.0',
premiumTongbi: '-29.5%',
},
{
comname2: '天津',
noCarPremium: '22.8',
premium: '96.0',
premiumHuanbi: '-16.9%',
premiumPer: '0.6%',
premiumRate: '68.6%',
premiumTargetM: '140.0',
premiumTongbi: '-54.3%',
}
];
更多推荐



所有评论(0)