|
1 | 1 | <template>
|
2 |
| - <el-table :data="formatData" :row-style="showRow" v-bind="$attrs"> |
3 |
| - <el-table-column v-if="columns.length===0" width="150"> |
| 2 | + <el-table :data="tableData" :row-style="showRow" v-bind="$attrs" v-on="$listeners" > |
| 3 | + <slot name="selection" /> |
| 4 | + <slot name="pre-column" /> |
| 5 | + <el-table-column |
| 6 | + v-for="item in columns" |
| 7 | + :label="item.label" |
| 8 | + :key="item.key" |
| 9 | + :width="item.width" |
| 10 | + :align="item.align||'center'" |
| 11 | + :header-align="item.headerAlign"> |
4 | 12 | <template slot-scope="scope">
|
5 |
| - <span v-for="space in scope.row._level" :key="space" class="ms-tree-space"/> |
6 |
| - <span v-if="iconShow(0,scope.row)" class="tree-ctrl" @click="toggleExpanded(scope.$index)"> |
7 |
| - <i v-if="!scope.row._expanded" class="el-icon-plus"/> |
8 |
| - <i v-else class="el-icon-minus"/> |
9 |
| - </span> |
10 |
| - {{ scope.$index }} |
| 13 | + <slot :scope="scope" :name="item.key"> |
| 14 | + <template v-if="item.expand"> |
| 15 | + <span :style="{'padding-left':+scope.row._level*indent + 'px'} "/> |
| 16 | + <span v-show="showSperadIcon(scope.row)" class="tree-ctrl" @click="toggleExpanded(scope.$index)"> |
| 17 | + <i v-if="!scope.row._expand" class="el-icon-plus" /> |
| 18 | + <i v-else class="el-icon-minus" /> |
| 19 | + </span> |
| 20 | + </template> |
| 21 | + <template v-if="item.checkbox"> |
| 22 | + <el-checkbox |
| 23 | + v-if="scope.row[defaultChildren]&&scope.row[defaultChildren].length>0" |
| 24 | + :style="{'padding-left':+scope.row._level*indent + 'px'} " |
| 25 | + :indeterminate="scope.row._select" |
| 26 | + v-model="scope.row._select" |
| 27 | + @change="handleCheckAllChange(scope.row)" /> |
| 28 | + <el-checkbox |
| 29 | + v-else |
| 30 | + :style="{'padding-left':+scope.row._level*indent + 'px'} " |
| 31 | + v-model="scope.row._select" |
| 32 | + @change="handleCheckAllChange(scope.row)" /> |
| 33 | + </template> |
| 34 | + {{ scope.row[item.key] }} |
| 35 | + </slot> |
11 | 36 | </template>
|
12 | 37 | </el-table-column>
|
13 |
| - <el-table-column v-for="(column, index) in columns" v-else :key="column.value" :label="column.text" :width="column.width"> |
14 |
| - <template slot-scope="scope"> |
15 |
| - <!-- Todo --> |
16 |
| - <!-- eslint-disable-next-line vue/no-confusing-v-for-v-if --> |
17 |
| - <span v-for="space in scope.row._level" v-if="index === 0" :key="space" class="ms-tree-space"/> |
18 |
| - <span v-if="iconShow(index,scope.row)" class="tree-ctrl" @click="toggleExpanded(scope.$index)"> |
19 |
| - <i v-if="!scope.row._expanded" class="el-icon-plus"/> |
20 |
| - <i v-else class="el-icon-minus"/> |
21 |
| - </span> |
22 |
| - {{ scope.row[column.value] }} |
23 |
| - </template> |
24 |
| - </el-table-column> |
25 |
| - <slot/> |
26 | 38 | </el-table>
|
27 | 39 | </template>
|
28 | 40 |
|
29 | 41 | <script>
|
30 |
| -/** |
31 |
| - Auth: Lei.j1ang |
32 |
| - Created: 2018/1/19-13:59 |
33 |
| -*/ |
34 |
| -import treeToArray from './eval' |
| 42 | +import treeToArray, { addAttrs } from './eval.js' |
| 43 | +
|
35 | 44 | export default {
|
36 | 45 | name: 'TreeTable',
|
37 | 46 | props: {
|
38 |
| - /* eslint-disable */ |
39 | 47 | data: {
|
40 |
| - type: [Array, Object], |
41 |
| - required: true |
| 48 | + type: Array, |
| 49 | + required: true, |
| 50 | + default: () => [] |
42 | 51 | },
|
43 | 52 | columns: {
|
44 | 53 | type: Array,
|
45 | 54 | default: () => []
|
46 | 55 | },
|
47 |
| - evalFunc: Function, |
48 |
| - evalArgs: Array, |
49 |
| - expandAll: { |
| 56 | + defaultExpandAll: { |
50 | 57 | type: Boolean,
|
51 | 58 | default: false
|
| 59 | + }, |
| 60 | + defaultChildren: { |
| 61 | + type: String, |
| 62 | + default: 'children' |
| 63 | + }, |
| 64 | + indent: { |
| 65 | + type: Number, |
| 66 | + default: 50 |
| 67 | + } |
| 68 | + }, |
| 69 | + data() { |
| 70 | + return { |
| 71 | + guard: 1 |
52 | 72 | }
|
53 | 73 | },
|
54 | 74 | computed: {
|
55 |
| - // 格式化数据源 |
56 |
| - formatData: function() { |
57 |
| - let tmp |
58 |
| - if (!Array.isArray(this.data)) { |
59 |
| - tmp = [this.data] |
60 |
| - } else { |
61 |
| - tmp = this.data |
| 75 | + children() { |
| 76 | + return this.defaultChildren |
| 77 | + }, |
| 78 | + tableData() { |
| 79 | + const data = this.data |
| 80 | + if (this.data.length === 0) { |
| 81 | + return [] |
62 | 82 | }
|
63 |
| - const func = this.evalFunc || treeToArray |
64 |
| - const args = this.evalArgs ? Array.concat([tmp, this.expandAll], this.evalArgs) : [tmp, this.expandAll] |
65 |
| - return func.apply(null, args) |
| 83 | + addAttrs(data, { |
| 84 | + expand: this.defaultExpandAll, |
| 85 | + children: this.defaultChildren |
| 86 | + }) |
| 87 | +
|
| 88 | + const retval = treeToArray(data, this.defaultChildren) |
| 89 | + return retval |
66 | 90 | }
|
67 | 91 | },
|
68 | 92 | methods: {
|
69 |
| - showRow: function(row) { |
70 |
| - const show = (row.row.parent ? (row.row.parent._expanded && row.row.parent._show) : true) |
71 |
| - row.row._show = show |
72 |
| - return show ? 'animation:treeTableShow 1s;-webkit-animation:treeTableShow 1s;' : 'display:none;' |
| 93 | + addBrother(row, data) { |
| 94 | + if (row._parent) { |
| 95 | + row._parent.children.push(data) |
| 96 | + } else { |
| 97 | + this.data.push(data) |
| 98 | + } |
73 | 99 | },
|
74 |
| - // 切换下级是否展开 |
75 |
| - toggleExpanded: function(trIndex) { |
76 |
| - const record = this.formatData[trIndex] |
77 |
| - record._expanded = !record._expanded |
| 100 | + addChild(row, data) { |
| 101 | + if (!row.children) { |
| 102 | + this.$set(row, 'children', []) |
| 103 | + } |
| 104 | + row.children.push(data) |
78 | 105 | },
|
79 |
| - // 图标显示 |
80 |
| - iconShow(index, record) { |
81 |
| - return (index === 0 && record.children && record.children.length > 0) |
| 106 | + delete(row) { |
| 107 | + const { _index, _parent } = row |
| 108 | + if (_parent) { |
| 109 | + _parent.children.splice(_index, 1) |
| 110 | + } else { |
| 111 | + this.data.splice(_index, 1) |
| 112 | + } |
| 113 | + }, |
| 114 | + getData() { |
| 115 | + return this.tableData |
| 116 | + }, |
| 117 | + showRow: function({ row }) { |
| 118 | + const parent = row._parent |
| 119 | + const show = parent ? parent._expand && parent._show : true |
| 120 | + row._show = show |
| 121 | + return show |
| 122 | + ? 'animation:treeTableShow 1s;-webkit-animation:treeTableShow 1s;' |
| 123 | + : 'display:none;' |
| 124 | + }, |
| 125 | + showSperadIcon(record) { |
| 126 | + return record[this.children] && record[this.children].length > 0 |
| 127 | + }, |
| 128 | + toggleExpanded(trIndex) { |
| 129 | + const record = this.tableData[trIndex] |
| 130 | + const expand = !record._expand |
| 131 | + record._expand = expand |
| 132 | + }, |
| 133 | + handleCheckAllChange(row) { |
| 134 | + this.selcetRecursion(row, row._select, this.defaultChildren) |
| 135 | + this.isIndeterminate = row._select |
| 136 | + }, |
| 137 | + selcetRecursion(row, select, children = 'children') { |
| 138 | + if (select) { |
| 139 | + this.$set(row, '_expand', true) |
| 140 | + this.$set(row, '_show', true) |
| 141 | + } |
| 142 | + const sub_item = row[children] |
| 143 | + if (sub_item && sub_item.length > 0) { |
| 144 | + sub_item.map(child => { |
| 145 | + child._select = select |
| 146 | + this.selcetRecursion(child, select, children) |
| 147 | + }) |
| 148 | + } |
82 | 149 | }
|
83 | 150 | }
|
84 | 151 | }
|
85 | 152 | </script>
|
86 |
| -<style rel="stylesheet/css"> |
87 |
| - @keyframes treeTableShow { |
88 |
| - from {opacity: 0;} |
89 |
| - to {opacity: 1;} |
90 |
| - } |
91 |
| - @-webkit-keyframes treeTableShow { |
92 |
| - from {opacity: 0;} |
93 |
| - to {opacity: 1;} |
94 |
| - } |
95 |
| -</style> |
96 | 153 |
|
97 |
| -<style lang="scss" rel="stylesheet/scss" scoped> |
98 |
| - $color-blue: #2196F3; |
99 |
| - $space-width: 18px; |
100 |
| - .ms-tree-space { |
101 |
| - position: relative; |
102 |
| - top: 1px; |
103 |
| - display: inline-block; |
104 |
| - font-style: normal; |
105 |
| - font-weight: 400; |
106 |
| - line-height: 1; |
107 |
| - width: $space-width; |
108 |
| - height: 14px; |
109 |
| - &::before { |
110 |
| - content: "" |
111 |
| - } |
| 154 | +<style> |
| 155 | +@keyframes treeTableShow { |
| 156 | + from { |
| 157 | + opacity: 0; |
| 158 | + } |
| 159 | + to { |
| 160 | + opacity: 1; |
112 | 161 | }
|
113 |
| - .processContainer{ |
114 |
| - width: 100%; |
115 |
| - height: 100%; |
| 162 | +} |
| 163 | +@-webkit-keyframes treeTableShow { |
| 164 | + from { |
| 165 | + opacity: 0; |
116 | 166 | }
|
117 |
| - table td { |
118 |
| - line-height: 26px; |
| 167 | + to { |
| 168 | + opacity: 1; |
119 | 169 | }
|
| 170 | +} |
120 | 171 |
|
121 |
| - .tree-ctrl{ |
122 |
| - position: relative; |
123 |
| - cursor: pointer; |
124 |
| - color: $color-blue; |
125 |
| - margin-left: -$space-width; |
126 |
| - } |
| 172 | +.tree-ctrl { |
| 173 | + position: relative; |
| 174 | + cursor: pointer; |
| 175 | + color: #2196f3; |
| 176 | +} |
127 | 177 | </style>
|
0 commit comments