fix: 优化组件方法透传并新增表单弹窗示例 (#6443)
parent
78076e70b4
commit
fee811d950
|
|
@ -8,13 +8,7 @@ import type { Component } from 'vue';
|
||||||
import type { BaseFormComponentType } from '@vben/common-ui';
|
import type { BaseFormComponentType } from '@vben/common-ui';
|
||||||
import type { Recordable } from '@vben/types';
|
import type { Recordable } from '@vben/types';
|
||||||
|
|
||||||
import {
|
import { defineAsyncComponent, defineComponent, h, ref } from 'vue';
|
||||||
defineAsyncComponent,
|
|
||||||
defineComponent,
|
|
||||||
getCurrentInstance,
|
|
||||||
h,
|
|
||||||
ref,
|
|
||||||
} from 'vue';
|
|
||||||
|
|
||||||
import { ApiComponent, globalShareState, IconPicker } from '@vben/common-ui';
|
import { ApiComponent, globalShareState, IconPicker } from '@vben/common-ui';
|
||||||
import { $t } from '@vben/locales';
|
import { $t } from '@vben/locales';
|
||||||
|
|
@ -82,16 +76,15 @@ const withDefaultPlaceholder = <T extends Component>(
|
||||||
$t(`ui.placeholder.${type}`);
|
$t(`ui.placeholder.${type}`);
|
||||||
// 透传组件暴露的方法
|
// 透传组件暴露的方法
|
||||||
const innerRef = ref();
|
const innerRef = ref();
|
||||||
const publicApi: Recordable<any> = {};
|
expose(
|
||||||
expose(publicApi);
|
new Proxy(
|
||||||
const instance = getCurrentInstance();
|
{},
|
||||||
instance?.proxy?.$nextTick(() => {
|
{
|
||||||
for (const key in innerRef.value) {
|
get: (_target, key) => innerRef.value?.[key],
|
||||||
if (typeof innerRef.value[key] === 'function') {
|
has: (_target, key) => key in (innerRef.value || {}),
|
||||||
publicApi[key] = innerRef.value[key];
|
},
|
||||||
}
|
),
|
||||||
}
|
);
|
||||||
});
|
|
||||||
return () =>
|
return () =>
|
||||||
h(
|
h(
|
||||||
component,
|
component,
|
||||||
|
|
|
||||||
|
|
@ -8,13 +8,7 @@ import type { Component } from 'vue';
|
||||||
import type { BaseFormComponentType } from '@vben/common-ui';
|
import type { BaseFormComponentType } from '@vben/common-ui';
|
||||||
import type { Recordable } from '@vben/types';
|
import type { Recordable } from '@vben/types';
|
||||||
|
|
||||||
import {
|
import { defineAsyncComponent, defineComponent, h, ref } from 'vue';
|
||||||
defineAsyncComponent,
|
|
||||||
defineComponent,
|
|
||||||
getCurrentInstance,
|
|
||||||
h,
|
|
||||||
ref,
|
|
||||||
} from 'vue';
|
|
||||||
|
|
||||||
import { ApiComponent, globalShareState, IconPicker } from '@vben/common-ui';
|
import { ApiComponent, globalShareState, IconPicker } from '@vben/common-ui';
|
||||||
import { $t } from '@vben/locales';
|
import { $t } from '@vben/locales';
|
||||||
|
|
@ -139,16 +133,15 @@ const withDefaultPlaceholder = <T extends Component>(
|
||||||
$t(`ui.placeholder.${type}`);
|
$t(`ui.placeholder.${type}`);
|
||||||
// 透传组件暴露的方法
|
// 透传组件暴露的方法
|
||||||
const innerRef = ref();
|
const innerRef = ref();
|
||||||
const publicApi: Recordable<any> = {};
|
expose(
|
||||||
expose(publicApi);
|
new Proxy(
|
||||||
const instance = getCurrentInstance();
|
{},
|
||||||
instance?.proxy?.$nextTick(() => {
|
{
|
||||||
for (const key in innerRef.value) {
|
get: (_target, key) => innerRef.value?.[key],
|
||||||
if (typeof innerRef.value[key] === 'function') {
|
has: (_target, key) => key in (innerRef.value || {}),
|
||||||
publicApi[key] = innerRef.value[key];
|
},
|
||||||
}
|
),
|
||||||
}
|
);
|
||||||
});
|
|
||||||
return () =>
|
return () =>
|
||||||
h(
|
h(
|
||||||
component,
|
component,
|
||||||
|
|
|
||||||
|
|
@ -8,13 +8,7 @@ import type { Component } from 'vue';
|
||||||
import type { BaseFormComponentType } from '@vben/common-ui';
|
import type { BaseFormComponentType } from '@vben/common-ui';
|
||||||
import type { Recordable } from '@vben/types';
|
import type { Recordable } from '@vben/types';
|
||||||
|
|
||||||
import {
|
import { defineAsyncComponent, defineComponent, h, ref } from 'vue';
|
||||||
defineAsyncComponent,
|
|
||||||
defineComponent,
|
|
||||||
getCurrentInstance,
|
|
||||||
h,
|
|
||||||
ref,
|
|
||||||
} from 'vue';
|
|
||||||
|
|
||||||
import { ApiComponent, globalShareState, IconPicker } from '@vben/common-ui';
|
import { ApiComponent, globalShareState, IconPicker } from '@vben/common-ui';
|
||||||
import { $t } from '@vben/locales';
|
import { $t } from '@vben/locales';
|
||||||
|
|
@ -85,16 +79,15 @@ const withDefaultPlaceholder = <T extends Component>(
|
||||||
$t(`ui.placeholder.${type}`);
|
$t(`ui.placeholder.${type}`);
|
||||||
// 透传组件暴露的方法
|
// 透传组件暴露的方法
|
||||||
const innerRef = ref();
|
const innerRef = ref();
|
||||||
const publicApi: Recordable<any> = {};
|
expose(
|
||||||
expose(publicApi);
|
new Proxy(
|
||||||
const instance = getCurrentInstance();
|
{},
|
||||||
instance?.proxy?.$nextTick(() => {
|
{
|
||||||
for (const key in innerRef.value) {
|
get: (_target, key) => innerRef.value?.[key],
|
||||||
if (typeof innerRef.value[key] === 'function') {
|
has: (_target, key) => key in (innerRef.value || {}),
|
||||||
publicApi[key] = innerRef.value[key];
|
},
|
||||||
}
|
),
|
||||||
}
|
);
|
||||||
});
|
|
||||||
return () =>
|
return () =>
|
||||||
h(
|
h(
|
||||||
component,
|
component,
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,13 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { Page } from '@vben/common-ui';
|
import { Page, useVbenModal } from '@vben/common-ui';
|
||||||
|
|
||||||
import { NButton, NCard, useMessage } from 'naive-ui';
|
import { NButton, NCard, useMessage } from 'naive-ui';
|
||||||
|
|
||||||
import { useVbenForm } from '#/adapter/form';
|
import { useVbenForm } from '#/adapter/form';
|
||||||
import { getAllMenusApi } from '#/api';
|
import { getAllMenusApi } from '#/api';
|
||||||
|
|
||||||
|
import modalDemo from './modal.vue';
|
||||||
|
|
||||||
const message = useMessage();
|
const message = useMessage();
|
||||||
const [Form, formApi] = useVbenForm({
|
const [Form, formApi] = useVbenForm({
|
||||||
commonConfig: {
|
commonConfig: {
|
||||||
|
|
@ -143,6 +145,10 @@ function setFormValues() {
|
||||||
date: Date.now(),
|
date: Date.now(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const [Modal, modalApi] = useVbenModal({
|
||||||
|
connectedComponent: modalDemo,
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<Page
|
<Page
|
||||||
|
|
@ -152,8 +158,12 @@ function setFormValues() {
|
||||||
<NCard title="基础表单">
|
<NCard title="基础表单">
|
||||||
<template #header-extra>
|
<template #header-extra>
|
||||||
<NButton type="primary" @click="setFormValues">设置表单值</NButton>
|
<NButton type="primary" @click="setFormValues">设置表单值</NButton>
|
||||||
|
<NButton type="primary" @click="modalApi.open()" class="ml-2">
|
||||||
|
打开弹窗
|
||||||
|
</NButton>
|
||||||
</template>
|
</template>
|
||||||
<Form />
|
<Form />
|
||||||
</NCard>
|
</NCard>
|
||||||
|
<Modal />
|
||||||
</Page>
|
</Page>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,71 @@
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { useVbenModal } from '@vben/common-ui';
|
||||||
|
|
||||||
|
import { useVbenForm } from '#/adapter/form';
|
||||||
|
|
||||||
|
defineOptions({
|
||||||
|
name: 'FormModelDemo',
|
||||||
|
});
|
||||||
|
|
||||||
|
const [Form, formApi] = useVbenForm({
|
||||||
|
schema: [
|
||||||
|
{
|
||||||
|
component: 'Input',
|
||||||
|
componentProps: {
|
||||||
|
placeholder: '请输入',
|
||||||
|
},
|
||||||
|
fieldName: 'field1',
|
||||||
|
label: '字段1',
|
||||||
|
rules: 'required',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: 'Input',
|
||||||
|
componentProps: {
|
||||||
|
placeholder: '请输入',
|
||||||
|
},
|
||||||
|
fieldName: 'field2',
|
||||||
|
label: '字段2',
|
||||||
|
rules: 'required',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: 'Select',
|
||||||
|
componentProps: {
|
||||||
|
options: [
|
||||||
|
{ label: '选项1', value: '1' },
|
||||||
|
{ label: '选项2', value: '2' },
|
||||||
|
],
|
||||||
|
placeholder: '请输入',
|
||||||
|
},
|
||||||
|
fieldName: 'field3',
|
||||||
|
label: '字段3',
|
||||||
|
rules: 'required',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
showDefaultActions: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
const [Modal, modalApi] = useVbenModal({
|
||||||
|
fullscreenButton: false,
|
||||||
|
onCancel() {
|
||||||
|
modalApi.close();
|
||||||
|
},
|
||||||
|
onConfirm: async () => {
|
||||||
|
await formApi.validateAndSubmitForm();
|
||||||
|
// modalApi.close();
|
||||||
|
},
|
||||||
|
onOpenChange(isOpen: boolean) {
|
||||||
|
if (isOpen) {
|
||||||
|
const { values } = modalApi.getData<Record<string, any>>();
|
||||||
|
if (values) {
|
||||||
|
formApi.setValues(values);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
title: '内嵌表单示例',
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<Modal>
|
||||||
|
<Form />
|
||||||
|
</Modal>
|
||||||
|
</template>
|
||||||
|
|
@ -8,13 +8,7 @@ import type { Component } from 'vue';
|
||||||
import type { BaseFormComponentType } from '@vben/common-ui';
|
import type { BaseFormComponentType } from '@vben/common-ui';
|
||||||
import type { Recordable } from '@vben/types';
|
import type { Recordable } from '@vben/types';
|
||||||
|
|
||||||
import {
|
import { defineAsyncComponent, defineComponent, h, ref } from 'vue';
|
||||||
defineAsyncComponent,
|
|
||||||
defineComponent,
|
|
||||||
getCurrentInstance,
|
|
||||||
h,
|
|
||||||
ref,
|
|
||||||
} from 'vue';
|
|
||||||
|
|
||||||
import { ApiComponent, globalShareState, IconPicker } from '@vben/common-ui';
|
import { ApiComponent, globalShareState, IconPicker } from '@vben/common-ui';
|
||||||
import { $t } from '@vben/locales';
|
import { $t } from '@vben/locales';
|
||||||
|
|
@ -82,16 +76,24 @@ const withDefaultPlaceholder = <T extends Component>(
|
||||||
$t(`ui.placeholder.${type}`);
|
$t(`ui.placeholder.${type}`);
|
||||||
// 透传组件暴露的方法
|
// 透传组件暴露的方法
|
||||||
const innerRef = ref();
|
const innerRef = ref();
|
||||||
const publicApi: Recordable<any> = {};
|
// const publicApi: Recordable<any> = {};
|
||||||
expose(publicApi);
|
expose(
|
||||||
const instance = getCurrentInstance();
|
new Proxy(
|
||||||
instance?.proxy?.$nextTick(() => {
|
{},
|
||||||
for (const key in innerRef.value) {
|
{
|
||||||
if (typeof innerRef.value[key] === 'function') {
|
get: (_target, key) => innerRef.value?.[key],
|
||||||
publicApi[key] = innerRef.value[key];
|
has: (_target, key) => key in (innerRef.value || {}),
|
||||||
}
|
},
|
||||||
}
|
),
|
||||||
});
|
);
|
||||||
|
// const instance = getCurrentInstance();
|
||||||
|
// instance?.proxy?.$nextTick(() => {
|
||||||
|
// for (const key in innerRef.value) {
|
||||||
|
// if (typeof innerRef.value[key] === 'function') {
|
||||||
|
// publicApi[key] = innerRef.value[key];
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// });
|
||||||
return () =>
|
return () =>
|
||||||
h(
|
h(
|
||||||
component,
|
component,
|
||||||
|
|
|
||||||
|
|
@ -1470,9 +1470,6 @@ importers:
|
||||||
vue:
|
vue:
|
||||||
specifier: ^3.5.17
|
specifier: ^3.5.17
|
||||||
version: 3.5.17(typescript@5.8.3)
|
version: 3.5.17(typescript@5.8.3)
|
||||||
vue-sonner:
|
|
||||||
specifier: ^2.0.1
|
|
||||||
version: 2.0.1
|
|
||||||
|
|
||||||
packages/@core/ui-kit/tabs-ui:
|
packages/@core/ui-kit/tabs-ui:
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|
@ -11258,9 +11255,6 @@ packages:
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
vue: ^3.5.17
|
vue: ^3.5.17
|
||||||
|
|
||||||
vue-sonner@2.0.1:
|
|
||||||
resolution: {integrity: sha512-sn4vjCRzRcnMaxaLa9aNSyZQi6S+gshiea5Lc3eqpkj0ES9LH8ljg+WJCkxefr28V4PZ9xkUXBIWpxGfQxstIg==}
|
|
||||||
|
|
||||||
vue-tippy@6.7.1:
|
vue-tippy@6.7.1:
|
||||||
resolution: {integrity: sha512-gdHbBV5/Vc8gH87hQHLA7TN1K4BlLco3MAPrTb70ZYGXxx+55rAU4a4mt0fIoP+gB3etu1khUZ6c29Br1n0CiA==}
|
resolution: {integrity: sha512-gdHbBV5/Vc8gH87hQHLA7TN1K4BlLco3MAPrTb70ZYGXxx+55rAU4a4mt0fIoP+gB3etu1khUZ6c29Br1n0CiA==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
|
|
@ -22068,8 +22062,6 @@ snapshots:
|
||||||
'@vue/devtools-api': 6.6.4
|
'@vue/devtools-api': 6.6.4
|
||||||
vue: 3.5.17(typescript@5.8.3)
|
vue: 3.5.17(typescript@5.8.3)
|
||||||
|
|
||||||
vue-sonner@2.0.1: {}
|
|
||||||
|
|
||||||
vue-tippy@6.7.1(vue@3.5.17(typescript@5.8.3)):
|
vue-tippy@6.7.1(vue@3.5.17(typescript@5.8.3)):
|
||||||
dependencies:
|
dependencies:
|
||||||
tippy.js: 6.3.7
|
tippy.js: 6.3.7
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue