879ee292 by renchao@pashanhoo.com

1

1 parent fcfe609b
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"
14 :border='border' :row-class-name="tableRowClassName" :show-header='showHeader' @row-click="singleElection"
15 :header-cell-style="{ background: 'rgb(236, 245, 255)' }" v-bind="$attrs" :height="tableHeight" v-on="$listeners"
16 :data="data" style="width: 100%" :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" class="table-radio"></el-radio>
20 </template>
21 </el-table-column>
22
23 <lb-column v-bind="$attrs" v-for="(item, index) in column" :key="index" :column="item">
24 </lb-column>
25 </el-table>
26
27 <el-table v-else ref="elTable" class="table-fixed" :row-style="{ height: '50px' }" :border='border'
28 :row-class-name="tableRowClassName" :show-header='showHeader'
29 :header-cell-style="{ background: 'rgb(236, 245, 255)' }" v-bind="$attrs" :max-height="maxHeight"
30 v-on="$listeners" :data="data" style="width: 100%" :span-method="this.merge ? this.mergeMethod : this.spanMethod">
31
32 <el-table-column width="45" align="center" v-if="isRadio">
33 <template slot-scope="scope">
34 <el-radio v-model="selected" :label="scope.$index" class="table-radio"></el-radio>
35 </template>
36 </el-table-column>
37 <lb-column v-bind="$attrs" v-for="(item, index) in column" :key="index" :column="item">
38 </lb-column>
39 </el-table>
40
41 <br>
42 <el-pagination class="lb-table-pagination" v-if="pagination" v-bind="$attrs" v-on="$listeners" background
43 :page-sizes="[10, 20, 50, 100]" layout="total, sizes, prev, pager, next" @current-change="paginationCurrentChange"
44 :style="{ 'margin-top': paginationTop, 'text-align': paginationAlign }">
45 </el-pagination>
46 </div>
47 </template>
48
49 <script>
50 import LbColumn from './lb-column'
51 export default {
52 props: {
53 column: Array,
54 data: Array,
55 spanMethod: Function,
56 pagination: {
57 type: Boolean,
58 default: true,
59 },
60 isRadio: {
61 type: Boolean,
62 default: false,
63 },
64 border: {
65 type: Boolean,
66 default: true,
67 },
68 showHeader: {
69 type: Boolean,
70 default: true,
71 },
72 paginationTop: {
73 type: String,
74 default: '0',
75 },
76 heightNum: {
77 type: Number,
78 default: 265,
79 },
80 maxHeight: {
81 type: Number,
82 default: 500
83 },
84 heightNumSetting: {
85 type: Boolean,
86 default: false,
87 },
88 customClass: {
89 type: String,
90 default: '',
91 },
92 paginationAlign: {
93 type: String,
94 default: 'left',
95 },
96 merge: Array,
97 },
98 components: {
99 LbColumn,
100 },
101 data () {
102 return {
103 tableHeight: '',
104 mergeLine: {},
105 mergeIndex: {},
106 selected: ''
107 }
108 },
109 created () {
110 this.getMergeArr(this.data, this.merge)
111 this.getHeight()
112 },
113 computed: {
114 dataLength () {
115 return [] || this.data.length
116 },
117 },
118 methods: {
119 // 单选
120 singleElection (row) {
121 this.selected = this.data.indexOf(row);
122 },
123
124 tableRowClassName ({ row, rowIndex }) {
125 if (rowIndex % 2 === 1) {
126 return 'interlaced';
127 }
128 },
129 getHeight () {
130 if (!this.heightNumSetting) {
131 this.tableHeight = window.innerHeight - this.heightNum
132 }
133 },
134 clearSelection () {
135 this.$refs.elTable.clearSelection()
136 },
137 toggleRowSelection (row, selected) {
138 this.$refs.elTable.toggleRowSelection(row, selected)
139 },
140 toggleAllSelection () {
141 this.$refs.elTable.toggleAllSelection()
142 },
143 toggleRowExpansion (row, expanded) {
144 this.$refs.elTable.toggleRowExpansion(row, expanded)
145 },
146 setCurrentRow (row) {
147 this.$refs.elTable.setCurrentRow(row)
148 },
149 clearSort () {
150 this.$refs.elTable.clearSort()
151 },
152 clearFilter (columnKey) {
153 this.$refs.elTable.clearFilter(columnKey)
154 },
155 doLayout () {
156 this.$refs.elTable.doLayout()
157 },
158 sort (prop, order) {
159 this.$refs.elTable.sort(prop, order)
160 },
161 paginationCurrentChange (val) {
162 this.$emit('p-current-change', val)
163 },
164 getMergeArr (tableData, merge) {
165 if (!merge) return
166 this.mergeLine = {}
167 this.mergeIndex = {}
168 merge.forEach((item, k) => {
169 tableData.forEach((data, i) => {
170 if (i === 0) {
171 this.mergeIndex[item] = this.mergeIndex[item] || []
172 this.mergeIndex[item].push(1)
173 this.mergeLine[item] = 0
174 } else {
175 if (data[item] === tableData[i - 1][item]) {
176 this.mergeIndex[item][this.mergeLine[item]] += 1
177 this.mergeIndex[item].push(0)
178 } else {
179 this.mergeIndex[item].push(1)
180 this.mergeLine[item] = i
181 }
182 }
183 })
184 })
185 },
186 mergeMethod ({ row, column, rowIndex, columnIndex }) {
187 const index = this.merge.indexOf(column.property)
188 if (index > -1) {
189 const _row = this.mergeIndex[this.merge[index]][rowIndex]
190 const _col = _row > 0 ? 1 : 0
191 return {
192 rowspan: _row,
193 colspan: _col,
194 }
195 }
196 },
197 },
198 watch: {
199 merge () {
200 this.getMergeArr(this.data, this.merge)
201 },
202 dataLength () {
203 this.getMergeArr(this.data, this.merge)
204 }
205 },
206 }
207 </script>
208 <style rel="stylesheet/scss" scoped lang="scss">
209 .lb-table {
210 margin-top: 1px;
211
212 .interlaced {
213 background: #fafcff;
214 border: 1px solid #ebf2fa;
215 }
216 }
217
218 /deep/.el-table .cell {
219 padding-left: 3px;
220 padding-right: 3px;
221 }
222
223 .table-radio {
224 /deep/.el-radio__label {
225 display: none;
226 }
227 }
228
229 /deep/.el-radio {
230 margin-right: 5px !important;
231 }
232 </style>
1 <template>
2 <div :class="['lb-table', customClass]">
3 <el-table v-if="!heightNumSetting" class="table-fixed" :row-style="{ height: '50px' }" ref="elTable" :border='border'
4 :row-class-name="tableRowClassName" :show-header='showHeader' @row-click="singleElection" v-bind="$attrs"
5 :height="tableHeight" v-on="$listeners" :data="data" style="width: 100%"
6 :span-method="this.merge ? this.mergeMethod : this.spanMethod">
7 <el-table-column width="45" align="center" v-if="isRadio">
8 <template slot-scope="scope">
9 <el-radio v-model="selected" :label="scope.$index"></el-radio>
10 </template>
11 </el-table-column>
12
13 <lb-column v-bind="$attrs" v-for="(item, index) in column" :key="index" :column="item">
14 </lb-column>
15 </el-table>
16
17 <el-table v-else ref="elTable" id="heightNumSetting" class="table-fixed" :row-style="{ height: '50px' }"
18 :border='border' :row-class-name="tableRowClassName" :show-header='showHeader' v-bind="$attrs"
19 :max-height="maxHeight" :height="tableHeight" v-on="$listeners" :data="data" style="width: 100%"
20 :span-method="this.merge ? this.mergeMethod : this.spanMethod">
21
22 <el-table-column width="45" align="center" v-if="isRadio">
23 <template slot-scope="scope">
24 <el-radio v-model="selected" :label="scope.$index"></el-radio>
25 </template>
26 </el-table-column>
27 <lb-column v-bind="$attrs" v-for="(item, index) in column" :key="index" :column="item">
28 </lb-column>
29 </el-table>
30
31 <br>
32 <el-pagination class="lb-table-pagination" v-if="pagination" v-bind="$attrs" v-on="$listeners" background
33 layout="total, prev, pager, next" @current-change="paginationCurrentChange"
34 :style="{ 'margin-top': paginationTop, 'text-align': paginationAlign }">
35 </el-pagination>
36 </div>
37 </template>
38
39 <script>
40 import LbColumn from './lb-column'
41 export default {
42 props: {
43 column: Array,
44 data: Array,
45 spanMethod: Function,
46 pagination: {
47 type: Boolean,
48 default: true,
49 },
50 isRadio: {
51 type: Boolean,
52 default: false,
53 },
54 border: {
55 type: Boolean,
56 default: false,
57 },
58 showHeader: {
59 type: Boolean,
60 default: true,
61 },
62 paginationTop: {
63 type: String,
64 default: '0',
65 },
66 heightNum: {
67 type: Number,
68 default: 355,
69 },
70 maxHeight: {
71 type: Number,
72 default: 500
73 },
74 minHeight: {
75 type: Number,
76 default: undefined
77 },
78 heightNumSetting: {
79 type: Boolean,
80 default: false,
81 },
82 customClass: {
83 type: String,
84 default: '',
85 },
86 paginationAlign: {
87 type: String,
88 default: 'left',
89 },
90 calcHeight: {
91 type: Number,
92 default: 170
93 },
94 merge: Array,
95 },
96 components: {
97 LbColumn,
98 },
99 data () {
100 return {
101 tableHeight: 'auto',
102 mergeLine: {},
103 mergeIndex: {},
104 selected: ''
105 }
106 },
107 created () {
108 this.getMergeArr(this.data, this.merge)
109 this.getHeight()
110 },
111 computed: {
112 dataLength () {
113 return [] || this.data.length
114 },
115 },
116 methods: {
117 // 单选
118 singleElection (row) {
119 this.selected = this.data.indexOf(row);
120 },
121
122 tableRowClassName ({ row, rowIndex }) {
123 if (rowIndex % 2 === 1) {
124 return 'interlaced';
125 }
126 },
127 getHeight () {
128 if (!this.heightNumSetting) {
129 let _this = this
130 if (this.heightNum) {
131 _this.$nextTick(() => {
132 if (document.querySelector(".tags-view-container")) {
133 window.addEventListener('resize', () => {
134 if (_this.calcHeight == 230) {
135 _this.tableHeight = _this.calcHeightx(192)
136 } else {
137 _this.tableHeight = _this.calcHeightx(_this.calcHeight)
138 }
139 });
140 if (_this.calcHeight == 230) {
141 _this.tableHeight = _this.calcHeightx(192)
142 } else {
143 _this.tableHeight = _this.calcHeightx(_this.calcHeight)
144 }
145 } else {
146 window.addEventListener('resize', () => {
147 _this.tableHeight = _this.calcHeightx(_this.calcHeight)
148 });
149 _this.tableHeight = _this.calcHeightx(_this.calcHeight)
150 }
151 })
152 } else {
153 _this.tableHeight = window.innerHeight - _this.heightNum
154 }
155 } else {
156 this.tableHeight = this.heightNum
157 this.$nextTick(() => {
158 this.minHeight && (document.getElementById('heightNumSetting').style.minHeight = this.minHeight + 'px')
159 })
160 }
161 },
162 calcHeightx (value, wappered = true) {
163 //项目自定义的公共header部分的高度,可忽略
164 let header = document.querySelector(".from-clues-header").offsetHeight;
165
166 //value为动态计算table界面高度时,减去的其他空白部分,需自行在调试找到临界值,剩下的就是table表格的高度(包含header+body部分)
167 value = value == undefined ? 100 : value;
168 if (document.querySelector(".tags-view-container")) {
169 let tagsView = document.querySelector(".tags-view-container").offsetHeight;
170 var res = window.innerHeight - parseInt(header) - value - parseInt(tagsView);
171 } else {
172 var res = window.innerHeight - parseInt(header) - value;
173 }
174 if (wappered) {
175 //通过原生方法,获取dom节点的高度------获取element-ui table表格body的元素
176 let wapper = window.document.getElementsByClassName('el-table__body-wrapper');
177 //通过原生方法,获取dom节点的高度------获取element-ui table表格header的元素
178 let header = window.document.getElementsByClassName('el-table__header-wrapper');
179 //必须加延时,要不然赋不上去值
180 setTimeout(() => {
181 //通过上边计算得到的table高度的value值,减去table表格的header高度,剩下的通过dom节点直接强行赋给table表格的body
182 wapper[0].style.height = (value - header[0].clientHeight)
183 }, 100)
184 }
185 return res;
186 },
187 clearSelection () {
188 this.$refs.elTable.clearSelection()
189 },
190 toggleRowSelection (row, selected) {
191 this.$refs.elTable.toggleRowSelection(row, selected)
192 },
193 toggleAllSelection () {
194 this.$refs.elTable.toggleAllSelection()
195 },
196 toggleRowExpansion (row, expanded) {
197 this.$refs.elTable.toggleRowExpansion(row, expanded)
198 },
199 setCurrentRow (row) {
200 this.$refs.elTable.setCurrentRow(row)
201 },
202 clearSort () {
203 this.$refs.elTable.clearSort()
204 },
205 clearFilter (columnKey) {
206 this.$refs.elTable.clearFilter(columnKey)
207 },
208 doLayout () {
209 this.$refs.elTable.doLayout()
210 },
211 sort (prop, order) {
212 this.$refs.elTable.sort(prop, order)
213 },
214 paginationCurrentChange (val) {
215 this.$emit('p-current-change', val)
216 },
217 getMergeArr (tableData, merge) {
218 if (!merge) return
219 this.mergeLine = {}
220 this.mergeIndex = {}
221 merge.forEach((item, k) => {
222 tableData.forEach((data, i) => {
223 if (i === 0) {
224 this.mergeIndex[item] = this.mergeIndex[item] || []
225 this.mergeIndex[item].push(1)
226 this.mergeLine[item] = 0
227 } else {
228 if (data[item] === tableData[i - 1][item]) {
229 this.mergeIndex[item][this.mergeLine[item]] += 1
230 this.mergeIndex[item].push(0)
231 } else {
232 this.mergeIndex[item].push(1)
233 this.mergeLine[item] = i
234 }
235 }
236 })
237 })
238 },
239 mergeMethod ({ row, column, rowIndex, columnIndex }) {
240 const index = this.merge.indexOf(column.property)
241 if (index > -1) {
242 const _row = this.mergeIndex[this.merge[index]][rowIndex]
243 const _col = _row > 0 ? 1 : 0
244 return {
245 rowspan: _row,
246 colspan: _col,
247 }
248 }
249 },
250 },
251 watch: {
252 merge () {
253 this.getMergeArr(this.data, this.merge)
254 },
255 dataLength () {
256 this.getMergeArr(this.data, this.merge)
257 }
258 },
259 }
260 </script>
261 <style rel="stylesheet/scss" scoped lang="scss">
262 .lb-table {
263 margin-top: 1px;
264
265 .interlaced {
266 background: #fafcff;
267 border: 1px solid #ebf2fa;
268 }
269 }
270
271 /deep/.el-table .cell {
272 padding-left: 3px;
273 padding-right: 3px;
274 }
275
276 /deep/.el-radio__label {
277 display: none;
278 }
279 </style>
280