Vue3+ts+element-plus 组件的二次封装-- el-table的封装,通过json进行配置表单,可用插槽进行拓展

Vue 笔记

本人是一个web前端开发工程师,主要是vue框架,整理了一些Vue常用的技术,一方面是分享,一方面是做总结,今后也会一直更新,有好建议的同学欢迎评论区分享 ;-)

序号文章
0组件库展示
1通过JSON配置–头部搜索条件的封装组件
2通过JSON配置–表单Table的封装组件
3页脚的封装组件
4通过JSON配置–Form表单的封装组件
5生成npm组件库
6发布到npm
7vitest为组件库添加单元测试
8vuepress为组件库生成文档
9通过github或者gitee pages将组件库文档发布到线上,免费!
10源码地址

在这里插入图片描述


组件库开发流程

Vue组件库专栏会按顺序执行一下流程,不断完善组件库开发流程

  1. Vue3+element-plus+vite 组件的二次封装,封装了头部的搜索条件栏,tabel栏,分页栏,form表单,都设置成了通过json可配置项,方便复用;
  2. 封装好了就开始打包,并且进行本地测试;
  3. 组件库发布到npm;
  4. 添加vitest单元测试框架;
  5. 添加vuepress文档。


前言

环境状态
vue版本:vue3
是否使用 ts:是

后台管理系统的网站,一个页面无非就是4个常用业务块

  1. 头部的搜索栏
  2. table表格
  3. 页脚
  4. 新增编辑弹框

那咋们是不是可以将其进行封装成组件呢?
只需要传入一个配置文件就可以了~

项目解构如下:
在这里插入图片描述

封装后的展示图如下:
在这里插入图片描述

效果图如下:

在这里插入图片描述

如果能做成这样,是不是页面就会整洁很多?


el-table表格的二次封装

原理:

  1. 通过tableData 传递进表格里面的数据,后台返回的数据
  2. 通过columnConfig 传递进去表格需要展示的效果,是个对象数组,每个对象都是一个列,里面有列名以及对应的tableData.props 属性,比如 typeName
  3. 通过hasOpr 传递看看需不需要操作列,因为有些角色是不是操作权限的,做兼容处理了
  4. 添加作用域插槽,让父组件可以获取子组件的数据,比如row.id,然后就可以在父组件中执行删除操作。

1. 效果图

在这里插入图片描述


2. 父组件

2.1 父组件 template 中的调用

<!-- 表格 -->
<PenkTable :table-data="tableData" :column-config="columnConfig" hasOpr>
  <template #default="{ scope }">
    <el-button
      type="danger"
      :icon="Delete"
      @click="handleForceDeleteItem(scope.$index, scope.row)"
    >
    </el-button>
  </template>
</PenkTable>

可以看到:
如果,只是简单的表格查看的话,只需要传递tableData数据,以及columnConfig配置项;
如果,需要有操作栏,就可以添加hasOpr 属性,并且使用作用域插槽。


2.2. 父组件 script 中的调用

2.2.1 将数据更新到组件上

由于双向绑定,直接修改tableData即可

// 表格数据
let tableData = reactive([]);
// 查找数据
async function getList() {
  // 清空数据
  tableData.length = 0;
  console.log("tableData1:", tableData);

  // 判断是否有对象,没有的话就自动弄
  let res = await http.getList({
  	//...
  });
  // @ts-ignore
  tableData.push(...res.rows);
  paginationData.total = res.count;

  console.log("tableData:", tableData);
}

tips:这边要注意reactive 创建的tabelData,不能使用直接赋值,因为是个proxy对象~


2.2.2 配置项

这边有的配置是可填可不填的,具体的配置项可以看封装组件里面的参数,这边大概看一下

  • props:每一列对应对象的属性名,方便通过索引的方式获得键值
  • render:渲染函数,比如后端给你返回了0 代表 禁止, 1 代表启用
  • label:在UI组件前面的label
  • width:列的宽度,无设置就是自适应
  • hidden:是否隐藏,有些业务需求是根据不同角色,一些是不展示的
 const columnConfig = [
  {
    label: "父级类型名",
    prop: "parentTypeFk.typeName",
    render: (value) => {
      if (value) return "父-"+value;
    },
  },
  {
    label: "类型名",
    prop: "typeName",
  },
  {
    label: "创建时间",
    prop: "createdAt",
  },
  {
    label: "更新时间",
    prop: "updatedAt",
  },
  {
    label: "删除时间",
    prop: "deletedAt",
  },
];

3. 组件的封装

3.1 封装组件template

代码太长了,将显示部分代码…

3.1.1 el-table的配置

这边统一的样式以及配置,就只用了父组件props上的tableData,用于将表格数据传递给elementUI组件 el-table

<el-table
  :data="props.tableData"
  table-layout="fixed"
  border
  highlight-current-row
  size="large"
  empty-text="-"
  stripe
