vue + element-ui二次封装Table组件,实现表格内容的完全自定义

前言

我们在用vue + element-ui写后台管理系统项目时,table组件应该是用的频率非常高的组件之一,但是我们不希望每次都使用element-ui的表格代码,秉着代码可读性和可复用性的原则,我们需要对element的table组件进行二次封装。

1、新建table.vue页面

<template>
  <Table :data="tableData" style="width:100%">
    <template v-for="column in columns">
      <TableColumn :key="column.prop" :prop="column.prop" :label="column.title" v-if="!column.action"/>
      // 操作列
      <TableColumn :label="column.title" v-else>
        <template slot-scope="scope">
          <template v-for="(fn,index) in column.actions">
            <Divider direction="vertical" v-if="index>0"/>
            <Button type="text" @click="handleClick(scope.row,fn.fnName)">{{fn.title}}</Button>
          </template>
        </template>
      </TableColumn>
    </template>
  </Table>
</template>
<script>
  import {Table, TableColumn,Divider,Button} from 'element-ui'

  export default {
    name: "tableC",
    components: {Table, TableColumn,Divider,Button},
    props: {
      columns: {
        required: true, type: Array, default: () => {
          return []
        }
      },
      tableData: {
        required: true,
        type: Array,
        default: () => {
          return []
        }
      }
    },
    methods:{
      handleClick(row,fnName){
        this.$emit(`${fnName}`,row)
      }
    }
  };
</script>

这里我使用了按需引入的方式,以下为官网的按需引入的方式
在这里插入图片描述

2、在页面中使用

<template>
    <TableC :columns="columns" :tableData="tableData" @add="add" @edit="edit"></TableC>
</template>

<script>
  import TableC from "./table";

  export default {
    name: "list",
    components: {TableC},
    data() {
      return {
        columns: [
          {prop: 'id', title: 'id'},
          {prop: 'name', title: '姓名'},
          {action: true, title: '操作', actions: [{fnName: 'add', title: '新增'}, {fnName: 'edit', title: '编辑'}]}
        ],
        tableData: [
          {id:'1267823566512bdh',name: 'chenkai'},
          {id:'qweq12312312',name: 'eqwe'},
        ]
      };
    },
    methods: {
      add(e) {
        console.log('新增:' + e.name);
      },
      edit(e) {
        console.log('编辑:' + e.name);
      }
    }
  };
</script>

可以看到,操作列的数据,我定义了是否为action的标识,操作的按钮数据通过actions的数组传入,其中fnName为方法名,title为按钮文字,子组件中通过$emit提交对应的方法,父组件中监听对应的方法即可。

这样,我们就完成了对table组件基本的二次封装。

但是,实际的业务场景中,这个组件并不能满足我们的开发需求,例如:某个列需要以链接的形式展示或者需要展示例如Switch的组件,这种情况下,上面的组件就不能满足我们的需求。所以,我们还得继续对组件进行优化。

话不多说,直接上代码

<template>
  <Table :data="tableData" style="width:100%">
    <template v-for="column in columns">
      <TableColumn :key="column.prop" :prop="column.prop" :label="column.title" v-if="!column.action">
        <template slot-scope="scope">
          <slot v-if="column.slot" :name="column.prop" :row='scope.row'/>
          <span v-else>{{ scope.row[column.prop] }}</span>
        </template>
      </TableColumn>
      <TableColumn :label="column.title" v-else>
        <template slot-scope="scope">
          <template v-for="(fn,index) in column.actions">
            <Divider direction="vertical" v-if="index>0"/>
            <Button type="text" @click="handleClick(scope.row,fn.fnName)">{{fn.title}}</Button>
          </template>
        </template>
      </TableColumn>
    </template>
  </Table>
</template>

这里我用slot插槽的方式来接收内容

页面调用代码改动

<TableC :columns="columns" :tableData="tableData" @add="add" @edit="edit">
  <template slot='id' slot-scope="scope">
    <a href="#">{{scope.row.id}}</a>
  </template>
</TableC>

columns: [
   {prop: 'id', title: 'id', slot: true},
   {prop: 'name', title: '姓名'},
   {action: true, title: '操作', actions: [{fnName: 'add', title: '新增'}, {fnName: 'edit', title: '编辑'}]}
 ],

以下为实际展示效果
在这里插入图片描述
至此,我们的组件已经改造完成,这种方式能够满足我们绝大多数的业务场景,如有好的想法或者更好的改造方式,欢迎提出。

本文结束,感谢观看!!!

题外话

本人最近空闲时间做了一个关于房贷计算的微信小程序,有兴趣和需要的同学可以看看,感谢感谢!!!
在这里插入图片描述

Logo

快速构建 Web 应用程序

更多推荐