首页 > 编程 > JavaScript > 正文

详解vue-cli+element-ui树形表格(多级表格折腾小计)

2019-11-19 11:45:55
字体:
来源:转载
供稿:网友

前沿

最近在项目开发中需要做一个多级表格,树形表格的功能,看看element-ui上没有,自己开是折腾,话不多说,上思路和代码。

效果图:

可点击收缩,展开。

一,首先创建一个公共的文件夹treeTable,里边放一个index.vue和eval.js

先看看index.vue,原理就是在element-ui的基础上做了进一步改造。

//利用element-ui的 <template slot-scope="scope">属性,在插入多级表格<template> <el-table :data="formatData" :row-style="showRow" v-bind="$attrs">  <el-table-column v-if="columns.length===0" width="150">   <template slot-scope="scope">    <span v-for="space in scope.row._level" class="ms-tree-space" :key="space"></span>    <span class="tree-ctrl" v-if="iconShow(0,scope.row)" @click="toggleExpanded(scope.$index)">     <i v-if="!scope.row._expanded" class="el-icon-plus"></i>     <i v-else class="el-icon-minus"></i>    </span>    {{scope.$index}}   </template>  </el-table-column>  <el-table-column v-else v-for="(column, index) in columns" :key="column.value" :label="column.text" :width="column.width">   <template slot-scope="scope">    <span v-if="index === 0" v-for="space in scope.row._level" class="ms-tree-space" :key="space"></span>    <span class="tree-ctrl" v-if="iconShow(index,scope.row)" @click="toggleExpanded(scope.$index)">     <i v-if="!scope.row._expanded" class="el-icon-plus"></i>     <i v-else class="el-icon-minus"></i>    </span>    {{scope.row[column.value]}}   </template>  </el-table-column>  <slot></slot> </el-table></template><script>import treeToArray from './eval'export default { name: 'treeTable', props: {  data: {   type: [Array, Object],   required: true  },  columns: {   type: Array,   default: () => []  },  evalFunc: Function,  evalArgs: Array,  expandAll: {   type: Boolean,   default: false  } }, computed: {  // 格式化数据源  formatData: function() {   let tmp   if (!Array.isArray(this.data)) {    tmp = [this.data]   } else {    tmp = this.data   }   const func = this.evalFunc || treeToArray   const args = this.evalArgs ? Array.concat([tmp, this.expandAll], this.evalArgs) : [tmp, this.expandAll]   return func.apply(null, args)  } }, methods: {  showRow: function(row) {   const show = (row.row.parent ? (row.row.parent._expanded && row.row.parent._show) : true)   row.row._show = show   return show ? 'animation:treeTableShow 1s;-webkit-animation:treeTableShow 1s;' : 'display:none;'  },  // 切换下级是否展开  toggleExpanded: function(trIndex) {   const record = this.formatData[trIndex]   record._expanded = !record._expanded  },  // 图标显示  iconShow(index, record) {   return (index === 0 && record.children && record.children.length > 0)  } }}</script><style rel="stylesheet/css"> @keyframes treeTableShow {  from {opacity: 0;}  to {opacity: 1;} } @-webkit-keyframes treeTableShow {  from {opacity: 0;}  to {opacity: 1;} }</style><style lang="scss" rel="stylesheet/scss" scoped> $color-blue: #2196F3; $space-width: 18px; .ms-tree-space {  position: relative;  top: 1px;  display: inline-block;  font-style: normal;  font-weight: 400;  line-height: 1;  width: $space-width;  height: 14px;  &::before {   content: ""  } } .processContainer{  width: 100%;  height: 100%; } table td {  line-height: 26px; } .tree-ctrl{  position: relative;  cursor: pointer;  color: $color-blue;  margin-left: -$space-width; }</style>

eval.js

