设计思路
可以在 DSL 文件中配置对应组件信息,然后在每个组件中配置子组件,最后在配置每一个字段在组件中显示什么组件,例如 有一个 name 字段 需要在 editForm 显示 input 框,我们就可以在 name 这个字段中配置 editFormOption 中的 monType 配置为 input,这样就可以在对应的组件中显示对应配置的子组件
具体实现
首先我们需要在 dsl 配置文件中配置对应的组件名称,我这边做的是一个弹出框,所以有一个 title 配置,saveBtnText 为保存按钮的 value, mainKey 为表单获取详情接口时需要的参数字段。
然后需要在对应的字段在组件中展示什么子组件,比如 product_name 在 createForm 和 editForm 中都是展示input 框, required 为校验字段必填项。注意(xxxxOption xxx 需要时再 componentConfig 下面的的 key 值对应,否则会找不到组件)
每个组件都必须要有 name 、inShow、和 show 方法来提供给父组件调用子组件
<template>
<el-drawer v-model="isShow" :destroy-on-close="true" append-to-body size="500">
<template #title>
<h2>{{ title }}</h2>
</template>
<template #default>
</template>
<template #footer>
<el-button type="primary" @click="save">{{ saveBtnText }}</el-button>
</template>
</el-drawer>
</template>
<script setup>
import { ref } from "vue";
const name = ref('editForm');
// 接受一个 command 方法,操作完后通知父组件执行方法
const emit = defineEmits(' command ')
const isShow = ref(false);
const show = () => {
isShow.value = true;
}
const save = () => {
// 保存逻辑...
isShow.value = false;
emit('command', {
event: 'loadTableData'
})
}
defineExpose({
name,
show
})
</script>
这样就完成了一个简单的组件,然后冗余在一个config.js文件中
import editForm from './edit-form/edit-form.vue';
const componentConfig = {
editForm: {
component: editForm
}
}
export default {
componentConfig,
}
当我们调用的时候就可以这样去调用
<template>
<component @command="onComponentCommand" ref="comListRef" v-for="(item, key) in components" :key="key"
:is="componentConfig[key]?.component">
</component>
</template>
<script setup>
import componentConfig from './components/component.config.js';
const comListRef = ref([]);
const showComponent = ({ btnConfig, rowData }) => {
const { comName } = btnConfig.eventOption;
if (!comName) {
console.error('没有配置组件')
return;
};
// 通过组件的 name 值去寻找到对应的组件
const comRef = comListRef.value.find(item => item.name === comName);
// 组件不存在或者没有show方法
if (!comRef || typeof comRef.show !== 'function') {
console.error(`找不到组件:${comName}`)
return
};
comRef.show(rowData);
const onComponentCommand = (e) => {
const { event } = e;
if (event === 'loadTableData') {
// 调用对应的方法
}
}
}
</script>