我是靠谱客的博主 隐形帆布鞋,这篇文章主要介绍Vue封装通用table组件的完整步骤记录,现在分享给大家,希望可以做个参考。

前言

随着业务的发展和功能的增多,我们发现不少页面都具备相似的功能,这里举几个比较俗的例子:可以多选的下拉菜单,带输入的对话框,日期选择器等等,于是我们会想办法将这些共有的功能抽取成一个个公共组件,以便能够在不同的页面或业务中使用。

为什么需要封装table组件?

后台管理系统表格使用频率高,减少关于table的业务代码,且便于后期统一修改、便于后期维护。如给table内容展示,超出单元格以省略号展示等。

对于大部分的后台管理系统,数据表格的展示大同小异,由于不想写重复的代码,所以我选择封装通用table组件,解放双手。如果你的表格有一列并不是简单dom元素,比如switch按钮,完全可以传入一个render函数,来达到目的。

第一步:定义通用组件

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
<!-- pro-table.vue --> <template> <div> <el-table :data="tableData" style="width: 100%" :stripe="tableTitle.stripe" :border="tableTitle.border" :fit="tableTitle.fit" :highlight-current-row="tableTitle.highlightCurrentRow" @selection-change="handleSelectionChange"> <!--表格第一列--> <el-table-column :type="firstTableCol.type" :width="firstTableCol.width" v-if="firstTableCol.select" > </el-table-column> <!--表格其它列--> <el-table-column v-for="(value,index) in tableCol" :key="index" :prop="value.prop" :label="value.label" :width="value.width || 180"> <template slot-scope="scope"> <template v-if="!value.render"> <template v-if="value.formatter"> {{ value.formatter(scope.row, value) }} </template> <template v-else-if="value.getImgurl"> <el-image :src="value.getImgurl(scope.row, value)" style="width: 70px; height: 70px" :preview-src-list="value.previewSrcList ? value.previewSrcList(scope.row, value) : value.getImgurl(scope.row, value).split(',')"/> </template> <template v-else> {{ scope.row[value.prop] }} </template> </template> <!--扩展dom--> <template v-else> <Table :key="`cus${index}`" :render="value.render" :param="scope.row"></Table> </template> </template> </el-table-column> <!--基础操作--> <el-table-column label="操作"> <template slot-scope="scope"> <el-button type="text" v-for="(value,index) in operator" @click="value.click(scope.row, value)" :key="index"> {{ value.text }} </el-button> </template> </el-table-column> </el-table> <!--分页插件--> <el-pagination v-show="total>0" :total="total" :page-size.sync="pageSize" :current-page.sync="currentPage" :page-sizes="[10, 20, 30, 50]" layout="total, sizes, prev, pager, next, jumper" @current-change="handleCurrentChange" @size-change="handleSizeChange" v-bind="$attrs"> </el-pagination> </div> </template> <script> // render函数 import Table from './table' export default { components: {Table}, props: { tableTitle: { type: Object, default: { stripe: false, border: false, fit: true, highlightCurrentRow: false } }, firstTableCol: { type: Object, default: { select: false, width: 55, type: 'selection' } }, tableCol: { type: Array, default: [] }, tableData: { type: Array, default: [] }, operator: { type: Array, default: [] }, total: { type: Number, default: 0 }, page: { type: Number, default: 1 }, limit: { type: Number, default: 10 }, autoScroll: { type: Boolean, default: true } }, computed: { currentPage: { get () { return this.page }, set (val) { this.$emit('update:page', val) } }, pageSize: { get () { return this.limit }, set (val) { this.$emit('update:limit', val) } } }, data () { return { } }, methods: { // 监听table选择框 handleSelectionChange (selection) { // 调用父组件对应的方法 handleSelectionChange this.$emit('handleSelectionChange', selection) }, // 监听每页多少条数据(limit) handleSizeChange (limit) { this.$emit('pagination', {page: this.currentPage, limit: limit}) if (this.autoScroll) { scrollTo(0, 800) } }, // 监听当前是第几页(page) handleCurrentChange (page) { this.$emit('pagination', {page: page, limit: this.pageSize}) if (this.autoScroll) { scrollTo(0, 800) } } } } </script> <style scoped> </style>

第二步:父组件与子组件进行render通信

为了实现父组件render函数在子组件中生效,我们需要定义一个render函数,在子组件中引用。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// table.js export default { props: { render: { type: Function }, param: { type: Object } }, render(h) { return this.render(h, this.param) } }

