Vue封裝通用table組件的完整步驟記錄
前言
隨著業(yè)務(wù)的發(fā)展和功能的增多,我們發(fā)現(xiàn)不少頁面都具備相似的功能,這里舉幾個(gè)比較俗的例子:可以多選的下拉菜單,帶輸入的對(duì)話框,日期選擇器等等,于是我們會(huì)想辦法將這些共有的功能抽取成一個(gè)個(gè)公共組件,以便能夠在不同的頁面或業(yè)務(wù)中使用。
為什么需要封裝table組件?
后臺(tái)管理系統(tǒng)表格使用頻率高,減少關(guān)于table的業(yè)務(wù)代碼,且便于后期統(tǒng)一修改、便于后期維護(hù)。如給table內(nèi)容展示,超出單元格以省略號(hào)展示等。
對(duì)于大部分的后臺(tái)管理系統(tǒng),數(shù)據(jù)表格的展示大同小異,由于不想寫重復(fù)的代碼,所以我選擇封裝通用table組件,解放雙手。如果你的表格有一列并不是簡(jiǎn)單dom元素,比如switch按鈕,完全可以傳入一個(gè)render函數(shù),來達(dá)到目的。
第一步:定義通用組件
<!-- 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> <!--擴(kuò)展dom--> <template v-else> <Table :key="`cus${index}`" :render="value.render" :param="scope.row"></Table> </template> </template> </el-table-column> <!--基礎(chǔ)操作--> <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函數(shù) 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: { // 監(jiān)聽table選擇框 handleSelectionChange (selection) { // 調(diào)用父組件對(duì)應(yīng)的方法 handleSelectionChange this.$emit('handleSelectionChange', selection) }, // 監(jiān)聽每頁多少條數(shù)據(jù)(limit) handleSizeChange (limit) { this.$emit('pagination', {page: this.currentPage, limit: limit}) if (this.autoScroll) { scrollTo(0, 800) } }, // 監(jiān)聽當(dāng)前是第幾頁(page) handleCurrentChange (page) { this.$emit('pagination', {page: page, limit: this.pageSize}) if (this.autoScroll) { scrollTo(0, 800) } } } } </script> <style scoped> </style>
第二步:父組件與子組件進(jìn)行render通信
為了實(shí)現(xiàn)父組件render函數(shù)在子組件中生效,我們需要定義一個(gè)render函數(shù),在子組件中引用。
// table.js export default { props: { render: { type: Function }, param: { type: Object } }, render(h) { return this.render(h, this.param) } }
第三步:使用組件
<template> <div> <!-- @自定義事件="父組件方法", 子組件中,this.$emit('自定義事件名稱') 觸發(fā)父組件事件。 ref="proTable",標(biāo)記在子組件上,指向子組件實(shí)例 --> <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中對(duì)table屬性的設(shè)置 tableTitle: { 'stripe': true, "highlightCurrentRow": true }, // 設(shè)置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:'函數(shù)', 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)}}, ], // 模擬數(shù)據(jù) tableData: [ { date: '2016-05-02', name: '王小虎', address: '上海市普陀區(qū)金沙江路 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: '上海市普陀區(qū)金沙江路 1517 弄', sex: 1, img:'https://pic1.zhimg.com/80/v2-894ab624807fd4cfa33dd4e42cc90ac8_720w.jpg?source=1940ef5c' }, { date: '2016-05-01', name: '王小虎', address: '上海市普陀區(qū)金沙江路 1519 弄', sex: 0, img:'xx.jpg' }, { date: '2016-05-03', name: '王小虎', address: '上海市普陀區(qū)金沙江路 1516 弄', sex: 1, img:'xx.jpg' }], firstTableCol: { 'select': true, 'type': 'selection' } } }, methods: { getInfo(val) { // 觸發(fā)父方法 console.log("獲取詳情",val) }, delInfo(val) { // 觸發(fā)父方法 console.log("刪除信息",val) }, editInfo(val) { // 觸發(fā)父方法 console.log("編輯信息",val) }, getImgurl(val) { console.log(val.img) return val.img }, sexFormatter(val) { return val.sex === 0 ? '男' : '女' }, handleSelectionChange(val) { console.log("監(jiān)聽選擇框",val) }, getList(queryParams) { console.log("父級(jí)方法",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 , '我是一個(gè)render組件') } } } </script>
總結(jié)
在引用組件的頁面中,我們可以給每一個(gè)table列加方法,也可以給編輯、刪除、詳情添加自定義的方法,完全實(shí)現(xiàn)定制化。也可以自定義render函數(shù)。效果圖如下:
到此這篇關(guān)于Vue封裝通用table組件的文章就介紹到這了,更多相關(guān)Vue封裝通用table組件內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Vue/React子組件實(shí)例暴露方法(TypeScript)
最近幾個(gè)月都在用TS開發(fā)各種項(xiàng)目,框架有涉及到Vue3,React18等,記錄一下Vue/React組件暴露出變量/函數(shù)的方法的寫法,對(duì)vue?react組件暴露方法相關(guān)知識(shí)感興趣的朋友跟隨小編一起看看吧2022-11-11vue實(shí)現(xiàn)路由不變的情況下,刷新頁面操作示例
這篇文章主要介紹了vue實(shí)現(xiàn)路由不變的情況下,刷新頁面操作,結(jié)合實(shí)例形式分析了vue路由不變的情況下刷新頁面具體原理、操作方法與相關(guān)注意事項(xiàng),需要的朋友可以參考下2020-02-02vant中的Cascader級(jí)聯(lián)選擇異步加載地區(qū)數(shù)據(jù)方式
這篇文章主要介紹了vant中的Cascader級(jí)聯(lián)選擇異步加載地區(qū)數(shù)據(jù)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-07-07nuxt 實(shí)現(xiàn)在其它js文件中使用store的方式
這篇文章主要介紹了nuxt 實(shí)現(xiàn)在其它js文件中使用store的方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-11-11vue實(shí)現(xiàn)的封裝全局filter并統(tǒng)一管理操作示例
這篇文章主要介紹了vue實(shí)現(xiàn)的封裝全局filter并統(tǒng)一管理操作,結(jié)合實(shí)例形式詳細(xì)分析了vue封裝全局filter及相關(guān)使用技巧,需要的朋友可以參考下2020-02-02vue將時(shí)間戳轉(zhuǎn)換成自定義時(shí)間格式的方法
下面小編就為大家分享一篇vue將時(shí)間戳轉(zhuǎn)換成自定義時(shí)間格式的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-03-03Vue 數(shù)據(jù)響應(yīng)式相關(guān)總結(jié)
這篇文章主要介紹了Vue 數(shù)據(jù)響應(yīng)式的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)vue框架的使用,感興趣的朋友可以了解下2021-01-01