组件解析器

This commit is contained in:
caixiaofeng 2023-11-24 22:27:24 +08:00
parent 6364a5b417
commit e60f10324e
3 changed files with 105 additions and 10 deletions

View File

@ -0,0 +1,7 @@
export interface Field {
id: string,
title: string,
name: string,
value: any,
props: Record<string, any>
}

View File

@ -0,0 +1,88 @@
import {defineAsyncComponent, defineComponent, h, PropType, resolveComponent} from "vue";
import {cloneDeep} from 'lodash-es'
import {Field} from "./index";
export default defineComponent({
props: {
modelValue: {
type: [String, Number, Boolean, Array, Object] as PropType<any>,
default: undefined,
required: false
},
field: {
type: Object as PropType<Field>,
required: true
}
},
emits: ['update:modelValue'],
components: {
Input: defineAsyncComponent(() => import('element-plus/es').then(({ElInput}) => ElInput)),
Select: defineAsyncComponent(() => import('element-plus/es').then(({ElSelect}) => ElSelect)),
Radio: defineAsyncComponent(() => import('element-plus/es').then(({ElRadio}) => ElRadio)),
Checkbox: defineAsyncComponent(() => import('element-plus/es').then(({ElCheckbox}) => ElCheckbox)),
},
setup(props, {emit}) {
/**
*
* @param fieldClone
*/
const buildDataObject = (fieldClone: Field) => {
const dataObject: Record<string, any> = {}
const _props = fieldClone.props || {}
Object.keys(_props).forEach(key => {
dataObject[key] = _props[key]
})
dataObject.modelValue = fieldClone.value
dataObject['onUpdate:modelValue'] = (value: any) => {
emit('update:modelValue', value)
}
return dataObject
}
/**
*
* @param fieldClone
*/
const buildSlots = (fieldClone: Field) => {
let children: Record<string, any> = {}
const slotFunctions: Record<string, any> = {
Select: (conf: Field) => {
return conf.props.options.map((item: any) => {
return <el-option label={item.label} value={item.value}></el-option>
})
},
Radio: (conf: Field) => {
return conf.props.options.map((item: any) => {
return <el-radio label={item.value}>{item.label}</el-radio>
})
},
Checkbox: (conf: Field) => {
return conf.props.options.map((item: any) => {
return <el-checkbox label={item.value}>{item.label}</el-checkbox>
})
}
}
const slotFunction = slotFunctions[fieldClone.name]
if (slotFunction) {
children.default = () => {
return slotFunction(fieldClone)
}
}
return children
}
return {
buildDataObject,
buildSlots
}
},
render() {
const fieldClone: Field = cloneDeep(this.field)
const slots = this.buildSlots(fieldClone)
const dataObject = this.buildDataObject(fieldClone)
const componentName = fieldClone.name
const eleComponent = resolveComponent(componentName)
if (typeof eleComponent === 'string') {
return h(eleComponent, dataObject, slots)
}
return h(eleComponent, dataObject, slots)
}
})

View File

@ -50,16 +50,16 @@ const {node} = useVModels($props, $emits)
<el-form-item prop="leader" label="多级上级" v-if="node.assigneeType === 'leader'">
<el-select v-model="node.leader" placeholder="请选择多级上级">
<el-option label="直属上级" :value="1"></el-option>
<el-option label="级上级" :value="2"></el-option>
<el-option label="级上级" :value="3"></el-option>
<el-option label="级上级" :value="4"></el-option>
<el-option label="级上级" :value="5"></el-option>
<el-option label="级上级" :value="6"></el-option>
<el-option label="级上级" :value="7"></el-option>
<el-option label="级上级" :value="8"></el-option>
<el-option label="级上级" :value="9"></el-option>
<el-option label="级上级" :value="10"></el-option>
<el-option label="十一级上级" :value="11"></el-option>
<el-option label="2级上级" :value="2"></el-option>
<el-option label="3级上级" :value="3"></el-option>
<el-option label="4级上级" :value="4"></el-option>
<el-option label="5级上级" :value="5"></el-option>
<el-option label="6级上级" :value="6"></el-option>
<el-option label="7级上级" :value="7"></el-option>
<el-option label="8级上级" :value="8"></el-option>
<el-option label="9级上级" :value="9"></el-option>
<el-option label="10级上级" :value="10"></el-option>
<el-option label="11级上级" :value="11"></el-option>
</el-select>
</el-form-item>
<el-form-item prop="roles" label="指定角色" v-if="node.assigneeType === 'role'">