增加注释
Showing
5 changed files
with
435 additions
and
0 deletions
src/components/downLbTable/LbColumn.vue
0 → 100644
1 | /* | ||
2 | * FileName: lb-column.vue | ||
3 | * Remark: element-column | ||
4 | * Project: lb-element-table | ||
5 | * Author: 任超 | ||
6 | * File Created: Tuesday, 19th March 2019 9:58:23 am | ||
7 | * Last Modified: Tuesday, 19th March 2019 10:14:42 am | ||
8 | * Modified By: 任超 | ||
9 | */ | ||
10 | |||
11 | <template> | ||
12 | <el-table-column v-bind="$attrs" v-on="$listeners" :prop="column.prop" :label="column.label" :type="column.type" | ||
13 | :index="column.index" :column-key="column.columnKey" :width="column.width" :min-width="column.minWidth" | ||
14 | :fixed="column.fixed" :scoped-slot="column.renderHeader" :sortable="column.sortable || false" | ||
15 | :sort-method="column.sortMethod" :sort-by="column.sortBy" :sort-orders="column.sortOrders" | ||
16 | :resizable="column.resizable || true" :formatter="column.formatter" | ||
17 | :show-overflow-tooltip="column.showOverflowTooltip || false" :align="column.align || align || 'center'" | ||
18 | :header-align="column.headerAlign || headerAlign || column.align || align || 'center'" | ||
19 | :class-name="column.className" :label-class-name="column.labelClassName" :selectable="column.selectable" | ||
20 | :reserve-selection="column.reserveSelection || false" :filters="column.filters" | ||
21 | :filter-placement="column.filterPlacement" :filter-multiple="column.filterMultiple" | ||
22 | :filter-method="column.filterMethod" :filtered-value="column.filteredValue"> | ||
23 | <template slot="header" slot-scope="scope"> | ||
24 | <lb-render v-if="column.renderHeader" :scope="scope" :render="column.renderHeader"> | ||
25 | </lb-render> | ||
26 | <span v-else>{{ scope.column.label }}</span> | ||
27 | </template> | ||
28 | |||
29 | <template slot-scope="scope"> | ||
30 | <lb-render :scope="scope" :render="column.render"> | ||
31 | </lb-render> | ||
32 | </template> | ||
33 | |||
34 | <template v-if="column.children"> | ||
35 | <lb-column v-for="(col, index) in column.children" :key="index" :column="col"> | ||
36 | </lb-column> | ||
37 | </template> | ||
38 | </el-table-column> | ||
39 | </template> | ||
40 | |||
41 | <script> | ||
42 | import LbRender from './LbRender' | ||
43 | import forced from './forced.js' | ||
44 | export default { | ||
45 | name: 'LbColumn', | ||
46 | props: { | ||
47 | column: Object, | ||
48 | headerAlign: String, | ||
49 | align: String | ||
50 | }, | ||
51 | components: { | ||
52 | LbRender | ||
53 | }, | ||
54 | methods: { | ||
55 | setColumn () { | ||
56 | if (this.column.type) { | ||
57 | this.column.renderHeader = forced[this.column.type].renderHeader | ||
58 | this.column.render = this.column.render || forced[this.column.type].renderCell | ||
59 | } | ||
60 | if (this.column.formatter) { | ||
61 | this.column.render = (h, scope) => { | ||
62 | return <span>{scope.column.formatter(scope.row, scope.column, scope.row, scope.$index)}</span> | ||
63 | } | ||
64 | } | ||
65 | if (!this.column.render) { | ||
66 | this.column.render = (h, scope) => { | ||
67 | return <span>{scope.row[scope.column.property]}</span> | ||
68 | } | ||
69 | } | ||
70 | } | ||
71 | }, | ||
72 | watch: { | ||
73 | column: { | ||
74 | handler () { | ||
75 | this.setColumn() | ||
76 | }, | ||
77 | immediate: true | ||
78 | } | ||
79 | } | ||
80 | } | ||
81 | </script> |
src/components/downLbTable/LbRender.vue
0 → 100644
1 | /* | ||
2 | * FileName: lb-render.vue | ||
3 | * Remark: 自定义render | ||
4 | * Project: lb-element-table | ||
5 | * Author: 任超 | ||
6 | * File Created: Tuesday, 19th March 2019 10:15:30 am | ||
7 | * Last Modified: Tuesday, 19th March 2019 10:15:32 am | ||
8 | * Modified By: 任超 | ||
9 | */ | ||
10 | <script> | ||
11 | export default { | ||
12 | name: 'LbRender', | ||
13 | functional: true, | ||
14 | props: { | ||
15 | scope: Object, | ||
16 | render: Function | ||
17 | }, | ||
18 | render: (h, ctx) => { | ||
19 | return ctx.props.render ? ctx.props.render(h, ctx.props.scope) : '' | ||
20 | } | ||
21 | } | ||
22 | </script> |
src/components/downLbTable/forced.js
0 → 100644
1 | export default { | ||
2 | selection: { | ||
3 | renderHeader: (h, { store }) => { | ||
4 | return ( | ||
5 | <el-checkbox | ||
6 | disabled={store.states.data && store.states.data.length === 0} | ||
7 | indeterminate={ | ||
8 | store.states.selection.length > 0 && !store.states.isAllSelected | ||
9 | } | ||
10 | nativeOn-click={store.toggleAllSelection} | ||
11 | value={store.states.isAllSelected} | ||
12 | /> | ||
13 | ) | ||
14 | }, | ||
15 | renderCell: (h, { row, column, store, $index }) => { | ||
16 | return ( | ||
17 | <el-checkbox | ||
18 | nativeOn-click={event => event.stopPropagation()} | ||
19 | value={store.isSelected(row)} | ||
20 | disabled={ | ||
21 | column.selectable | ||
22 | ? !column.selectable.call(null, row, $index) | ||
23 | : false | ||
24 | } | ||
25 | on-input={() => { | ||
26 | store.commit('rowSelectedChanged', row) | ||
27 | }} | ||
28 | /> | ||
29 | ) | ||
30 | }, | ||
31 | sortable: false, | ||
32 | resizable: false | ||
33 | }, | ||
34 | index: { | ||
35 | renderHeader: (h, scope) => { | ||
36 | return <span>{scope.column.label || '#'}</span> | ||
37 | }, | ||
38 | renderCell: (h, { $index, column }) => { | ||
39 | let i = $index + 1 | ||
40 | const index = column.index | ||
41 | |||
42 | if (typeof index === 'number') { | ||
43 | i = $index + index | ||
44 | } else if (typeof index === 'function') { | ||
45 | i = index($index) | ||
46 | } | ||
47 | |||
48 | return <div>{i}</div> | ||
49 | }, | ||
50 | sortable: false | ||
51 | }, | ||
52 | expand: { | ||
53 | renderHeader: (h, scope) => { | ||
54 | return <span>{scope.column.label || ''}</span> | ||
55 | }, | ||
56 | renderCell: (h, { row, store }, proxy) => { | ||
57 | const expanded = store.states.expandRows.indexOf(row) > -1 | ||
58 | return ( | ||
59 | <div | ||
60 | class={ | ||
61 | 'el-table__expand-icon ' + | ||
62 | (expanded ? 'el-table__expand-icon--expanded' : '') | ||
63 | } | ||
64 | on-click={e => proxy.handleExpandClick(row, e)} | ||
65 | > | ||
66 | <i class='el-icon el-icon-arrow-right' /> | ||
67 | </div> | ||
68 | ) | ||
69 | }, | ||
70 | sortable: false, | ||
71 | resizable: false, | ||
72 | className: 'el-table__expand-column' | ||
73 | } | ||
74 | } |
src/components/downLbTable/index.vue
0 → 100644
1 | /* | ||
2 | * FileName: lb-table.vue | ||
3 | * Remark: element table | ||
4 | * Project: lb-element-table | ||
5 | * Author: 任超 | ||
6 | * File Created: Tuesday, 19th March 2019 9:55:27 am | ||
7 | * Last Modified: Tuesday, 19th March 2019 9:55:34 am | ||
8 | * Modified By: 任超 | ||
9 | */ | ||
10 | |||
11 | <template> | ||
12 | <div :class="['lb-table', customClass]"> | ||
13 | <el-table v-if="!heightNumSetting" class="table-fixed" :row-style="{ height: '50px' }" ref="elTable" :border='border' | ||
14 | :row-class-name="tableRowClassName" :show-header='showHeader' @row-click="singleElection" v-bind="$attrs" | ||
15 | :height="tableHeight" v-on="$listeners" :data="data" style="width: 100%" | ||
16 | :span-method="this.merge ? this.mergeMethod : this.spanMethod"> | ||
17 | <el-table-column width="45" align="center" v-if="isRadio"> | ||
18 | <template slot-scope="scope"> | ||
19 | <el-radio v-model="selected" :label="scope.$index"></el-radio> | ||
20 | </template> | ||
21 | </el-table-column> | ||
22 | |||
23 | <el-table-column :label="downTitle" align="center"> | ||
24 | <lb-column v-bind="$attrs" v-for="(item, index) in column" :key="index" :column="item"> | ||
25 | </lb-column> | ||
26 | </el-table-column> | ||
27 | </el-table> | ||
28 | <br> | ||
29 | <el-pagination class="lb-table-pagination" v-if="pagination" v-bind="$attrs" v-on="$listeners" background | ||
30 | layout="total, prev, pager, next" @current-change="paginationCurrentChange" | ||
31 | :style="{ 'margin-top': paginationTop, 'text-align': paginationAlign }"> | ||
32 | </el-pagination> | ||
33 | </div> | ||
34 | </template> | ||
35 | |||
36 | <script> | ||
37 | import LbColumn from './LbColumn' | ||
38 | export default { | ||
39 | props: { | ||
40 | column: Array, | ||
41 | data: Array, | ||
42 | spanMethod: Function, | ||
43 | pagination: { | ||
44 | type: Boolean, | ||
45 | default: true, | ||
46 | }, | ||
47 | downExcel: { | ||
48 | type: Boolean, | ||
49 | default: false, | ||
50 | }, | ||
51 | downTitle: { | ||
52 | type: String, | ||
53 | default: '标题' | ||
54 | }, | ||
55 | isRadio: { | ||
56 | type: Boolean, | ||
57 | default: false, | ||
58 | }, | ||
59 | border: { | ||
60 | type: Boolean, | ||
61 | default: false, | ||
62 | }, | ||
63 | showHeader: { | ||
64 | type: Boolean, | ||
65 | default: true, | ||
66 | }, | ||
67 | paginationTop: { | ||
68 | type: String, | ||
69 | default: '0', | ||
70 | }, | ||
71 | heightNum: { | ||
72 | type: Number, | ||
73 | default: 355, | ||
74 | }, | ||
75 | maxHeight: { | ||
76 | type: Number, | ||
77 | default: 500 | ||
78 | }, | ||
79 | heightNumSetting: { | ||
80 | type: Boolean, | ||
81 | default: false, | ||
82 | }, | ||
83 | customClass: { | ||
84 | type: String, | ||
85 | default: '', | ||
86 | }, | ||
87 | paginationAlign: { | ||
88 | type: String, | ||
89 | default: 'left', | ||
90 | }, | ||
91 | merge: Array, | ||
92 | }, | ||
93 | components: { | ||
94 | LbColumn, | ||
95 | }, | ||
96 | data () { | ||
97 | return { | ||
98 | tableHeight: 'auto', | ||
99 | mergeLine: {}, | ||
100 | mergeIndex: {}, | ||
101 | selected: '' | ||
102 | } | ||
103 | }, | ||
104 | created () { | ||
105 | this.getMergeArr(this.data, this.merge) | ||
106 | this.getHeight() | ||
107 | }, | ||
108 | computed: { | ||
109 | dataLength () { | ||
110 | return [] || this.data.length | ||
111 | }, | ||
112 | }, | ||
113 | methods: { | ||
114 | // 单选 | ||
115 | singleElection (row) { | ||
116 | this.selected = this.data.indexOf(row); | ||
117 | }, | ||
118 | |||
119 | tableRowClassName ({ row, rowIndex }) { | ||
120 | if (rowIndex % 2 === 1) { | ||
121 | return 'interlaced'; | ||
122 | } | ||
123 | }, | ||
124 | getHeight () { | ||
125 | if (!this.heightNumSetting) { | ||
126 | let _this = this | ||
127 | if (this.heightNum) { | ||
128 | _this.$nextTick(() => { | ||
129 | |||
130 | window.addEventListener('resize', () => { | ||
131 | _this.tableHeight = _this.calcHeightx(230) | ||
132 | }); | ||
133 | _this.tableHeight = _this.calcHeightx(230) | ||
134 | }) | ||
135 | } else { | ||
136 | _this.tableHeight = window.innerHeight - _this.heightNum | ||
137 | } | ||
138 | } | ||
139 | }, | ||
140 | calcHeightx (value, wappered = true) { | ||
141 | //项目自定义的公共header部分的高度,可忽略 | ||
142 | let header = document.querySelector(".from-clues-header").offsetHeight; | ||
143 | //value为动态计算table界面高度时,减去的其他空白部分,需自行在调试找到临界值,剩下的就是table表格的高度(包含header+body部分) | ||
144 | value = value == undefined ? 100 : value; | ||
145 | let res = window.innerHeight - parseInt(header) - value; | ||
146 | if (wappered) { | ||
147 | //通过原生方法,获取dom节点的高度------获取element-ui table表格body的元素 | ||
148 | let wapper = window.document.getElementsByClassName('el-table__body-wrapper'); | ||
149 | //通过原生方法,获取dom节点的高度------获取element-ui table表格header的元素 | ||
150 | let header = window.document.getElementsByClassName('el-table__header-wrapper'); | ||
151 | //必须加延时,要不然赋不上去值 | ||
152 | setTimeout(() => { | ||
153 | //通过上边计算得到的table高度的value值,减去table表格的header高度,剩下的通过dom节点直接强行赋给table表格的body | ||
154 | wapper[0].style.height = (value - header[0].clientHeight) | ||
155 | }, 100) | ||
156 | } | ||
157 | return res; | ||
158 | }, | ||
159 | clearSelection () { | ||
160 | this.$refs.elTable.clearSelection() | ||
161 | }, | ||
162 | toggleRowSelection (row, selected) { | ||
163 | this.$refs.elTable.toggleRowSelection(row, selected) | ||
164 | }, | ||
165 | toggleAllSelection () { | ||
166 | this.$refs.elTable.toggleAllSelection() | ||
167 | }, | ||
168 | toggleRowExpansion (row, expanded) { | ||
169 | this.$refs.elTable.toggleRowExpansion(row, expanded) | ||
170 | }, | ||
171 | setCurrentRow (row) { | ||
172 | this.$refs.elTable.setCurrentRow(row) | ||
173 | }, | ||
174 | clearSort () { | ||
175 | this.$refs.elTable.clearSort() | ||
176 | }, | ||
177 | clearFilter (columnKey) { | ||
178 | this.$refs.elTable.clearFilter(columnKey) | ||
179 | }, | ||
180 | doLayout () { | ||
181 | this.$refs.elTable.doLayout() | ||
182 | }, | ||
183 | sort (prop, order) { | ||
184 | this.$refs.elTable.sort(prop, order) | ||
185 | }, | ||
186 | paginationCurrentChange (val) { | ||
187 | this.$emit('p-current-change', val) | ||
188 | }, | ||
189 | getMergeArr (tableData, merge) { | ||
190 | if (!merge) return | ||
191 | this.mergeLine = {} | ||
192 | this.mergeIndex = {} | ||
193 | merge.forEach((item, k) => { | ||
194 | tableData.forEach((data, i) => { | ||
195 | if (i === 0) { | ||
196 | this.mergeIndex[item] = this.mergeIndex[item] || [] | ||
197 | this.mergeIndex[item].push(1) | ||
198 | this.mergeLine[item] = 0 | ||
199 | } else { | ||
200 | if (data[item] === tableData[i - 1][item]) { | ||
201 | this.mergeIndex[item][this.mergeLine[item]] += 1 | ||
202 | this.mergeIndex[item].push(0) | ||
203 | } else { | ||
204 | this.mergeIndex[item].push(1) | ||
205 | this.mergeLine[item] = i | ||
206 | } | ||
207 | } | ||
208 | }) | ||
209 | }) | ||
210 | }, | ||
211 | mergeMethod ({ row, column, rowIndex, columnIndex }) { | ||
212 | const index = this.merge.indexOf(column.property) | ||
213 | if (index > -1) { | ||
214 | const _row = this.mergeIndex[this.merge[index]][rowIndex] | ||
215 | const _col = _row > 0 ? 1 : 0 | ||
216 | return { | ||
217 | rowspan: _row, | ||
218 | colspan: _col, | ||
219 | } | ||
220 | } | ||
221 | }, | ||
222 | }, | ||
223 | watch: { | ||
224 | merge () { | ||
225 | this.getMergeArr(this.data, this.merge) | ||
226 | }, | ||
227 | dataLength () { | ||
228 | this.getMergeArr(this.data, this.merge) | ||
229 | } | ||
230 | }, | ||
231 | } | ||
232 | </script> | ||
233 | <style rel="stylesheet/scss" scoped lang="scss"> | ||
234 | .lb-table { | ||
235 | margin-top: 1px; | ||
236 | |||
237 | .interlaced { | ||
238 | background: #fafcff; | ||
239 | border: 1px solid #ebf2fa; | ||
240 | } | ||
241 | } | ||
242 | |||
243 | /deep/.el-table .cell { | ||
244 | padding-left: 3px; | ||
245 | padding-right: 3px; | ||
246 | } | ||
247 | |||
248 | /deep/.el-radio__label { | ||
249 | display: none; | ||
250 | } | ||
251 | </style> |
-
Please register or sign in to post a comment