• 售前

  • 售后

热门帖子
入门百科

Vue封装通用table组件的完备步调纪录

[复制链接]
墙和鸡蛋 显示全部楼层 发表于 2021-8-14 13:53:17 |阅读模式 打印 上一主题 下一主题
目录


  • 前言
  • 为什么须要封装table组件?
  • 第一步:界说通用组件
  • 第二步:父组件与子组件进行render通讯
  • 第三步:利用组件
  • 总结

前言


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

为什么须要封装table组件?


后台管理体系表格利用频率高,淘汰关于table的业务代码,且便于后期统一修改、便于后期维护。如给table内容展示,超出单位格以省略号展示等。
对于大部分的后台管理体系,数据表格的展示大同小异,由于不想写重复的代码,以是我选择封装通用table组件,解放双手。如果你的表格有一列并不是简朴dom元素,好比switch按钮,完全可以传入一个render函数,来达到目的。

第一步:界说通用组件

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


为了实现父组件render函数在子组件中见效,我们须要界说一个render函数,在子组件中引用。
  1. // table.js
  2. export default {
  3.   props: {
  4.     render: {
  5.       type: Function
  6.     },
  7.     param: {
  8.       type: Object
  9.     }
  10.   },
  11.   render(h) {
  12.     return this.render(h, this.param)
  13.   }
  14. }
复制代码
第三步:利用组件

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


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

到此这篇关于Vue封装通用table组件的文章就先容到这了,更多相干Vue封装通用table组件内容请搜刮脚本之家从前的文章或继承浏览下面的相干文章盼望各人以后多多支持脚本之家!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x

帖子地址: 

回复

使用道具 举报

分享
推广
火星云矿 | 预约S19Pro,享500抵1000!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

草根技术分享(草根吧)是全球知名中文IT技术交流平台,创建于2021年,包含原创博客、精品问答、职业培训、技术社区、资源下载等产品服务,提供原创、优质、完整内容的专业IT技术开发社区。
  • 官方手机版

  • 微信公众号

  • 商务合作