vue-vben-admin
vue-vben-admin copied to clipboard
能否提供一个自定义封装用户选择框的组件(并托管给Form进行双向绑定管理)
⚠️ 重要 ⚠️ 在进一步操作之前,请检查下列选项。如果您忽视此模板或者没有提供关键信息,您的 Issue 将直接被关闭
- [ ] 已阅读 文档.
- [ ] 确保您的代码已是最新或者所报告的 Bug 在最新版本中可以重现. (部分 Bug 可能已经在最近的代码中修复)
- [ ] 已在 Issues 中搜索了相关的关键词
- [ ] 不是 ant design vue 组件库的 Bug
描述 Bug
我想封装一个自定义选择用户Form组件,单总是提示ReferenceError: Cannot access 'ApiTreeSelect' before initialization如下图
偶尔又不提示组件能用,重启后又提示这个错误组件又不渲染了
效果下图,我必须把弹框界面PositionSelectModal先注释,

复现 Bug
问题应是不能在自定义弹框组件中 BasicModal 里用BasicTable 望作者指点下
系统信息
- 操作系统:
- Node 版本:
- 包管理器 (npm/yarn/pnpm) 及其版本:
尝试修改代码结构如下:
<template>
<div class="p-4">
<BasicTable ref="tableRef" :dataSource="state?.data" @register="registerTable" />
<PositionSelectModal
:schemas="positionSelectModalSchemas"
@register="registerPositionSelectModal"
@submit="submitPositionSelect"
/>
<JSelectBizModal
:schemas="jSelectBizModalSchemas"
@register="registerJSelectBizModal"
@submit="submitJSelectBiz"
/>
</div>
</template>
创建可以动态传参的Modal自定义组件,将JSelectBizModal选择到的数据传入PositionSelectModal即可。
动态传参Modal参考,JSelectBizModal一样采用此类方法封装。
// Modal
<template>
<BasicModal v-bind="$attrs" @register="register" :title="title" @ok="getFormValues">
<BasicForm @register="registerForm" :model="modelRef" />
</BasicModal>
</template>
<script lang="ts" setup>
import type { PropType } from 'vue';
import { ref } from 'vue';
import { BasicModal, useModalInner } from '/@/components/Modal';
import { BasicForm, useForm } from '/@/components/Form/index';
import type { FormSchema } from '/@/components/Form/index';
const emits = defineEmits(['submit']);
const props = defineProps({
title: { type: String, default: '基本信息' },
schemas: {
type: [] as PropType<FormSchema[]>,
default: [
{
field: 'data',
component: 'Input',
label: '字段',
defaultValue: 'defaultValue',
},
],
},
});
const modelRef = ref({});
// 注册Form
const [
registerForm,
{
validateFields,
clearValidate,
resetFields,
// getFieldsValue, resetFields, setFieldsValue
},
] = useForm({
labelWidth: 100,
schemas: props.schemas,
showActionButtonGroup: false, //重置按钮
wrapperCol: { span: 16 }, // 输入表格
// 样式
baseRowStyle: {
display: 'flex',
flexDirection: 'column',
},
});
// 注册Modal
const [register, { closeModal }] = useModalInner((data: any) => {
let mergeData: any = {};
// 动态获取传参
props.schemas
.map((item) => item['field'])
.map((key: string) => {
if (!data[key]) return;
return { [key]: data[key] };
})
.forEach((item) => {
mergeData = Object.assign(mergeData, item);
});
// 绑定值到form
modelRef.value = mergeData;
});
// 获取表单数据
async function getFormValues() {
// 校验表单
const res = await validateForm();
// const values = getFieldsValue();
if (!res) return;
emits('submit', Object.assign({}, res));
// 重置校验
resetValidate();
// 清除值
clearField();
// 关闭 Modal
closeModal();
}
// 校验表格数据
async function validateForm() {
try {
const res = await validateFields();
console.log('passing', res);
// 返回校验后数据
return res;
} catch (error) {
return false;
}
}
// 重置表格数据
async function resetValidate() {
clearValidate();
}
// 清除表格数据
async function clearField() {
resetFields();
}
</script>
``
尝试修改代码结构如下:
<template> <div class="p-4"> <BasicTable ref="tableRef" :dataSource="state?.data" @register="registerTable" /> <PositionSelectModal :schemas="positionSelectModalSchemas" @register="registerPositionSelectModal" @submit="submitPositionSelect" /> <JSelectBizModal :schemas="jSelectBizModalSchemas" @register="registerJSelectBizModal" @submit="submitJSelectBiz" /> </div> </template>创建可以动态传参的
Modal自定义组件,将JSelectBizModal选择到的数据传入PositionSelectModal即可。 动态传参Modal参考,JSelectBizModal一样采用此类方法封装。// Modal <template> <BasicModal v-bind="$attrs" @register="register" :title="title" @ok="getFormValues"> <BasicForm @register="registerForm" :model="modelRef" /> </BasicModal> </template> <script lang="ts" setup> import type { PropType } from 'vue'; import { ref } from 'vue'; import { BasicModal, useModalInner } from '/@/components/Modal'; import { BasicForm, useForm } from '/@/components/Form/index'; import type { FormSchema } from '/@/components/Form/index'; const emits = defineEmits(['submit']); const props = defineProps({ title: { type: String, default: '基本信息' }, schemas: { type: [] as PropType<FormSchema[]>, default: [ { field: 'data', component: 'Input', label: '字段', defaultValue: 'defaultValue', }, ], }, }); const modelRef = ref({}); // 注册Form const [ registerForm, { validateFields, clearValidate, resetFields, // getFieldsValue, resetFields, setFieldsValue }, ] = useForm({ labelWidth: 100, schemas: props.schemas, showActionButtonGroup: false, //重置按钮 wrapperCol: { span: 16 }, // 输入表格 // 样式 baseRowStyle: { display: 'flex', flexDirection: 'column', }, }); // 注册Modal const [register, { closeModal }] = useModalInner((data: any) => { let mergeData: any = {}; // 动态获取传参 props.schemas .map((item) => item['field']) .map((key: string) => { if (!data[key]) return; return { [key]: data[key] }; }) .forEach((item) => { mergeData = Object.assign(mergeData, item); }); // 绑定值到form modelRef.value = mergeData; }); // 获取表单数据 async function getFormValues() { // 校验表单 const res = await validateForm(); // const values = getFieldsValue(); if (!res) return; emits('submit', Object.assign({}, res)); // 重置校验 resetValidate(); // 清除值 clearField(); // 关闭 Modal closeModal(); } // 校验表格数据 async function validateForm() { try { const res = await validateFields(); console.log('passing', res); // 返回校验后数据 return res; } catch (error) { return false; } } // 重置表格数据 async function resetValidate() { clearValidate(); } // 清除表格数据 async function clearField() { resetFields(); } </script>
不是很理解,PositionSelectModal 是具体的选择框是个列表,选择数据后要回传给JSelectBiz ,JSelectBiz封装了一个下拉框和一个选择按钮,JSelectBiz作为自定义组件注册给了BasicForm
你position的选择应该是用了basic-table把? basic-table里面又使用了form,那你这个form里面又使用了basic-table,block住了
This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 7 days