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%',
  }
];
Logo

Vue社区为您提供最前沿的新闻资讯和知识内容

更多推荐