83c80a68 by yuanbo

增加注释

1 parent bd129aa0
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>
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 tableRowClassName ({ row, rowIndex }) {
119 if (rowIndex % 2 === 1) {
120 return 'interlaced';
121 }
122 },
123 getHeight () {
124 if (!this.heightNumSetting) {
125 let _this = this
126 if (this.heightNum) {
127 _this.$nextTick(() => {
128
129 window.addEventListener('resize', () => {
130 _this.tableHeight = _this.calcHeightx(230)
131 });
132 _this.tableHeight = _this.calcHeightx(230)
133 })
134 } else {
135 _this.tableHeight = window.innerHeight - _this.heightNum
136 }
137 }
138 },
139 calcHeightx (value, wappered = true) {
140 //项目自定义的公共header部分的高度,可忽略
141 let header = document.querySelector(".from-clues-header").offsetHeight;
142 //value为动态计算table界面高度时,减去的其他空白部分,需自行在调试找到临界值,剩下的就是table表格的高度(包含header+body部分)
143 value = value == undefined ? 100 : value;
144 let res = window.innerHeight - parseInt(header) - value;
145 if (wappered) {
146 //通过原生方法,获取dom节点的高度------获取element-ui table表格body的元素
147 let wapper = window.document.getElementsByClassName('el-table__body-wrapper');
148 //通过原生方法,获取dom节点的高度------获取element-ui table表格header的元素
149 let header = window.document.getElementsByClassName('el-table__header-wrapper');
150 //必须加延时,要不然赋不上去值
151 setTimeout(() => {
152 //通过上边计算得到的table高度的value值,减去table表格的header高度,剩下的通过dom节点直接强行赋给table表格的body
153 wapper[0].style.height = (value - header[0].clientHeight)
154 }, 100)
155 }
156 return res;
157 },
158 clearSelection () {
159 this.$refs.elTable.clearSelection()
160 },
161 toggleRowSelection (row, selected) {
162 this.$refs.elTable.toggleRowSelection(row, selected)
163 },
164 toggleAllSelection () {
165 this.$refs.elTable.toggleAllSelection()
166 },
167 toggleRowExpansion (row, expanded) {
168 this.$refs.elTable.toggleRowExpansion(row, expanded)
169 },
170 setCurrentRow (row) {
171 this.$refs.elTable.setCurrentRow(row)
172 },
173 clearSort () {
174 this.$refs.elTable.clearSort()
175 },
176 clearFilter (columnKey) {
177 this.$refs.elTable.clearFilter(columnKey)
178 },
179 doLayout () {
180 this.$refs.elTable.doLayout()
181 },
182 sort (prop, order) {
183 this.$refs.elTable.sort(prop, order)
184 },
185 paginationCurrentChange (val) {
186 this.$emit('p-current-change', val)
187 },
188 getMergeArr (tableData, merge) {
189 if (!merge) return
190 this.mergeLine = {}
191 this.mergeIndex = {}
192 merge.forEach((item, k) => {
193 tableData.forEach((data, i) => {
194 if (i === 0) {
195 this.mergeIndex[item] = this.mergeIndex[item] || []
196 this.mergeIndex[item].push(1)
197 this.mergeLine[item] = 0
198 } else {
199 if (data[item] === tableData[i - 1][item]) {
200 this.mergeIndex[item][this.mergeLine[item]] += 1
201 this.mergeIndex[item].push(0)
202 } else {
203 this.mergeIndex[item].push(1)
204 this.mergeLine[item] = i
205 }
206 }
207 })
208 })
209 },
210 mergeMethod ({ row, column, rowIndex, columnIndex }) {
211 const index = this.merge.indexOf(column.property)
212 if (index > -1) {
213 const _row = this.mergeIndex[this.merge[index]][rowIndex]
214 const _col = _row > 0 ? 1 : 0
215 return {
216 rowspan: _row,
217 colspan: _col,
218 }
219 }
220 },
221 },
222 watch: {
223 merge () {
224 this.getMergeArr(this.data, this.merge)
225 },
226 dataLength () {
227 this.getMergeArr(this.data, this.merge)
228 }
229 },
230 }
231 </script>
232 <style rel="stylesheet/scss" scoped lang="scss">
233 .lb-table {
234 margin-top: 1px;
235
236 .interlaced {
237 background: #fafcff;
238 border: 1px solid #ebf2fa;
239 }
240 }
241
242 /deep/.el-table .cell {
243 padding-left: 3px;
244 padding-right: 3px;
245 }
246
247 /deep/.el-radio__label {
248 display: none;
249 }
250 </style>
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>
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>