第三步:使用组件

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
<template> <div> <!-- @自定义事件="父组件方法", 子组件中,this.$emit('自定义事件名称') 触发父组件事件。 ref="proTable",标记在子组件上,指向子组件实例 --> <proTable ref="proTable" :tableTitle="tableTitle" :tableCol="tableCol" :tableData="tableData" :operator="operator" :firstTableCol="firstTableCol" @handleSelectionChange="handleSelectionChange" :total="total" :page.sync="queryParams.page" :limit.sync="queryParams.limit" @pagination="getList"/> </div> </template> <script> import proTable from './pro-table' export default { components: { proTable }, data() { return { queryParams: { page: 1, limit: 10, }, type: 'success', total: 50, // element-ui中对table属性的设置 tableTitle: { 'stripe': true, "highlightCurrentRow": true }, // 设置table的列 tableCol: [ { prop:'date',label:'日期'}, { prop:'name',label:'姓名'}, { prop:'address',label:'地址',width: 300}, { prop:'src',label:'图片', getImgurl: (row, col, cellValue) => { return this.getImgurl(row)}, previewSrcList: (row, col, cellValue) => {return this.listImgUrl(row)}}, { prop:'sex',label:'性别', formatter: (row, col, cellVaule) => {return this.sexFormatter(row)}}, { prop:'src',label:'图片', getImgurl: (row, col, cellValue) => { return this.getImgurl(row)}}, { prop:'text',label:'函数', render: (h, params) => {return this.render(h, params)}} ], // table的基本操作 operator: [ {'text':'详情', click: (row, col, cellValue) => {return this.getInfo(row)}}, {'text':'删除', click: (row, col, cellValue) => {return this.delInfo(row)}}, {'text':'编辑', click: (row, col, cellValue) => {return this.editInfo(row)}}, ], // 模拟数据 tableData: [ { date: '2016-05-02', name: '王小虎', address: '上海市普陀区金沙江路 1518 弄', sex: 0, img:'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fpic2.zhimg.com%2F50%2Fv2-193cbb243dc14d3a016caaa54ba02837_hd.jpg&refer=http%3A%2F%2Fpic2.zhimg.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1628435704&t=deb5584cb9ff53fe6977f14a5e0755bb' }, { date: '2016-05-04', name: '王小虎', address: '上海市普陀区金沙江路 1517 弄', sex: 1, img:'https://pic1.zhimg.com/80/v2-894ab624807fd4cfa33dd4e42cc90ac8_720w.jpg?source=1940ef5c' }, { date: '2016-05-01', name: '王小虎', address: '上海市普陀区金沙江路 1519 弄', sex: 0, img:'xx.jpg' }, { date: '2016-05-03', name: '王小虎', address: '上海市普陀区金沙江路 1516 弄', sex: 1, img:'xx.jpg' }], firstTableCol: { 'select': true, 'type': 'selection' } } }, methods: { getInfo(val) { // 触发父方法 console.log("获取详情",val) }, delInfo(val) { // 触发父方法 console.log("删除信息",val) }, editInfo(val) { // 触发父方法 console.log("编辑信息",val) }, getImgurl(val) { console.log(val.img) return val.img }, sexFormatter(val) { return val.sex === 0 ? '男' : '女' }, handleSelectionChange(val) { console.log("监听选择框",val) }, getList(queryParams) { console.log("父级方法",queryParams) }, listImgUrl() { let array = []; array.push("https://pic1.zhimg.com/80/v2-894ab624807fd4cfa33dd4e42cc90ac8_720w.jpg?source=1940ef5c"); array.push("https://cdn.pixabay.com/photo/2021/07/01/21/20/girl-6380331_960_720.jpg"); return array; }, render(h, params) { return h('span', null , '我是一个render组件') } } } </script>

总结

在引用组件的页面中,我们可以给每一个table列加方法,也可以给编辑、删除、详情添加自定义的方法,完全实现定制化。也可以自定义render函数。效果图如下:

到此这篇关于Vue封装通用table组件的文章就介绍到这了,更多相关Vue封装通用table组件内容请搜索靠谱客以前的文章或继续浏览下面的相关文章希望大家以后多多支持靠谱客!

最后

以上就是隐形帆布鞋最近收集整理的关于Vue封装通用table组件的完整步骤记录的全部内容,更多相关Vue封装通用table组件内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(359)

评论列表共有 0 条评论

立即
投稿
返回
顶部