关于二次封装element-plus table的一些归纳总结(1)

前言

在许多中后台管理系统中,表格占据着半壁江山,如果使用element plus组件库,那么少不了要用到table组件,可是table组件的功能过于基础,因此,我在table组件的实现基础之上进一步封装,从而实现功能更强大的table组件。

在实现table组件的功能之前,我们首先需要先来看看用法,由于使用示例比较多,可能将会有几篇文章主要介绍所有示例用法,介绍完示例之后将会有专门的文章基于使用方式去详细讲解封装思路。

毕竟我们要实现一个东西,就应该需要先理解这个东西怎么用的,从如何使用再去推导如何实现就会很有思路了。

所以在实现之前,我们需要先来具体了解一下每个示例的用法和效果。

首先这个组件被我封装成以插件的形式来使用,我们可以看到在main.ts下的使用代码如下所示:

ts 复制代码
import { createApp } from 'vue'
import App from './App.vue'
//...
import ElementTable from './components/index'


const app = createApp(App);
//....
app.use(ElementTable);
app.mount('#app')

如此一来,我们就可以全局使用该组件了。

示例1-基础使用

组件支持传入column和data属性,即表格列数据和表体数据,前面我们已经说过了,我们是在全局当中注册好了,因此在vue文件当中可以直接使用。示例代码如下:

html 复制代码
 <element-table :column="column" :data="tableData" />

然后就是ts代码,如下所示:

ts 复制代码
import { ElTableColumnProps } from '../components/tableProps';
/* 引入ElTableColumnProps定义column可获得类型提示 */
const column: ElTableColumnProps[] = [
  {
    type: "index",
    width: "60px",
    label: "序号",
  },
  {
    prop: "name",
    label: "名字",
  },
  {
    prop: "date",
    label: "日期",
  },
  {
    prop: "address",
    label: "地址",
  },
];
// 后续如无特殊说明,表体数据都是这个
const tableData = [
  {
    date: "2016-05-02",
    name: "佘太君",
    address: "上海市普陀区金沙江路 1518 弄",
  },
  {
    date: "2016-05-04",
    name: "王小虎",
    address: "上海市普陀区金沙江路 1517 弄",
  },
  {
    date: "2016-05-01",
    name: "王小帅",
    address: "上海市普陀区金沙江路 1519 弄",
  },
  {
    date: "2016-05-03",
    name: "王小呆",
    address: "上海市普陀区金沙江路 1516 弄",
  },
];

从这个示例,我们可以看到,我们的column传入一个对象数组,对象的属性包含prop,label,type,width等属性,其中type值为index,代表制定一个索引列,然后label和prop分别指定列名以及对应绑定的表体数据字段名,width则指定列宽。

上述代码展示效果如下所示:

示例2--基础的render table

render渲染函数html部分和前面示例1保持一致,唯一不同的是ts代码,我们只需要绑定column和data属性数据即可,一个示例代码如下所示:

ts 复制代码
import { h } from 'vue';
// 这里是导入的类型
import { ElTableColumnProps } from '../components/tableProps';
const column: ElTableColumnProps[] = [
  {
    type: "index",
    width: "60px",
    label: "序号",
  },
  {
    label: "名字",
    prop: "name",
    render: (data, scope) => {
      const { row, column } = scope;
      const propKey = column.property;
      return h('div', null, { default: () => `render 结果 -- ${row[propKey]}== ${data}` })
    },
  },
  {
    prop: "date",
    label: "日期",
  },
  {
    prop: "address",
    label: "地址",
  },
];

上述代码展示效果如下所示:

从这个示例,我们可以看到,render是一个渲染函数,代表自定义渲染列。

这里尤其需要注意render函数的参数,第一个参数指的是数据,第二个参数则指的是当前表格上下文,我们可以从中获取一些属性,例如列数据column,行数据row等等,从而实现自定义渲染表体。

示例3--插槽用法

关于使用插槽,我们通常使用一个template标签,并制定#加属性值来表示,如示例:

html 复制代码
 <element-table :column="column" :data="tableData">
    <template #name="{ row }">
      <div>
        <span>
          <code>name</code>
          插槽--{{ row.name }}
        </span>
      </div>
    </template>
    <template #default>
      <div>
        <span>
          默认插槽名字为
          <strong>default</strong>
        </span>
      </div>
    </template>
  </element-table>

这里分成了两种插槽,第一种是具名插槽,通过#[属性名(这里的属性名通过column里的slotName属性指定)]指定,第二种则是默认插槽,通过#default(与前面具名插槽原理类似)指定,然后在配置的column列数据中,我们通过slotName来指定插槽名,代码如下所示:

ts 复制代码
const column = [
  {
    type: "index",
    width: "60px",
    label: "序号",
  },
  {
    label: "具名插槽",
    slotName: "name",
  },
  {
    label: "默认插槽",
    slotName: "default",
  },
  {
    prop: "date",
    label: "日期",
  },
  {
    prop: "address",
    label: "地址",
  },
];

上述代码展示效果如下所示:

示例4--边框

边框table,只是在组件当中传入一个border属性即可,其它跟前面示例没什么两样。代码如下所示:

html 复制代码
<element-table border :column="column" :data="tableData" />

ts代码忽略,以上代码展示效果如下图所示:

示例5--自定义列渲染

在前面的示例3当中,我们已经初窥自定义列渲染的实现了,接下来这个示例,我们将基于示例3,实现更为复杂的自定义渲染列示例。我们将会引入element-plus的icon(图标)组件和popover(悬浮对话框)组件。代码如下所示:

