vue封装table 适配vantUI,可固定列,可多层级下拉

1,130 阅读1分钟
<template>  <div class="vant-table">    <div class="positionColumn" v-if="isPosition">      <table cellspacing="0" style="width: 100%" class="table">        <thead>          <tr>            <th class="th">{{ option.collectColumn[0].label }}</th>          </tr>        </thead>        <tbody>          <template v-if="tableData.length > 0">            <tr              v-for="(item, index) in tableData"              :key="index"              :class="{ grey: item.isChildren, isOdd: item.isOdd }"              class="list-tr"              @click="getChildren(item, index)"            >              <td v-for="(context, key) in option.collectColumn" :key="key">                <van-icon v-if="item.level > 1" :class="{ img01: item.show }" name="arrow-up" />                <span :class="{ div: isPosition }">{{ item[context.prop] }}</span>              </td>            </tr>          </template>        </tbody>      </table>    </div>    <div :class="{ positionBody: isPosition }">      <table cellspacing="0" class="table" :class="{ tableWidth: isPosition }">        <thead>          <tr>            <th class="th" v-for="(item, index) in option.column" :key="index">{{ item.label }}</th>          </tr>        </thead>        <tbody>          <template v-if="tableData.length > 0">            <tr              @click="getChildren(item, index)"              :class="{ grey: item.isChildren, isOdd: item.isOdd }"              v-for="(item, index) in tableData"              :key="index"              class="list-tr"            >              <td v-for="(context, key) in option.column" :key="key">                <van-icon v-if="!isPosition && !key && item.level > 1" :class="{ img01: item.show }" name="arrow-up" />                <span :class="{ div: !isPosition && !key }">{{ item[context.prop] }}</span>              </td>            </tr>          </template>        </tbody>      </table>    </div>  </div></template><script>export default {  name: 'VantTable',  data() {    return {      bgcolor: { background: 'black' }    }  },  props: {    isPosition: { // 是否固定列      default: false,      type: Boolean    },    tableData: Array,    option: Object  },  created() {    this.tableData.forEach(item => {      item.show = false    })  },  methods: {    getChildren(item, index) {      if (!item.level || item.level <= 1) {        return      }      if (item.show) {        this.$emit('deleteChildren', item, index)      } else {        this.$emit('getChildren', item, index)      }    }  }}</script><style lang="scss" scoped>* {  padding: 0;}.img01 {  transform: rotate(180deg);  transition-duration: 0.3s;}.tableWidth {  min-width: 400px;}.isOdd {  background: #f4f7f9;}.vant-table {  width: 100%;  position: relative;  .positionColumn {    position: absolute;    left: 0;    top: 0;    width: 150px;    background: #fff;    padding-bottom: 8px;    .table {      .list-tr {        width: 100%;        height: 56px;        th,        td {          text-align: left !important;          display: flex;          width: 150px;          .van-icon {            width: 15px;            padding-right: 5px;            color: #a5abb9;          }          &:first-child {            text-align: left;            span {              width: 130px;            }          }          i {            top: 0px;          }        }      }    }  }  .positionBody {    width: calc(100% - 150px);    padding-left: 150px;    overflow-x: scroll;    padding-bottom: 8px;    .table {      table-layout: fixed;      thead th:first-child {        padding: 0;        width: 70px;        text-align: center;      }      .list-tr td:first-child {        padding: 0;        width: 70px;        text-align: center;        span {          width: 70px;        }      }    }  }  .table {    width: 100%;    table-layout: fixed;    thead {      background: #ecf3fe;      border-radius: 1px;      .th {        height: 56px;        text-align: center;        width: 70px;        &:first-child {          text-align: center;          width: 120px;        }      }    }    .list-tr {      height: 56px;      text-align: center;      td {        color: #078eff;        // display: flex;        height: 56px;        align-items: center;        width: 70px;        @include textoverflow;        &:first-child {          padding-left: 10px;          text-align: left;          width: 120px;          span {            width: 90px;          }        }        span {          @include textoverflow;          width: 70px;          // display: inline-block;        }        i {          // top: -4px;          transition-duration: 0.3s;        }      }    }    .grey {      background: #f5f5f5;      td {        color: #0e0e0e;        .div {          // padding-left: 25px;        }      }    }  }}</style>

调用组件代码

// html
<vantTable          :option="option"          :tableData="accountList"          @deleteChildren="deleteChildren"          @getChildren="getChildren"        />

// js  数据源
// 表头
option=[
  {
    label: '部门名称',
    prop: 'departName'
  },
  {
    label: '总数',
    prop: 'total'
  },
  {
    label: '已完成',
    prop: 'patrolTotal'
  },
  {
    label: '完成率',
    prop: 'patrolRate'
  }
]
// 数据
accountList=[{  departName: "部门1",  level: 1,  noPatrolTotal: 3,  orgCode: "A03A13A15A14A04A06A08",  parentId: "GO_33356fd59b024a73be1fbee20f1fba5b",  patrolRate: "25%",  patrolTotal: 1,  total: 4}]

// js  组装数据
 geChildren(item, index) {      item.show = !item.show      this.getPatrolAccount( item.orgCode, index, item)    },
getPatrolAccount( orgCode, index, targetItem) {      try {                var collectParams = {          departId: orgCode        }       // 获取数据
        let res = await getCollectStatistics(collectParams)             if (res && res.success && res.result) {                      if (orgCode) {              // 添加子集              res.result.forEach(item => {                item.isChildren = true                item.parent = targetItem              })              targetItem.childrenLength = res.result.length              // 给当前节点所有父级的childrenLength追加子集的长度              const addLenToGrandParent = (targetItem) => {                if (targetItem.parent) {                  targetItem.parent.childrenLength += res.result.length                  addLenToGrandParent(targetItem.parent)                }              }              addLenToGrandParent(targetItem)              this.accountList.splice(index + 1, 0, ...res.result)              this.$set(this.accountList[index], 'length', res.result.length)            }         } else {          this.$toast(res.message, '查询数据失败,请稍后再试')        }      } catch (error) {        console.log('error', error)        this.$toast('查询数据失败,请稍后再试')      }    },// 删除当前节点所有的子孙数据,并把当前所属父集节点length 减掉对应的长度deleteChildren(item, index) {       const deletedLen = item.childrenLength      this.accountList.splice(index + 1, deletedLen)      const reduceLenToGrandParent = (target) => {        if (target.parent) {          target.parent.childrenLength -= deletedLen          reduceLenToGrandParent(target.parent)        }      }      item.childrenLength = 0      reduceLenToGrandParent(item)      item.show = !item.show    },