Skip to content

Commit 66abcda

Browse files
authored
fix(form): validate 获取子节点规则方式调整 (#2593)
1 parent 326b893 commit 66abcda

File tree

3 files changed

+95
-50
lines changed

3 files changed

+95
-50
lines changed

src/packages/__VUE/form/common.ts

Lines changed: 59 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,5 @@
1-
import { getPropByPath, isObject, isPromise } from '@/packages/utils/util';
2-
import {
3-
computed,
4-
isVNode,
5-
PropType,
6-
provide,
7-
reactive,
8-
watch,
9-
getCurrentInstance,
10-
type VNodeNormalizedChildren
11-
} from 'vue';
1+
import { getPropByPath, isPromise } from '@/packages/utils/util';
2+
import { computed, PropType, provide, reactive, watch } from 'vue';
123
import { FormItemRule } from '../formitem/types';
134
import { ErrorMessage, FormRule, FormRules } from './types';
145

@@ -28,6 +19,55 @@ export const component = (components: any) => {
2819
emits: ['validate'],
2920

3021
setup(props: any, { emit }: any) {
22+
const useChildren = () => {
23+
const publicChildren: any[] = reactive([]);
24+
const internalChildren: any[] = reactive([]);
25+
26+
const linkChildren = (value?: any) => {
27+
const link = (child: any) => {
28+
if (child.proxy) {
29+
internalChildren.push(child);
30+
publicChildren.push(child.proxy as any);
31+
}
32+
};
33+
34+
const removeLink = (child: any) => {
35+
if (child.proxy) {
36+
let internalIndex = internalChildren.indexOf(child);
37+
if (internalIndex > -1) {
38+
internalChildren.splice(internalIndex, 1);
39+
}
40+
41+
let publicIndex = publicChildren.indexOf(child.proxy);
42+
if (internalIndex > -1) {
43+
publicChildren.splice(publicIndex, 1);
44+
}
45+
}
46+
};
47+
48+
provide(
49+
'NutFormParent',
50+
Object.assign(
51+
{
52+
removeLink,
53+
link,
54+
children: publicChildren,
55+
internalChildren
56+
},
57+
value
58+
)
59+
);
60+
};
61+
62+
return {
63+
children: publicChildren,
64+
linkChildren
65+
};
66+
};
67+
68+
const { children, linkChildren } = useChildren();
69+
linkChildren({ props });
70+
3171
const formErrorTip = computed(() => reactive<any>({}));
3272
provide('formErrorTip', formErrorTip);
3373
const clearErrorTips = () => {
@@ -48,39 +88,14 @@ export const component = (components: any) => {
4888
{ immediate: true }
4989
);
5090

51-
const findFormItem = (vNodeChildren: VNodeNormalizedChildren) => {
91+
const getTaskFromChildren = () => {
5292
const task: FormRule[] = [];
53-
54-
const search = (vNode: VNodeNormalizedChildren) => {
55-
if (isVNode(vNode)) {
56-
const type = (vNode?.type as any)?.name || vNode?.type;
57-
if (type == 'nut-form-item' || type?.toString().endsWith('form-item')) {
58-
task.push({
59-
prop: vNode.props?.['prop'],
60-
rules: vNode.props?.['rules'] || []
61-
});
62-
} else if (vNode.component?.subTree) {
63-
const childSubTree = vNode.component?.subTree;
64-
search(childSubTree.children);
65-
if (isObject(childSubTree.children) && Object.keys(childSubTree.children)) {
66-
// 异步节点获取
67-
if ((childSubTree.children as any)?.default) {
68-
search((childSubTree.children as any).default());
69-
}
70-
} else {
71-
search(childSubTree.children);
72-
}
73-
} else if (vNode.children) {
74-
search(vNode.children);
75-
}
76-
} else if (Array.isArray(vNode)) {
77-
vNode.forEach((v: any) => {
78-
search(v);
79-
});
80-
}
81-
};
82-
83-
search(vNodeChildren);
93+
children.forEach((item) => {
94+
task.push({
95+
prop: item?.['prop'],
96+
rules: item?.['rules'] || []
97+
});
98+
});
8499
return task;
85100
};
86101

@@ -150,9 +165,6 @@ export const component = (components: any) => {
150165
return Promise.resolve(true);
151166
};
152167

153-
// only setup get
154-
const instance = getCurrentInstance()!;
155-
156168
/**
157169
* 校验
158170
* @param customProp 指定校验,用于用户自定义场景时触发,例如 blur、change 事件
@@ -161,8 +173,7 @@ export const component = (components: any) => {
161173
const validate = (customProp = '') => {
162174
return new Promise((resolve, reject) => {
163175
try {
164-
// 改用当前组件树subtree
165-
const task = findFormItem(instance.subTree.children);
176+
const task = getTaskFromChildren();
166177

167178
const errors = task.map((item) => {
168179
if (customProp && customProp !== item.prop) {

src/packages/__VUE/formitem/index.taro.vue

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
</template>
2525
<script lang="ts">
2626
import { pxCheck } from '@/packages/utils/pxCheck';
27-
import { computed, inject, provide, PropType, CSSProperties } from 'vue';
27+
import { computed, inject, provide, PropType, CSSProperties, getCurrentInstance, onUnmounted } from 'vue';
2828
import type { FormItemRule } from './types';
2929
import { createComponent } from '@/packages/utils/create';
3030
import Cell from '../cell/index.taro.vue';
@@ -77,6 +77,23 @@ export default create({
7777
[Cell.name]: Cell
7878
},
7979
setup(props, { slots }) {
80+
const useParent: any = () => {
81+
const parent = inject('NutFormParent', null);
82+
if (parent) {
83+
// 获取子组件自己的实例
84+
const instance = getCurrentInstance()!;
85+
const { link, removeLink } = parent;
86+
// @ts-ignore
87+
link(instance);
88+
onUnmounted(() => {
89+
// @ts-ignore
90+
removeLink(instance);
91+
});
92+
return { parent };
93+
}
94+
};
95+
useParent();
96+
8097
const parent = inject('formErrorTip') as any;
8198
provide('form', {
8299
props

src/packages/__VUE/formitem/index.vue

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
</template>
2525
<script lang="ts">
2626
import { pxCheck } from '@/packages/utils/pxCheck';
27-
import { computed, inject, provide, PropType, CSSProperties } from 'vue';
27+
import { computed, inject, provide, PropType, CSSProperties, getCurrentInstance, onUnmounted } from 'vue';
2828
import type { FormItemRule } from './types';
2929
import { createComponent } from '@/packages/utils/create';
3030
import Cell from '../cell/index.vue';
@@ -77,6 +77,23 @@ export default create({
7777
[Cell.name]: Cell
7878
},
7979
setup(props, { slots }) {
80+
const useParent: any = () => {
81+
const parent = inject('NutFormParent', null);
82+
if (parent) {
83+
// 获取子组件自己的实例
84+
const instance = getCurrentInstance()!;
85+
const { link, removeLink } = parent;
86+
// @ts-ignore
87+
link(instance);
88+
onUnmounted(() => {
89+
// @ts-ignore
90+
removeLink(instance);
91+
});
92+
return { parent };
93+
}
94+
};
95+
useParent();
96+
8097
const parent = inject('formErrorTip') as any;
8198
provide('form', {
8299
props

0 commit comments

Comments
 (0)