1.使用原因
公司需要一个数据表格以查看各项数据, 其中蓝色的字体(可点击), 点击之后打开弹窗查看订单列表细节. 编写多个弹窗不现实, 并且有5个页面需要编写类似功能, 于是想到复用弹窗组件, 放弃了props数据流的方法(因为每个页面都需要状态控制).转而 使用更易懂更简洁的 hook的方式.
2.hook内容
弹窗内的表格展示需要什么呢? 首先是控制弹窗的字段, 使用的地方直接设置即可控制弹窗的展示. 其次是弹窗的顶部title ,在最后就是表格的展示需要的列数据和表格数据. 为了规范操作使用统一的方法更新数据
import { reactive } from "vue";
const dialogConfig = reactive({
title: "default_title",
showList: [],
columList: [],
isShow: false,
tableType: "",
});
export function useViewDialog() {
return {
dialogConfig,
update(newData = {}) {
let keys = Reflect.ownKeys(newData);
keys.map((item) => {
dialogConfig[item] = newData[item];
});
},
clear() {
dialogConfig.isShow = false;
dialogConfig.title = "";
dialogConfig.showList = [];
},
};
}
3.弹窗内容
这部分因为每个项目技术栈不同所以只展示关键部分代码
viewDialog.vue文件使用hook
//引入
import { useViewDialog } from "./useViewDialog.js";
const { dialogConfig, update, clear } = useViewDialog();
//监听表格数据
const tableData = computed(() => dialogConfig.showList ?? []);
const columData = computed(() => dialogConfig.columList ?? []);
//dialogConfig的数据可以直接使用 也可以使用computed
const title = computed(() => dialogConfig.title ?? '--');
const isShow = computed(() => dialogConfig.isShow ?? '--');
//关闭可直接调用hook内容清空数据
const closeModal = () => {
clear();
};
数据在组件模板中使用
//页面
<template>
<n-modal
preset="dialog"
:showIcon="false"
:mask-closable="false"
:style="{ width: '100vw', minHeight: '100vh' ,maxWidth:'100vw'}"
@update:show="closeModal"
:close-on-esc="false"
:auto-focus="false"
contentClass="tableStyle"
:show="isShow"
>
<template #header>
<div>
{{ title }}
</div>
</template>
<div class="">
<n-data-table
bordered
remote
striped
:paginate-single-page="true"
:single-line="false"
:single-column="false"
:columns="myColumns"
:data="tableData"
:row-key="(row) => row['orderId']"
></n-data-table>
</div>
</n-modal>
</template>
注意: 也可以单独处理赋值列数据取决于怎么使用
我这里是根据打开表单名字做的判断
4.弹窗的使用
因为使用的动态传递的缘故, 所以表格能点击的列需要自定义展示内容. 当前项目使用的NaiveUI, 需要使用render返回元素, 所以返回h函数创建的一个可点击的 span标签. stylePrimary为自定义的style. 表格列数据也应该在此传递进去. 因为我在弹窗部分做过处理, 所以没有传(copy的老系统代码, 直接根据title名字判断赋值列的数据).
import { useViewDialog } from "@/views/financial/commission/modal/viewDialog/useViewDialog.js";
const { update, clear } = useViewDialog();
//其中一个表格的一个列数据
[{
title: "xxxx",
key: "monthOrderAmount",
render: (row) => {
const click = h(
"span",
{
style: stylePrimary,
onclick: () => {
update({
title: "xxxx",
isShow: true,
showList: row[operatorTableKey["monthOrderAmount"]] ?? [],
});
},
},
row?.monthOrderAmount ?? "--",
);
return click;
},
needSummary: true,
},]
需要注意, 也要在表格所在vue文件引入弹窗组件(为此找了一会儿bug原因);
5.结语
以上是首次使用这种方式去复用组件, 以前都是用的父子组件传递数据的方式. 相比之下, 此方法更方便快捷.也减少多个组件使用的复杂度. 翻看其他开猿项目的复用组件也大多是用的此方法.