原来的方案虽然可以实现,但要在父组件里进行逻辑判断(drawer里写是在打开drawer的时候执行了update),进行数据转换。
折腾了2天,重新找到一个方案,通过在onChange那里判断(直接写在data里,是渲染的时候执行的),更新新的选项:
data组件:一个是三联动态选择;一个customer,可以模糊搜索,更新选项:
// 抽屉表单,新增和修改用, FormSchema ,是一个数组,用于描述表单的结构和行为
// component: 用于渲染表单字段的组件类型,'Input' 表示这是一个输入框组件
// component: 'DictSelect',下拉选择框(Select),它与字典(Dictionary)数据关联
// import { getMachineClassList, getMachineOrControlTypeList } from '/@/views/basic_data/machine_type/api';
// import { getList as getCustomerList } from '/@/views/basic_data/customer/customer_data/api';
export const formSchema: FormSchema[] = [
{
field: 'id',
label: 'ID',
component: 'Input',
show: false,
},
{
field: 'machine_class_id',
component: 'Input',
ifShow: false,
},
{
field: 'machine_type_id',
component: 'Input',
ifShow: false,
},
{
field: 'control_type_id',
component: 'Input',
ifShow: false,
},
// formActionType 通常是一个对象,包含了一些用于操作表单的方法
// 以下是一些常见的 formActionType 方法及其用途:updateSchema:用于动态更新表单字段的 schema
// resetFields:用于重置表单字段;setFieldsValue:用于设置表单字段的值; validate:用于验证表单
// formModel 通常表示当前表单的模型数据,即表单中的各个字段及其对应的值
// 可以通过formModel读和写
{
field: 'machine_class_type',
label: '机床类型',
required: true,
component: 'ApiSelect',
componentProps: ({ formModel, formActionType }) => ({
api: getMachineClassList,
labelField: 'type',
valueField: 'id',
onChange: async (selectedId) => {
if (typeof selectedId === 'number') { // 如果 value 是数字,表示是有效的 ID
formModel.machine_class_id = selectedId;
}
// formModel.machine_class_id = selectedId;
formModel.machine_type_type = undefined;
formModel.control_type_type = undefined;
if (formActionType !== undefined) {
const { updateSchema } = formActionType;
const res = await getMachineOrControlTypeList(selectedId);
const machine_type_option = res.map((item) => ({
label: item.type,
value: item.id,
}));
updateSchema({
field: 'machine_type_type',
componentProps: ({ formModel, formActionType}) => ({
options: machine_type_option,
onChange: async (value) => {
if (typeof value === 'number') { // 如果 value 是数字,表示是有效的 ID
formModel.machine_type_id = value;
}
formModel.control_type_type = undefined;
if (formActionType !== undefined) {
const res = await getMachineOrControlTypeList(value);
const control_type_option = res.map((item) => ({
label: item.type,
value: item.id,
}));
updateSchema({
field: 'control_type_type',
componentProps: {
options: control_type_option,
onChange: (controlTypeValue) => {
formModel.control_type_id = controlTypeValue;
},
},
});
}
},
}),
});
}
},
}),
},
{
field: 'machine_type_type',
label: '机器型号',
required: true,
component: 'Select',
},
{
field: 'control_type_type',
label: '控制系统',
required: true,
component: 'Select',
},
{
field: 'setup_date',
label: '安装日期',
required: true,
component: 'DatePicker',
componentProps: {
style: { width: '100%' },
valueFormat: 'YYYY-MM-DD',
},
},
{
field: 'year_of_build',
label: '制造年份',
required: true,
component: 'Input',
},
{
field: 'warranty_date',
label: '保修日期',
required: true,
component: 'DatePicker',
componentProps: {
style: { width: '100%' },
valueFormat:'YYYY-MM-DD',
},
},
{
field: 'customer_id',
component: 'Input',
ifShow: false,
},
{
field: 'customer_name',
label: '客户名字',
required: true,
component: 'ApiSelect',
componentProps: ({ formModel }) => {//formModel 是一个代表表单当前状态或模型的对象(有name多个属性),这个对象被传递给 componentProps 函数,以便在自定义组件 ApiSelect 中使用
return {
api: getCustomerList,
params: { name: formModel.name }, //params是请求参数,其中根据表单模型中的“name”来设置
resultField: 'items', // 指定结果数据中的字段,items、labelField 和 valueField 一起定义了下拉列表中的选项
showSearch: true,
labelField: 'name',
valueField: 'id',
immediate: true,
onSearch(value) {
formModel.name = value; // 定义了搜索时的行为,将搜索值赋给表单模型中的“name”
},
onChange(value) {
// // formModel.customer_name = value; // 将选择的值赋给表单模型中的“customer_name”
// formModel.customer_id = value; // 将选择的值赋给表单模型中的“customer_id”
if (typeof value === 'number') { // 如果 value 是数字,表示是有效的 ID
formModel.customer_id = value;
}
},
filterOption: false, // 表示进行选项过滤,用户在下拉框中输入 “张”,并且 filterOption 设置为 true,那么下拉列表将只显示 “张三” 这一个选项
};
},
},
{
field: 'machine_sn',
label: '序列号',
required: true,
component: 'Input',
},
];
新的drawer 组件,比之前简单一些了:
<script lang="ts">
import { defineComponent, ref, computed, unref } from 'vue';
import { BasicForm, useForm } from '/@/components/Form/index';
import { createOrUpdate } from './api';
import { useI18n } from 'vue-i18n';
import { formSchema } from './data';
import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
export default defineComponent({
name: 'MachineBankDrawer',
components: { BasicDrawer, BasicForm },
emits: ['success', 'register'],
setup(_, { emit }) {
const isUpdate = ref(true); //isUpdate是一个响应式引用
const { t } = useI18n();
const rowId = ref(''); //定义行的ID,UPDATE用
const [registerForm,{ resetFields, setFieldsValue, validate, updateSchema, getFieldsValue }] = useForm({
labelWidth: 100,
schemas: formSchema,
showActionButtonGroup: false, //显示查询,重置按钮
baseColProps: { lg: 12, md: 24 },
});
const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
await resetFields(); // 重置表单字段,打开POST请求清空
setDrawerProps({ confirmLoading: false });
isUpdate.value = !!data?.isUpdate;
if (unref(isUpdate)) {
rowId.value = data.record.id;
await setFieldsValue({// 插入await,原来没有
...data.record,
});
} // if update 执行到这里
});
const getTitle = computed(() =>
!unref(isUpdate) ? t('common.addText') : t('common.updateText'),
);
// 提交表单数据
async function handleSubmit() {
try {
const values = await validate();
console.log('Form values:', values); // 打印表单值,检查是否包含 customer 信息
setDrawerProps({ confirmLoading: true });
await createOrUpdate(values, unref(isUpdate));
closeDrawer();
emit('success',{ isUpdate: unref(isUpdate), values: { ...values, id: rowId.value } });
} finally {
setDrawerProps({ confirmLoading: false });
}
}
return {
registerDrawer,
registerForm,
getTitle,
handleSubmit,
isUpdate,
};
},
});
</script>
onChange 有一个bug:
所有在onChange后加了个数字判断,只有数字才转换(实际生活中几乎没有用数字做名字的)。