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

对于一个中后台类的项目,一个比较常见的展示形式就是Table了,这篇文章主要给大家介绍了关于Vue封装通用table组件的相关资料,需要的朋友可以参考下

Vue封装通用table组件的完整步骤记录,久久派带你了解更多相关信息。

目录
  • 前言
  • 为什么需要封装table组件?
  • 第一步:定义通用组件
  • 第二步:父组件与子组件进行render通信
  • 第三步:使用组件
  • 总结

前言

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

为什么需要封装table组件?

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

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

第一步:定义通用组件

<!-- pro-table.vue --><template>  <p>    <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>  </p></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>  <p>    <!--        @自定义事件=\"父组件方法\", 子组件中,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\"/>  </p></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组件内容请搜索趣讯吧以前的文章或继续浏览下面的相关文章希望大家以后多多支持趣讯吧!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,请发送邮件至 55@qq.com 举报,一经查实,本站将立刻删除。转转请注明出处:https://www.szhjjp.com/n/8957.html

(0)
上一篇 2021-07-31 21:51:30
下一篇 2021-07-31 21:51:32

相关推荐

  • 赵薇手下的13个艺人?赵薇旗下艺人最新名单

    赵薇是很早就转型当老板的那波人,之后更是当导演、干投资,风生水起,那么赵薇的娱乐公司叫什么名字呢?赵薇手下的13个艺人分别是谁?赵薇旗下艺人最新名单在哪看?下面就跟趣讯吧小编来详细了解一下吧!

    2021-08-14
    0
  • 支付宝上的理财产品可靠吗(看完以下介绍就知道)

    提起支付宝,相信大家都知道,它除了可以消费、转账、贷款、还信用卡之外,还可以利用支付宝理财产品进行赚钱。但大家在使用支付宝理财的时候

    2021-07-31
    0
  • 老师乘凉却让5名幼儿暴晒罚站? 教体局:做法有问题,已道歉 !

    5月19日,市民称蚌埠一幼儿园内5名小朋友在太阳下罚站,老师一旁乘凉。园方回应其他媒体称老师在让孩子拍球。教体局称因孩子做操不规范让他们重做,已对教师通报批评。体罚学生本身就不是一件值得提倡的事,国家也明令禁止老师以任何方式来体罚学生,学生不听话可以考虑其他的方式,但是这种粗暴的行为不应该出现在课堂

    2023-05-20
    0
  • 2021年6月制造业ISM商业报告

    经济在活动制造业增长在六月,随着整体经济开槽增长连续第13个月,说在最新的全美供应管理人员制造业ISM®报告关于企业®。该报告由供应管理协会®(ISM®)制造企业调查委员会、CPSM、CPMTimothyR.Fiore今天发布:“

    2022-01-07
    0
  • 纪梵希的口红怎么样(纪梵希少女时光系列)

    这只口红是唇妆堆里的正宫娘娘,。万年回购,使用率也极高送上自己的全脸效果,以及嘴唇局部试色。iPhonex后置摄像头拍摄的,无滤镜,有磨皮。据说这只口红的外文翻译叫“小仙女”。颜色:第一次去专柜试的时候看膏体以为是只正红色的口红,拿起来

    2021-12-15
    0
  • 5g手机为什么显示4g信号(换了5G手机依然用4G网络)

    摘要:如果你的手机不是几年没换,大概率现在都是用的5G手机吧,这两年,所有手机厂商都用上了5G技术,但是不知道大家发现没有,就是很多人虽然换了5G手机,但是套餐却依然用的4G,上网一直用4G网络。

    2023-03-31
    0

发表回复

登录后才能评论