vue-vben-admin/src/views/form-design/components/VFormDesign/components/ComponentProps.vue

244 lines
7.5 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!--
* @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>