244 lines
7.5 KiB
Vue
244 lines
7.5 KiB
Vue
<!--
|
||
* @Description: 组件属性控件
|
||
-->
|
||
<template>
|
||
<div class="properties-content">
|
||
<div class="properties-body" v-if="formConfig.currentItem">
|
||
<Empty class="hint-box" v-if="!formConfig.currentItem.key" description="未选择组件" />
|
||
|
||
<Form label-align="left" layout="vertical">
|
||
<!-- 循环遍历渲染组件属性 -->
|
||
|
||
<div v-if="formConfig.currentItem && formConfig.currentItem.componentProps">
|
||
<FormItem v-for="item in inputOptions" :key="item.name" :label="item.label">
|
||
<!-- 处理数组属性,placeholder -->
|
||
|
||
<div v-if="item.children">
|
||
<template v-for="(child, index) of item.children" :key="index">
|
||
<component
|
||
v-if="child.component"
|
||
v-bind="child.componentProps"
|
||
v-model:value="formConfig.currentItem.componentProps[item.name][index]"
|
||
:is="child.component"
|
||
/>
|
||
</template>
|
||
</div>
|
||
<!-- 如果不是数组,则正常处理属性值 -->
|
||
<component
|
||
v-else-if="item.component"
|
||
class="component-prop"
|
||
v-bind="item.componentProps"
|
||
:is="item.component"
|
||
v-model:value="formConfig.currentItem.componentProps[item.name]"
|
||
/>
|
||
</FormItem>
|
||
<FormItem label="控制属性">
|
||
<Col v-for="item in controlOptions" :key="item.name">
|
||
<Checkbox
|
||
v-if="showControlAttrs(item.includes)"
|
||
v-bind="item.componentProps"
|
||
v-model:checked="formConfig.currentItem.componentProps[item.name]"
|
||
>
|
||
{{ item.label }}
|
||
</Checkbox>
|
||
</Col>
|
||
</FormItem>
|
||
</div>
|
||
<FormItem label="关联字段">
|
||
<Select
|
||
mode="multiple"
|
||
v-model:value="formConfig.currentItem['link']"
|
||
:options="linkOptions"
|
||
/>
|
||
</FormItem>
|
||
|
||
<FormItem
|
||
label="选项"
|
||
v-if="
|
||
[
|
||
'Select',
|
||
'CheckboxGroup',
|
||
'RadioGroup',
|
||
'TreeSelect',
|
||
'Cascader',
|
||
'AutoComplete',
|
||
].includes(formConfig.currentItem.component)
|
||
"
|
||
>
|
||
<FormOptions />
|
||
</FormItem>
|
||
|
||
<FormItem label="栅格" v-if="['Grid'].includes(formConfig.currentItem.component)">
|
||
<FormOptions />
|
||
</FormItem>
|
||
</Form>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
<script lang="ts">
|
||
import {
|
||
Empty,
|
||
Input,
|
||
Form,
|
||
FormItem,
|
||
Switch,
|
||
Checkbox,
|
||
Select,
|
||
InputNumber,
|
||
RadioGroup,
|
||
Col,
|
||
Row,
|
||
} from 'ant-design-vue';
|
||
import RadioButtonGroup from '@/components/Form/src/components/RadioButtonGroup.vue';
|
||
import { computed, defineComponent, ref, watch } from 'vue';
|
||
import { useFormDesignState } from '../../../hooks/useFormDesignState';
|
||
import {
|
||
baseComponentControlAttrs,
|
||
baseComponentAttrs,
|
||
baseComponentCommonAttrs,
|
||
componentPropsFuncs,
|
||
} from '../../VFormDesign/config/componentPropsConfig';
|
||
import FormOptions from './FormOptions.vue';
|
||
import { formItemsForEach, remove } from '../../../utils';
|
||
import { IBaseFormAttrs } from '../config/formItemPropsConfig';
|
||
|
||
export default defineComponent({
|
||
name: 'ComponentProps',
|
||
components: {
|
||
FormOptions,
|
||
Empty,
|
||
Input,
|
||
Form,
|
||
FormItem,
|
||
Switch,
|
||
Checkbox,
|
||
Select,
|
||
InputNumber,
|
||
RadioGroup,
|
||
RadioButtonGroup,
|
||
Col,
|
||
Row,
|
||
},
|
||
setup() {
|
||
// 让compuated属性自动更新
|
||
|
||
const allOptions = ref([] as Omit<IBaseFormAttrs, 'tag'>[]);
|
||
const showControlAttrs = (includes: string[] | undefined) => {
|
||
if (!includes) return true;
|
||
return includes.includes(formConfig.value.currentItem!.component);
|
||
};
|
||
|
||
const { formConfig } = useFormDesignState();
|
||
|
||
if (formConfig.value.currentItem) {
|
||
formConfig.value.currentItem.componentProps =
|
||
formConfig.value.currentItem.componentProps || {};
|
||
}
|
||
|
||
watch(
|
||
() => formConfig.value.currentItem?.field,
|
||
(_newValue, oldValue) => {
|
||
formConfig.value.schemas &&
|
||
formItemsForEach(formConfig.value.schemas, (item) => {
|
||
if (item.link) {
|
||
const index = item.link.findIndex((linkItem) => linkItem === oldValue);
|
||
index !== -1 && remove(item.link, index);
|
||
}
|
||
});
|
||
},
|
||
);
|
||
|
||
watch(
|
||
() => formConfig.value.currentItem && formConfig.value.currentItem.component,
|
||
() => {
|
||
allOptions.value = [];
|
||
baseComponentControlAttrs.forEach((item) => {
|
||
item.category = 'control';
|
||
if (!item.includes) {
|
||
// 如果属性没有include,所有的控件都适用
|
||
|
||
allOptions.value.push(item);
|
||
} else if (item.includes.includes(formConfig.value.currentItem!.component)) {
|
||
// 如果有include,检查是否包含了当前控件类型
|
||
allOptions.value.push(item);
|
||
}
|
||
});
|
||
|
||
baseComponentCommonAttrs.forEach((item) => {
|
||
item.category = 'input';
|
||
if (item.includes) {
|
||
if (item.includes.includes(formConfig.value.currentItem!.component)) {
|
||
allOptions.value.push(item);
|
||
}
|
||
} else if (item.exclude) {
|
||
if (!item.exclude.includes(formConfig.value.currentItem!.component)) {
|
||
allOptions.value.push(item);
|
||
}
|
||
} else {
|
||
allOptions.value.push(item);
|
||
}
|
||
});
|
||
|
||
baseComponentAttrs[formConfig.value.currentItem!.component] &&
|
||
baseComponentAttrs[formConfig.value.currentItem!.component].forEach(async (item) => {
|
||
if (item.component) {
|
||
if (['Switch', 'Checkbox', 'Radio'].includes(item.component as string)) {
|
||
item.category = 'control';
|
||
allOptions.value.push(item);
|
||
} else {
|
||
item.category = 'input';
|
||
allOptions.value.push(item);
|
||
}
|
||
}
|
||
});
|
||
},
|
||
{
|
||
immediate: true,
|
||
},
|
||
);
|
||
// 控制性的选项
|
||
const controlOptions = computed(() => {
|
||
return allOptions.value.filter((item) => {
|
||
return item.category == 'control';
|
||
});
|
||
});
|
||
|
||
// 非控制性选择
|
||
const inputOptions = computed(() => {
|
||
return allOptions.value.filter((item) => {
|
||
return item.category == 'input';
|
||
});
|
||
});
|
||
|
||
watch(
|
||
() => formConfig.value.currentItem!.componentProps,
|
||
() => {
|
||
const func = componentPropsFuncs[formConfig.value.currentItem!.component];
|
||
if (func) {
|
||
func(formConfig.value.currentItem!.componentProps, allOptions.value);
|
||
}
|
||
},
|
||
{
|
||
immediate: true,
|
||
deep: true,
|
||
},
|
||
);
|
||
const linkOptions = computed(() => {
|
||
return (
|
||
formConfig.value.schemas &&
|
||
formConfig.value.schemas
|
||
.filter((item) => item.key !== formConfig.value.currentItem!.key)
|
||
.map(({ label, field }) => ({ label: label + '/' + field, value: field }))
|
||
);
|
||
});
|
||
return {
|
||
formConfig,
|
||
showControlAttrs,
|
||
linkOptions,
|
||
controlOptions,
|
||
inputOptions,
|
||
};
|
||
},
|
||
});
|
||
</script>
|