您当前的位置:首页 > 网站建设 > javascript
| php | asp | css | H5 | javascript | Mysql | Dreamweaver | Delphi | 网站维护 | 帝国cms | React | 考试系统 | ajax |

Vue封装通用table组件的完整步骤记录

51自学网 2022-05-02 21:35:26
  javascript

前言

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

为什么需要封装table组件?

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

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

第一步:定义通用组件

<!-- 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函数,在子组件中引用。

// table.jsexport default {  props: {    render: {      type: Function    },    param: {      type: Object    }  },  render(h) {    return this.render(h, this.param)  }}

第三步:使用组件

<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组件内容请搜索wanshiok.com以前的文章或继续浏览下面的相关文章希望大家以后多多支持wanshiok.com!


H5微信公众号授权的简单实现步骤
jQuery实现表格行数据滚动效果
51自学网,即我要自学网,自学EXCEL、自学PS、自学CAD、自学C语言、自学css3实例,是一个通过网络自主学习工作技能的自学平台,网友喜欢的软件自学网站。
京ICP备13026421号-1