/** * @Author: hyf * @Date:  2018-10-27 */'use strict'import Vue from 'vue'export default function treeToArray(data, expandAll, parent = null, level = null) {  let tmp = []  Array.from(data).forEach(function(record) {    if (record._expanded === undefined) {      Vue.set(record, '_expanded', expandAll)    }    let _level = 1    if (level !== undefined && level !== null) {      _level = level + 1    }    Vue.set(record, '_level', _level)      // 如果有父元素    if (parent) {      Vue.set(record, 'parent', parent)    }    tmp.push(record)    if (record.children && record.children.length > 0) {      const children = treeToArray(record.children, expandAll, record, _level)      tmp = tmp.concat(children)    }  })  return tmp}

二,页面中的用法

<template> <div class="app-container">  <tree-table :data="data" :columns="columns" border></tree-table> </div></template><script>import treeTable from '@/components/TreeTable'export default { name: 'treeTableDemo', components: { treeTable }, data() {  return {   columns: [    {     text: '事件',     value: 'event',     width: 200    },    {     text: 'ID',     value: 'id'    },    {     text: '时间线',     value: 'timeLine'    },    {     text: '备注',     value: 'comment'    }   ],   data: [    {     id: 0,     event: '事件1',     timeLine: 50,     comment: '无'    },    {     id: 1,     event: '事件1',     timeLine: 100,     comment: '无',     children: [      {       id: 2,       event: '事件2',       timeLine: 10,       comment: '无'      },      {       id: 3,       event: '事件3',       timeLine: 90,       comment: '无',       children: [        {         id: 4,         event: '事件4',         timeLine: 5,         comment: '无'        },        {         id: 5,         event: '事件5',         timeLine: 10,         comment: '无'        },        {         id: 6,         event: '事件6',         timeLine: 75,         comment: '无',         children: [          {           id: 7,           event: '事件7',           timeLine: 50,           comment: '无',           children: [            {             id: 71,             event: '事件71',             timeLine: 25,             comment: 'xx'            },            {             id: 72,             event: '事件72',             timeLine: 5,             comment: 'xx'            },            {             id: 73,             event: '事件73',             timeLine: 20,             comment: 'xx'            }           ]          },          {           id: 8,           event: '事件8',           timeLine: 25,           comment: '无'          }         ]        }       ]      }     ]    }   ]  } }}</script>

一下为一些整体思路,以及一些说明,方便后续使用

写在前面

此组件仅提供一个创建TreeTable的解决思路

prop说明

data

必填

原始数据,要求是一个数组或者对象

 [{  key1: value1,  key2: value2,  children: [{   key1: value1  },  {   key1: value1  }] }, {  key1: value1 }]

或者

  {   key1: value1,   key2: value2,   children: [{    key1: value1   },   {    key1: value1   }]  }

columns

列属性,要求是一个数组

text: 显示在表头的文字
value: 对应data的key。treeTable将显示相应的value
width: 每列的宽度,为一个数字(可选)

如果你想要每个字段都有自定义的样式或者嵌套其他组件,columns可不提供,直接像在el-table一样写即可,如果没有自定义内容,提供columns将更加的便捷方便

如果你有几个字段是需要自定义的,几个不需要,那么可以将不需要自定义的字段放入columns,将需要自定义的内容放入到slot中,详情见后文

[{ value:string, text:string, width:number},{ value:string, text:string, width:number}]

expandAll
是否默认全部展开,boolean值,默认为false

evalFunc
解析函数,function,非必须
如果不提供,将使用默认的evalFunc

evalArgs
解析函数的参数,是一个数组

请注意,自定义的解析函数参数第一个为this.data,第二个参数为, this.expandAll,你不需要在evalArgs填写。一定记住,这两个参数是强制性的,并且位置不可颠倒 this.data为需要解析的数据,this.expandAll为是否默认展开
如你的解析函数需要的参数为(this.data, this.expandAll,1,2,3,4),那么你只需要将[1,2,3,4]赋值给evalArgs就可以了
如果你的解析函数参数只有(this.data, this.expandAll),那么就可以不用填写evalArgs了

slot

这是一个自定义列的插槽。
默认情况下,treeTable只有一行行展示数据的功能。但是一般情况下,我们会要给行加上一个操作按钮或者根据当行数据展示不同的样式,这时我们就需要自定义列了。
slot和columns属性可同时存在,columns里面的数据列会在slot自定义列的左边展示

其他

如果有其他的需求,请参考el-table的api自行修改index.vue

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持武林网。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表