「这是我参与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
- 项目地址:github.com/ClyingDeng/…