>
  <!-- el-table 没数据插槽 -->
  <template #empty>
    <h1>没数据</h1>
  </template>

  <!-- 选择框,通过props.isSelection 来判断是否需要展示 -->
  <el-table-column v-if="props.isSelection" type="selection" width="55" />
  <!-- 索引,默认展示索引 -->
  <el-table-column type="index" width="50" />
...
...
...

3.1.2 el-table-column 的配置
  1. props.columnConfig:数组,用于每一列的配置。
  2. 通过作用域插槽,可以获取每一条数据row,通过配置中columnConfig.prop 实现字符串索引,可以得到每一项的值。
  3. 配合columnConfig中的render函数,可以渲染出自己想要的数据,比如 0 => 禁用,1=> 启用…
<template v-for="item in props.columnConfig" :key="item.label">
  <el-table-column
    v-if="item.hidden != true"
    :fixed="item.fixed"
    :prop="item.prop"
    :label="item.label"
    :width="item.width || 'auto'"
  >
    <template #default="{ row, column, $index }">
      <span style="white-space: nowrap" v-if="item.render">{{
        item.render(row[item.prop]) || item.emptyStr || "--"
      }}</span>
      <span style="white-space: nowrap" v-else>{{
        row[item.prop] || item.emptyStr || "--"
      }}</span>
    </template>
  </el-table-column>
</template>

3.2 封装组件script

由于使用了TS来编码,咋们可以在组件中interface中写清楚一些配置,方便使用者知道有什么配置 :)

这边用的是typescript写的,不懂得同学可能要先学习一下,或者去我的ts专栏看看~

3.2.1 props属性
interface props {
  // 表格数据
  tableData: {
    [index: number]: dataItemObj;
  };
  // 列数据
  columnConfig: columnItemObj[];
  // 判断表格有无列操作
  hasOpr?: boolean;
  // 判断是否有checkbox
  isSelection?: boolean;
}
3.2.2 tableData后台返回数据
// tableData的item对象,是一个不确定的对象
interface dataItemObj {
  [index: string]: any;
}
3.2.3 columnConfig配置文件
// 渲染函数,比如后端给你返回了0 代表 禁止, 1 代表启用
// 这个时候就需要渲染函数了...
interface render {
  (v: any): string;
}
// 每一列的配置对象
interface columnItemObj {
  // 判断是否隐藏,一些业务需求,比如不同的权限可能就不展示了
  hidden?:boolean
  // 列无数据占位符
  emptyStr?: string;
  // el-table fixed 属性 左右固定布局
  fixed?: string;
  // el-table width 属性 宽度
  width?: number;
  // el-table prop 属性 字段名
  prop: string;
  // el-table label 属性 列名
  label: string;
  // 自定义渲染
  render?: render;
}

总结

这边只是将只是用作展示数据,并没有什么数据交互,所以封装的组件并没有什么事件,唯一需要获取的数据可能就是通过作用域插槽了~


组件源码

<!--
 * @Author: Penk
 * @LastEditors: Penk
 * @LastEditTime: 2022-11-29 18:23:25
 * @FilePath: \front-master\src\components\public\PenkTable.vue
 * @email: 492934056@qq.com
-->
<template>
<el-table
  :data="props.tableData"
  table-layout="fixed"
  border
  highlight-current-row
  size="large"
  empty-text="-"
  stripe
>
	<!-- el-table 没数据插槽 -->
  <template #empty>
    <h1>没数据</h1>
  </template>

  <!-- 选择框,通过props.isSelection 来判断是否需要展示 -->
  <el-table-column v-if="props.isSelection" type="selection" width="55" />
  <!-- 索引,默认展示索引 -->
  <el-table-column type="index" width="50" />

    <template v-for="item in props.columnConfig" :key="item.label">
      <el-table-column
        v-if="item.hidden != true"
        :fixed="item.fixed"
        :prop="item.prop"
        :label="item.label"
        :width="item.width || 'auto'"
      >
        <template #default="{ row, column, $index }">
          <span style="white-space: nowrap" v-if="item.render">{{
            item.render(row[item.prop]) || item.emptyStr || "--"
          }}</span>
          <span style="white-space: nowrap" v-else>{{
            row[item.prop] || item.emptyStr || "--"
          }}</span>
        </template>
      </el-table-column>
    </template>

    <!-- 操作列 -->
    <el-table-column v-if="hasOpr" fixed="right" label="操作" width="200">
      <!-- 这边是插槽组件,外部无法访问到里面的数据,比如每一列的item -->
      <!-- 使用作用域插槽,将数据从element组件拿下来,
        再通过 自定义插槽属性scope 传递到父组件,
        使父组件可以调用子组件的数据 -->
      <template #default="{ row, column, $index }">
        <slot :scope="{ row, column, $index }"></slot>
      </template>
    </el-table-column>
  </el-table>
</template>

<script setup lang="ts">
// 渲染函数,比如后端给你返回了0 代表 禁止, 1 代表启用
// 这个时候就需要渲染函数了...
interface render {
  (v: any): string;
}

