「这是我参与11月更文挑战的第1天,活动详情查看:2021最后一次更文挑战」
hello 大家好,🙎🏻♀️🙋🏻♀️🙆🏻♀️
我是一个热爱知识传递,正在学习写作的作者,ClyingDeng
凳凳!
作为参与了6、8月更文活动的老用户,这期又怎么少得了我呢!嘿嘿!
本文主要针对table表格item多次渲染进行了一个二次封装,节省代码量。将table表头和表体数据独立出来,通过js数据去控制其表头展示文字。
业务需求
我相信在很多业务场景中,尤其是做管理台这种的,有这样的一个需求。每个页面有个一两个表格,但是表格样式可能不同,比如一个页面要这样的:
另一个页面要这样的:
又或者是带操作按钮的表格:
emmm,如果项目小可以不用考虑优化,大不了多写几个表格。一旦遇到大型的项目,再这样一个表格一个sfc是不是不妥呢?如果有个10个表格,那么每个表格内部牵扯到的逻辑操作顺带着查询、对话框每个文件的代码行数都是一个不小的数字,并且内部重复量是非常大的一个数值!
那么,问题来了,如何以尽量少的代码去完成呢?
解决方案
目前,以element-plus为基础组件。只考虑单表格样式、数据、行内操作等情况(查询、分页可以在此基础再进行封装)。将其table组件单独做成一个插件。
实例展示
安装
通过npm命令安装dyingtable。
npm install dyingtable --save
快速上手
在vue项目中的入口文件main.ts中:
import { createApp } from 'vue'
import App from './App.vue'
import DyTable from 'dyingtable'
createApp(App).use(DyTable).mount('#app')
注意:dyingtable
插件是面向Vue3版本哦!vue2版本的封装是混合在其他项目中,有兴趣也可以点击这里去看看哟!
demo实现
由于对于表格应用场景有很多demo,可自行前往dyingtable,在此,我们就展示基础表格、选择行表格和多级表头三个demo。
基础表格
先看看element表格
自己根据所需表格列,去渲染。换个数据不同的表格,再次需要自己去拷贝一份table表格修改。
对于 dyingtable
来说,可以根据传入你所需要的表头和所需对应列的数据即可。
tHeads中的props
值需要与tableData中所对应。
表格头部label
绑定表头名称,props
作为唯一标识,width
表格列宽度,align
控制列左中右对齐。
<dy-table :tHeads="tHeads" :tableData="tableData"></dy-table>
<script lang="ts">
import Vue, { defineComponent, reactive } from 'vue'
export default defineComponent({
setup() {
let tHeads = reactive([
{
label: '日期',
props: 'date',
width: '200',
align: 'center',
},
...
])
let tableData = reactive([
{
date: '2016-05-02',
name: '王小虎',
age: 22,
address: '上海市普陀区金沙江路 1518 弄',
},
...,
])
return { tableData, tHeads }
},
})
</script>
效果
选择行表格
选择多行数据时使用 Checkbox。 给表格添加ref属性,通过refs给组件内table传入ref属性。给表头添加 { type: 'selection' }
属性,展示Checkbox。
<dy-table ref="multiple" :refs="refs" :tHeads="tHeads" :tableData="tableData"></dy-table>
<div style="margin-top: 20px">
<el-button @click="toggleSelection([tableData[1], tableData[2]])">
切换第二、第三行的选中状态
</el-button>
<el-button @click="toggleSelection()">取消选择</el-button>
</div>
<script lang="ts">
import { defineComponent, reactive, ref } from 'vue'
export default defineComponent({
setup() {
let tHeads = reactive([
{ type: 'selection' },
{
label: '日期',
props: 'date',
width: '200',
sortable: false,
align: 'center',
className: 'stripa', // 列样式
},
])
let tableData = reactive([
{
date: '2016-05-02',
name: '王小虎',
age: 22,
address: '上海市普陀区金沙江路 1518 弄',
},
{
date: '2016-04-04',
name: '王小虎',
age: 12,
address: '上海市普陀区金沙江路 1517 弄',
},
...
])
let multiple: any = ref(null)
let refs = ref('multipleTable')
let toggleSelection = (rows: any) => {
let ref = multiple.value.$refs
if (rows) {
rows.forEach((row: any) => {
ref.multipleTable.toggleRowSelection(row)
})
} else {
ref.multipleTable.clearSelection()
}
}
return { tableData, tHeads, multiple, refs, toggleSelection }
},
})
</script>
效果
多级表头
数据结构比较复杂的时候,可使用多级表头来展现数据的层次关系。使用tHeads
的children属性来渲染子表头。一定要注意的是:需要展示列数据的,一定要绑定props
。
<dy-table :tableData="tableData" :tHeads="tHeads"></dy-table>
<script lang="ts">
import { defineComponent, reactive } from 'vue'
export default defineComponent({
setup() {
let tHeads = reactive([
{
label: '日期',
props: 'date',
width: '200',
sortable: false,
align: 'center',
},
{
label: '配送信息',
children: [
{
label: '姓名',
props: 'name',
width: '200',
sortable: false,
align: 'center',
},
{
label: '地址',
sortable: false,
align: 'left',
children: [
{
label: '省份',
props: 'province',
width: '150',
}
...
],
},
],
},
])
let tableData = reactive([
{
date: '2016-05-03',
name: '王小虎',
province: '上海',
city: '普陀区',
address: '上海市普陀区金沙江路 1518 弄',
zip: 200333,
},
])
return { tableData, tHeads }
},
})
</script>
效果
rollup 踩坑
在此呢,我也是比较爱折腾。
原本用element-ui、vue2实现了table的封装。
又想着现在的vue3,那就再用vue3和element-plus再试试。
写完了把,又想把这个组件单独拎出来,搞个插件玩玩。好吧,用vue-cli搞的插件跑通了。
又想着要不用rollup试试,这下好了,试着试着,踩到了个大泥潭里面了。。。
看着官网文档,emmm,就像个天书一样🪁🪁🪁
这个学法呢,我是借鉴我之前使用rollup打包的项目配置,先将最基础能够编译ts文件的所需配置先搭建好。
因为我是使用的vue3、element-plus去封装自己的组件。所以必须要安装能够解析vue文件和element-plus的插件并配置的。
安装下段代码中所需依赖:
import Components from 'unplugin-vue-components/rollup'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
import vue from 'rollup-plugin-vue'
export default {
plugins: [
vue({
compileTemplate: true,
}),
Components({
resolvers: [ElementPlusResolver()],
})
]
}
你以为安装好,就可以正常跑通了吗,那你可就太天真了🎃
321,来!上BUG
:
请问,这是什么问题?
这是典型的rollup打包问题: Error: "[name] is not exported by [module]"
一旦遇到什么东西导出错误,一定要检查自己安装的commonjs插件是否支持自己所有依赖的npm模块导出格式。
那这个你知道吗?
遇到这个问题当时我百度不得其解,看到唯一一个有点相关的问题,竟然是这个。好家伙,人家直接用vite解决了。。。🙃🙂🙃
想知道我是怎么解决的吗?
🎊铛铛铛,答案揭晓:
当时安装 rollup-plugin-vue
时,直接使用的是 npm i rollup-plugin-vue
。。。然后我将其依赖卸载,重新安装,安装时给它加了个 -D
。然后,它就好了。我也很无语😶
npm 发版踩坑
npm 发版遇到的问题主要是TLS升级问题。
从 2021 年 10 月 4 日开始,所有与 npm 网站和 npm 注册表的连接(包括软件包安装)都必须使用 TLS 1.2 或更高版本。点击即可查看并升级TLS版本。
除了更新TLS版本之外还要将npm更新到7版本以上版本。
再看看自己的npm版本:
通常npm版本更新频率是高于node版本更新的。emmm,那就下一个最新版的npm把:
npm install npm@latest -g
此外还需将npm注册表设置为https端点如下图:
至于登录npm账号进行npm发版没有遇到太大问题,在此不再过多赘述。
关于 dyingtable 插件
-
dyingtable 项目地址:github.com/ClyingDeng/…
-
根据 vue2 + element-ui,对表格进行的二次封装详情可见:formdemo