有时候我们会遇到表格树的展示,类似于下图的需求:
其中组件的封装主要在table-tree文件夹内:
main.vue的内容如下:
1 <template> 2 <el-table :data="formatData" 3 :stripe="option.stripe" 4 :row-style="showRow" 5 :row-class-name="rowClassName" 6 v-bind="$attrs" 7 :border="border"> 8 <el-table-column v-if="columns.length===0" 9 width="150"> 10 <template slot-scope="scope"> 11 <span v-for="space in scope.row._level" 12 class="ms-tree-space" 13 :key="space"></span> 14 <span class="tree-ctrl" 15 v-if="iconShow(0,scope.row)" 16 @click="toggleExpanded(scope.$index)"> 17 <i v-if="!scope.row._expanded" 18 class="el-icon-plus"></i> 19 <i v-else 20 class="el-icon-minus"></i> 21 </span> 22 {{scope.$index}} 23 </template> 24 </el-table-column> 25 <el-table-column v-else 26 v-for="(column, index) in columns" 27 :key="column.value" 28 :label="column.text" 29 :width="column.width"> 30 <template slot-scope="scope"> 31 <span v-if="index === 0" 32 v-for="space in scope.row._level" 33 class="ms-tree-space" 34 :key="space"></span> 35 <span class="tree-ctrl" 36 v-if="iconShow(index,scope.row)" 37 @click="toggleExpanded(scope.$index)"> 38 <i v-if="!scope.row._expanded" 39 class="el-icon-plus"></i> 40 <i v-else 41 class="el-icon-minus"></i> 42 </span> 43 {{scope.row[column.value]}} 44 </template> 45 </el-table-column> 46 <slot></slot> 47 </el-table> 48 </template> 49 50 <script> 51 import treeToArray from "./eval"; 52 export default { 53 name: "AvueTreeTable", 54 props: { 55 option: { 56 type: Object, 57 required: true 58 }, 59 rowClassName: Function, 60 evalFunc: Function, 61 evalArgs: Array 62 }, 63 data() { 64 return {}; 65 }, 66 created() {}, 67 computed: { 68 data: function() { 69 return this.option.data || []; 70 }, 71 columns: function() { 72 return this.option.columns || []; 73 }, 74 expandAll: function() { 75 return this.option.expandAll; 76 }, 77 border: function() { 78 return this.option.border || true; 79 }, 80 // 格式化数据源 81 formatData: function() { 82 let tmp; 83 if (!Array.isArray(this.data)) { 84 tmp = [this.data]; 85 } else { 86 tmp = this.data; 87 } 88 const func = this.evalFunc || treeToArray; 89 const args = this.evalArgs 90 ? Array.concat([tmp, this.expandAll], this.evalArgs) 91 : [tmp, this.expandAll]; 92 return func.apply(null, args); 93 } 94 }, 95 methods: { 96 showRow: function(row) { 97 const show = row.row.parent 98 ? row.row.parent._expanded && row.row.parent._show 99 : true; 100 row.row._show = show; 101 return show 102 ? "animation:treeTableShow 1s;-webkit-animation:treeTableShow 1s;" 103 : "display:none;"; 104 }, 105 // 切换下级是否展开 106 toggleExpanded: function(trIndex) { 107 const record = this.formatData[trIndex]; 108 record._expanded = !record._expanded; 109 }, 110 // 图标显示 111 iconShow(index, record) { 112 return index === 0 && record.children && record.children.length > 0; 113 } 114 } 115 }; 116 </script> 117 <style rel="stylesheet/css"> 118 @keyframes treeTableShow { 119 from { 120 opacity: 0; 121 } 122 to { 123 opacity: 1; 124 } 125 } 126 @-webkit-keyframes treeTableShow { 127 from { 128 opacity: 0; 129 } 130 to { 131 opacity: 1; 132 } 133 } 134 </style> 135 136 <style lang="scss" rel="stylesheet/scss" scoped> 137 $color-blue: #2196f3; 138 $space-width: 18px; 139 .ms-tree-space { 140 position: relative; 141 top: 1px; 142 display: inline-block; 143 font-style: normal; 144 font-weight: 400; 145 line-height: 1; 146 width: $space-width; 147 height: 14px; 148 &::before { 149 content: ""; 150 } 151 } 152 .processContainer { 153 width: 100%; 154 height: 100%; 155 } 156 table td { 157 line-height: 26px; 158 } 159 160 .tree-ctrl { 161 position: relative; 162 cursor: pointer; 163 color: $color-blue; 164 margin-left: -$space-width; 165 } 166 </style>