html 复制代码
  <element-table :column="column" :data="tableData" style="width: 100%">
    <template #date="scope">
      <div style="display: flex; align-items: center">
        <el-icon>
          <timer />
        </el-icon>
        <span style="margin-left: 10px">{{ scope.row.date }}</span>
      </div>
    </template>
    <template #name="scope">
      <el-popover effect="light" trigger="hover" placement="top" width="auto">
        <template #default>
          <div>name: {{ scope.row.name }}</div>
          <div>address: {{ scope.row.address }}</div>
        </template>
        <template #reference>
          <el-tag>{{ scope.row.name }}</el-tag>
        </template>
      </el-popover>
    </template>
    <template #default="scope">
      <el-button size="small" @click="handleEdit(scope.$index, scope.row)"
        >Edit</el-button
      >
      <el-button size="small" type="danger" @click="handleDelete(scope.$index, scope.row)"
        >Delete</el-button
      >
    </template>
  </element-table>

接下来,来看我们的ts代码,如下所示:

ts 复制代码
import { Timer } from "@element-plus/icons-vue";

interface User {
  date: string;
  name: string;
  address: string;
}

const handleEdit = (index: number, row: User) => {
  console.log(index, row);
};
const handleDelete = (index: number, row: User) => {
  console.log(index, row);
};

const column = [
  {
    type: "index",
    width: "60px",
    label: "序号",
  },
  {
    prop: "date",
    label: "日期",
    width: 180,
    slotName: "date",
  },
  {
    prop: "name",
    width: 180,
    label: "名字",
    slotName: "name",
  },
  {
    prop: "address",
    label: "Operations",
    slotName: "default",
  },
];

const tableData: User[] = [
  //...
];

这个示例其实也还是插槽的用法,只不过多了绑定按钮事件。上述代码展示效果如下所示:

示例6-自定义表头

自定义表头与自定义列渲染是同一个原理,也是插槽用法,只不过自定义列的插槽名属性叫做slotName,而自定义表头的插槽名则叫做headerSlot,然后就可以像自定义列那样自定义表头即可。如以下一个示例:

html 复制代码
 <element-table :column="column" :data="filterTableData" style="width: 100%">
    <template #header>
      <el-input v-model="search" size="small" placeholder="Type to search" />
    </template>
    <template #default="scope">
      <el-button size="small" @click="handleEdit(scope.$index, scope.row)"
        >Edit</el-button
      >
      <el-button size="small" type="danger" @click="handleDelete(scope.$index, scope.row)"
        >Delete</el-button
      >
    </template>
  </element-table>

然后我们的ts代码就可以基于搜索框,实现数据的过滤,利用ref函数创建一个响应书数据,也就是search。代码如下所示:

ts 复制代码
import { ref, computed } from "vue";

interface User {
  date: string;
  name: string;
  address: string;
}

const search = ref("");
//...注意这里
const filterTableData = computed(() =>
  tableData.filter(
    (data) =>
      !search.value || data.name.toLowerCase().includes(search.value.toLowerCase())
  )
);

const handleEdit = (index: number, row: User) => {
  console.log(index, row);
};
const handleDelete = (index: number, row: User) => {
  console.log(index, row);
};

const column = [
  {
    prop: "date",
    label: "日期",
    width: 180,
    slotName: "date",
  },
  {
    prop: "name",
    width: 180,
    label: "名字",
    slotName: "name",
  },
  {
    align: "right",
    slotName: "default",
    //这里就是自定义表头的自定义插槽名
    headerSlot: "header",
  },
];

const tableData: User[] = [
  //...
];

以上代码展示效果如下图所示:

输入搜索值之后,展示效果如下图所示:

示例7--自定义索引值

自定义索引值示例很简单,只需要配置列的index属性值为一个函数即可,代码如下:

ts 复制代码
const indexMethod = (index: number) => index * 2;
const column = [
  {
    type: "index",
    //主要是这里
    index: indexMethod,
  },
 //...
];
const tableData = [
    // ...
]

其余的没什么变化,html代码也很简单,如下所示:

html 复制代码
<element-table :column="column" :data="tableData" style="width: 100%"></element-table>

以上代码展示效果如下图所示:

以上示例展示了常规用法,预知后续示例,敬请关注下文。

相关推荐
程序员爱技术1 小时前
Vue 2 + JavaScript + vue-count-to 集成案例
前端·javascript·vue.js
并不会2 小时前
常见 CSS 选择器用法
前端·css·学习·html·前端开发·css选择器
衣乌安、2 小时前
【CSS】居中样式
前端·css·css3
兔老大的胡萝卜2 小时前
ppk谈JavaScript,悟透JavaScript,精通CSS高级Web,JavaScript DOM编程艺术,高性能JavaScript pdf
前端·javascript
低代码布道师2 小时前
CSS的三个重点
前端·css
耶啵奶膘3 小时前
uniapp-是否删除
linux·前端·uni-app
王哈哈^_^5 小时前
【数据集】【YOLO】【目标检测】交通事故识别数据集 8939 张,YOLO道路事故目标检测实战训练教程!
前端·人工智能·深度学习·yolo·目标检测·计算机视觉·pyqt
cs_dn_Jie5 小时前
钉钉 H5 微应用 手机端调试
前端·javascript·vue.js·vue·钉钉
开心工作室_kaic6 小时前
ssm068海鲜自助餐厅系统+vue(论文+源码)_kaic
前端·javascript·vue.js
有梦想的刺儿6 小时前
webWorker基本用法
前端·javascript·vue.js