// columnConfig 是一个columnItemObj对象的数组
interface columnConfig {
  [index: string]: columnItemObj;
}

// 每一列的配置对象
interface columnItemObj {
  // 必填
  // el-table prop 属性 字段名
  prop: string;
  // el-table label 属性 列名
  label: string;

  // 选填
  // 判断是否隐藏,一些业务需求,比如不同的权限可能就不展示了
  hidden?: boolean;
  // 列无数据占位符
  emptyStr?: string;
  // el-table fixed 属性 左右固定布局  只能在头尾的配置中存在
  fixed?: string;
  // el-table width 属性 宽度
  width?: number;
  // 自定义渲染
  render?: render;
}

// tableData的item对象,是一个不确定的对象
interface dataItemObj {
  [index: string]: any;
}

interface props {
  // 表格数据
  tableData: {
    [index: number]: dataItemObj;
  };
  // 列数据
  columnConfig: columnConfig;
  // 判断表格有无列操作
  hasOpr?: boolean;
  // 判断是否有checkbox
  isSelection?: boolean;
}

let props = defineProps<props>();
console.log("props:", props.columnConfig);
</script>

<style lang="less" scoped>
.el-table-border {
  border: 1px #eee solid;
}
// :deep(.el-scrollbar__view) {
//   width: 100%;
// }
</style>
  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: Vue3中封装el-table可以通过以下步骤进行: 1. 首先,我们需要创建一个自定义组件,可以命名为MyTable。 2. 在MyTable组件中,我们需要导入el-tableel-table-column组件,可以使用import语句进行导入。 3. 在template标签中,我们可以使用el-table来渲染表格。可以设置属性如:data、border、stripe等。 4. 在el-table标签内部,我们可以使用el-table-column来定义表格的列。可以设置属性如:prop(对应数据源)、label(列名)、width(列宽)等。 5. 在script标签中,我们需要定义MyTable组件的props,用于接收父组件传递的数据。 6. 在script标签中,我们可以定义一些方法或者计算属性,用于处理表格的点击事件、排序、筛选等。 7. 最后,我们需要在父组件中使用MyTable组件,并传递数据和配置选项给MyTable组件的props,来渲染自定义的表格。 总结一下,Vue3中封装el-table的关键步骤包括创建自定义组件、导入el-tableel-table-column组件、在MyTable组件中使用el-tableel-table-column来渲染表格、定义props、定义方法和计算属性以及在父组件中使用MyTable组件。通过封装el-table,我们可以更好地复用和管理表格组件,并实现更灵活的表格功能。 ### 回答2: Vue3是一个用于构建用户界面的渐进式JavaScript框架。它具有轻量级、高效、易用的特点,并且在Vue3中可以灵活地封装el-table。 首先,为了封装el-table,我们可以创建一个自定义组件,命名为TableWrapper。在TableWrapper组件的模板中使用el-table,并将el-table的相关属性、事件和插槽通过props进行传递和接收。 在TableWrapper组件的props中,我们可以定义例如data、columns、pagination等与el-table相关的属性。这样,我们就可以通过在使用TableWrapper组件时传递这些属性来配置el-table的行为。 另外,我们还可以在TableWrapper组件中定义一些需要自定义的功能,例如表格的样式、表头的固定、排序功能等。这些功能可以通过在TableWrapper组件中添加相关的方法和事件来实现。 除了属性和方法外,我们还可以使用插槽TableWrapper组件中自定义表格的各个部分,例如表头、表尾、表格内容等。通过在TableWrapper组件的模板中使用<slot>元素,并在使用TableWrapper组件时传递相应的内容,可以方便地自定义el-table的外观和布局。 总之,通过将el-table封装到自定义组件TableWrapper中,我们可以更好地控制和定制el-table的行为和外观。这样,我们就能够根据实际需要快速构建出符合需求的数据表格。 ### 回答3: Vue3中封装el-table的步骤如下: 1. 首先,创建一个名为el-table-wrapper的组件,该组件用于封装el-table。 2. 在el-table-wrapper组件中,引入el-table组件,并在模板中使用el-table进行数据展示。 3. 在el-table-wrapper组件中,接收名为data的props属性,用于传递表格数据。 4. 在el-table-wrapper组件中,通过v-for指令遍历data数据,并使用el-table-column组件进行表格列的定义。 5. 在el-table-wrapper组件中,使用slot插槽来支持自定义表格内容,例如添加操作按钮等。 6. 在el-table-wrapper组件中,可以设置一些其他属性,如border、stripe等,以适应不同的需求。 7. 在el-table-wrapper组件中,可以使用事件监听器来捕获el-table的一些事件,例如选择行、排序等。 8. 在el-table-wrapper组件中,通过emit方法触发自定义事件,以便在父组件中处理表格的交互逻辑。 总结:在Vue3中封装el-table,需要通过创建一个包装组件,在其中引入el-table组件并定义相应的列和属性,同时支持自定义内容和事件。这样可以提高代码的复用性和可维护性,方便在不同的项目中使用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Penk是个码农

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值