在VUE3.x项目中二次封装ElementUI Plus El-Table组件
(先回忆初恋放松下)
1.应用场景
相信同志们在写后台管理的项目时,表格组件是使用最多的一个组件了。尽管饿了么中的ElTable已经非常的完善了,但抵不住数量的庞大,正常的流程可能就是cv官方的代码然后再修改一下,那有没有一劳永逸的方法呢?当然,哥几个把表格二次封装一下就能很好的解决这个问题了。
下面是修沟在工作中常用的两种封装方式。
2.二次封装
2.1 low点的封装
为什么说叫low点的封装呢,因为与第二方式的比较,观众老爷们心里会有答案的。
话不多说先上代码
<script setup>
const props = defineProps({
tableData: {
type: Array,
default: () => [],
},
colItems: {
type: Array,
default: () => [],
},
});
</script>
<template>
<el-table
ref="refTable"
:data="tableData"
style="width: 100%; height: 100%"
@row-dblclick="
(row, col, event) =>; {
emit('handleRowDblclick', row, col, event);
}
"
>;
<el-table-column v-if="showCheckBox" type="selection" width="50">;</el-table-column>;
<el-table-column v-if="showIndex" type="index" label="序号" width="80">;</el-table-column>;
<el-table-column
v-for="item in colItems"
:key="item.prop"
:prop="item.prop"
:label="item.label"
:width="item.width"
:align="item.align"
>;</el-table-column>;
</el-table>;
</template>
上述的封装方式应该是大家在工作中比较常见的一种方式,使用起来也非常的简单。
2.2 别样的封装
相较于上一种的封装方式,这种方式区别还是挺大的,也是笔者在工作常用的封装方式。
先上代码
import {
getCurrentInstance,
h,
toRefs,
useAttrs,
ref,
defineComponent,
} from "vue";
import { ElTable, ElTableColumn } from "element-plus";
import "element-plus/dist/index.css";
export default defineComponent({
props: {
columns: {
type: Array,
default: () => [],
},
},
setup(props) {
const attrs = useAttrs();
const { columns } = toRefs(props);
const getTableColumn = (column) => {
const { children, render, ...data } = column;
const slots = {};
if (render) {
slots.default = render;
}
if (children) {
slots.default = () =>
children.map((childColumn) => {
return getTableColumn(childColumn);
});
}
return h(
ElTableColumn,
{
...data,
},
slots.default
);
};
const tableColumns = () =>
columns.value.map((column) => {
return getTableColumn(column);
});
const instance = getCurrentInstance();
instance.render = () => {
return h(
ElTable,
{
ref: "refElTable",
...attrs,
},
tableColumns
);
};
const refElTable = ref();
return {
refElTable,
};
},
});
看完上述代码,可能各位观众老爷会有疑问?整个代码块中没有一个HTML,那到底是怎么渲染成一个组件的呢?在这里就不得不提一下VUE中的 [h函数](https://cn.vuejs.org/api/render-function.html#h) 了。
创建虚拟 DOM 节点 (vnode)。VUE官方文档中对h函数的解释就这么一句话,非常简单,详情的用法可以去官网上查看,在此就不做陈述了。上述代码的逻辑其实也非常简单,通过h函数渲染出一个vnode,然后再setup钩子函数中调用render方法去渲染vnode。
使用示例代码如下:
<script setup>
import { ref } from "vue";
import CustomTable from "./components/CustomTable/CustomTable.vue";
const data = ref([
{
name: "xxx",
gender: "men",
},
]);
const columns = [
{
prop: "name",
label: "姓名",
},
{
prop: "gender",
label: "性别",
},
];
const handleCustomTableSelect = () => {}
const refCustomTable = ref(null)
// 调用el-table的方法
refCustomTable.value.refElTable.clearSelection()
</script>
<template>
<div class="main">
<CustomTable ref="refCustomTable" :data="data" :columns="columns" @select="handleCustomTableSelect" />
</div>
</template>
属性和方法的使用方式和ElTable组件一样,有点出入的就是调用ElTable的方法。
其中h函数其实非常强大,我们可以围绕去实现更多、更简洁的功能
3.二者的区别
初恋回忆录,放松一下观众老爷们
放松完了咱们继续,其实第一种封装已经能够满足大多数场景了,那为什么还要去深究第二种呢。主要的原因是第一种封装不太能满足功能时,第二种方式能够更多样化的去完成表格。因为当slot用的多时候,我们就要在第一种封装中疯狂的if else,一个两个还好,相信大家都不愿意写太多的if else。在第二种方式中,我们能够利用h函数的特性去手动控制表格单元格中渲染的内容。
那么这期的实用小技巧就到此结束了,希望观众老爷们在工作时放松下来,敲出诗一样的代码。