最近在学习vue3,结合element-plus做了一个后台管理系统的模板
项目中因所有一级页面的布局基本一致,所以将红框部分封装成了一个组件模板,模板内部所有控件可根据实际业务需求进行加载。
因为里面的组件全部都是用的element的控件,用模板封装后组件的attributes,event不太好写入,所以用vue的render对element组件做了一次渲染,动态写入传入配置,也可以使用v-bind,v-on绑定。
示例1:
//模板内部关于Tree的封装示例
import { getCurrentInstance,h} from "vue";
class commonModule {
createModule(constitute = { event: {}, attributes: {}, ref: "" }) {
return {
render: () => {
return h(
constitute.vnode, {
...constitute.attributes,
...constitute.event,
ref: constitute.ref,
}
)
}
}
}
}
const elementComponents = getCurrentInstance().appContext.components;
const createModule = new commonModule();
const props = defineProps({
treeConfig: {
type: Object,
default: () => {
return {};
},
requird: false,
},
})
const treeDefaultProps = computed(() => {
return Object.assign(
{
/**
* 详见element-plus Tree attribute配置
* 所有下划线连接替换为驼峰模式 例:
* show-checkbox 替换为 showCheckbox
* */
attributes: {},
/**
* 详见element-plus Tree event配置
* 所有方法需要在前面加上on 驼峰替换下划线 例:
* node-click 替换为 onNodeClick
* */
event: {},
},
props.treeConfig
);
});
const sinoTree = createModule.createModule({
vnode: elementComponents.ElTree,
attributes: treeDefaultProps.value.attributes,
event: treeDefaultProps.value.event,
ref: "treeRef",
});
// 组件的调用
<sinoTree><sinoTree/>
//模板调用页面传入配置
const treeDefaultProps = reactive({
attributes: {
emptyText: "暂无数据",
highlightCurrent: true,
defaultExpandAll: true,
checkStrictly: true,
data: [],
showCheckbox: true,
props: {
children: "children",
label: "label",
},
},
event: {
onNodeClick: (val) => {
console.log("点击");
},
onCheckChange: (val) => {
console.log("勾选");
},
},
});
示例 2
组件内部代码
<el-table
ref="sinoTableRef"
v-bind="props.tableConfig.tableattributes"
v-on="tableDefaultProps.tableEvent"
height="100%"
style="width: 100%"
:border="true"
>
<component
v-for="(item, index) in tableDefaultProps.tableColumnAttributes"
:key="index"
v-bind="item"
:is="'ElTableColumn'"
>
</component>
<slot name="customTableSlot"></slot>
</el-table>
const props = defineProps({
// table表格参数
tableConfig: {
type: Object,
default: () => {
return {};
},
requird: false,
},
})
const tableDefaultProps = computed(() => {
return Object.assign(
{
// 是否显示自定义table表格
customTable: false,
// 是否显示loading
loading: false,
/**
* 详见element-plus Table-column 配置
* 所有下划线连接替换为驼峰模式 例:
* column-key 替换为 columnKey
* */
tableColumnAttributes: [],
/**
* 详见element-plus table attribute配置
* 所有下划线连接替换为驼峰模式 例:
* max-height 替换为 maxHeight
* */
tableattributes: {
data: [],
},
/**
* 详见element-plus table event配置
* 驼峰替换下划线 例:
* selection-change 替换为 selectionChange
* */
tableEvent: {},
},
props.tableConfig
);
});
调用组件
//调用组件
<table :tableConfig="tableDefaultProps"></table>
//引入封装的组件
import table from "./table.vue";
const tableDefaultProps = reactive({
loading: false,
tableColumnAttributes: [
{
type: "index",
},
{
prop: "date",
label: "Date",
},
{
prop: "name",
label: "Name",
},
{
prop: "address",
label: "Address",
},
],
tableattributes: {
data: [],
},
tableEvent: {
onSelectionChange(val) {
console.log(val);
},
},
});