diff --git a/package.json b/package.json
index 587ff619a67..5ed89712889 100644
--- a/package.json
+++ b/package.json
@@ -57,9 +57,9 @@
"@rollup/plugin-commonjs": "^17.0.0",
"@testing-library/jest-dom": "^5.0.0",
"@testing-library/react": "^11.2.3",
- "@testing-library/vue": "^5.6.1",
- "@types/hoist-non-react-statics": "^3.3.1",
+ "@testing-library/vue": "^5.6.2",
"@types/fs-extra": "^8.1.0",
+ "@types/hoist-non-react-statics": "^3.3.1",
"@types/jest": "^24.0.18",
"@types/node": "^12.6.8",
"@types/react": "^17.0.0",
@@ -67,6 +67,7 @@
"@typescript-eslint/eslint-plugin": "^4.9.1",
"@typescript-eslint/parser": "^4.8.2",
"@umijs/plugin-sass": "^1.1.1",
+ "@vue/test-utils": "^1.2.0",
"antd": "^4.0.0",
"chalk": "^2.4.2",
"chokidar": "^2.1.2",
@@ -77,22 +78,22 @@
"css-loader": "^5.0.0",
"cz-conventional-changelog": "^2.1.0",
"dumi": "^1.1.0-rc.8",
+ "escape-string-regexp": "^4.0.0",
"eslint": "^7.14.0",
- "semver": "^7.3.5",
- "string-similarity": "^4.0.4",
"eslint-config-prettier": "^7.0.0",
"eslint-plugin-import": "^2.13.0",
+ "eslint-plugin-markdown": "^2.0.1",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-prettier": "^3.1.0",
"eslint-plugin-promise": "^4.0.0",
"eslint-plugin-react": "^7.14.2",
"eslint-plugin-react-hooks": "^4.2.0",
- "eslint-plugin-markdown": "^2.0.1",
"eslint-plugin-vue": "^7.0.1",
"execa": "^5.0.0",
"file-loader": "^5.0.2",
"findup": "^0.1.5",
"fs-extra": "^7.0.1",
+ "gh-release": "^5.0.1",
"ghooks": "^2.0.4",
"glob": "^7.1.3",
"html-webpack-plugin": "^3.2.0",
@@ -106,35 +107,37 @@
"jest-styled-components": "6.3.3",
"jest-watch-lerna-packages": "^1.1.0",
"lerna": "^4.0.0",
- "gh-release": "^5.0.1",
"less": "^4.1.1",
"less-plugin-npm-import": "^2.1.0",
- "postcss": "^8.0.0",
"lint-staged": "^8.2.1",
"mfetch": "^0.2.27",
"mobx": "^6.0.4",
"mobx-react-lite": "^3.1.6",
- "escape-string-regexp": "^4.0.0",
"onchange": "^5.2.0",
"opencollective": "^1.0.3",
"opencollective-postinstall": "^2.0.2",
"param-case": "^3.0.4",
+ "postcss": "^8.0.0",
"prettier": "^2.2.1",
"pretty-format": "^24.0.0",
"pretty-quick": "^3.1.0",
"raw-loader": "^4.0.0",
"react": "^17.0.1",
"react-dom": "^17.0.1",
+ "react-mde": "^11.5.0",
"react-test-renderer": "^16.11.0",
"rimraf": "^3.0.0",
"rollup": "^2.37.1",
"rollup-plugin-external-globals": "^0.6.1",
"rollup-plugin-node-resolve": "^5.2.0",
+ "rollup-plugin-postcss": "^4.0.0",
"rollup-plugin-terser": "^7.0.2",
"rollup-plugin-typescript2": "^0.30.0",
- "rollup-plugin-postcss": "^4.0.0",
+ "semver": "^7.3.5",
"semver-regex": "^2.0.0",
+ "showdown": "^1.9.1",
"staged-git-files": "^1.1.2",
+ "string-similarity": "^4.0.4",
"style-loader": "^1.1.3",
"styled-components": "^5.0.0",
"ts-import-plugin": "1.6.1",
@@ -145,9 +148,7 @@
"vue-eslint-parser": "^7.1.1",
"webpack": "^4.41.5",
"webpack-cli": "^3.3.10",
- "webpack-dev-server": "^3.10.1",
- "showdown": "^1.9.1",
- "react-mde": "^11.5.0"
+ "webpack-dev-server": "^3.10.1"
},
"repository": {
"type": "git",
diff --git a/packages/vue/docs/demos/api/components/recursion-field-with-component.vue b/packages/vue/docs/demos/api/components/recursion-field-with-component.vue
index 969b7bf8a1c..53820542d6c 100644
--- a/packages/vue/docs/demos/api/components/recursion-field-with-component.vue
+++ b/packages/vue/docs/demos/api/components/recursion-field-with-component.vue
@@ -15,46 +15,69 @@ import { defineComponent, h } from '@vue/composition-api'
// or "import { defineComponent, h } from 'vue'" if using vue3
import { Input, Button, Space } from 'ant-design-vue'
import { createForm } from '@formily/core'
-import { FormProvider, createSchemaField, RecursionField, useField, useFieldSchema, observer } from '@formily/vue'
+import {
+ FormProvider,
+ createSchemaField,
+ RecursionField,
+ useField,
+ useFieldSchema,
+ observer,
+} from '@formily/vue'
import 'ant-design-vue/dist/antd.css'
-const ArrayItems = observer(defineComponent({
- props: ['value', 'disabled', 'readOnly'],
- setup (props) {
- const fieldRef = useField()
- const schemaRef = useFieldSchema()
+const ArrayItems = observer(
+ defineComponent({
+ setup() {
+ const fieldRef = useField()
+ const schemaRef = useFieldSchema()
- return () => {
- const field = fieldRef.value
- const schema = schemaRef.value
- const items = props.value?.map((item, index) => {
- return h('div', { key: item.id, style: { marginBottom: '10px' } }, [
- h(Space, [
- // params of render function is different in vue3
- h(RecursionField, { props: { schema: schema.items, name: index } }),
- h(Button, { on: { click: () => field.remove(index) } }, ['Remove']),
+ return () => {
+ const field = fieldRef.value
+ const schema = schemaRef.value
+ const items = field.value?.map((item, index) => {
+ return h('div', { key: item.id, style: { marginBottom: '10px' } }, [
+ h(Space, [
+ // params of render function is different in vue3
+ h(RecursionField, {
+ props: { schema: schema.items, name: index },
+ }),
+ h(Button, { on: { click: () => field.remove(index) } }, [
+ 'Remove',
+ ]),
+ ]),
])
- ])
- })
- const button = h(Button, { on: { click: () => field.push({ id: Date.now() }) } }, ['Add'])
- return h('div', [items, button])
- }
- },
-}))
+ })
+ const button = h(
+ Button,
+ { on: { click: () => field.push({ id: Date.now() }) } },
+ ['Add']
+ )
+ return h('div', [items, button])
+ }
+ },
+ })
+)
-const { SchemaField, SchemaStringField, SchemaArrayField, SchemaObjectField } = createSchemaField({
- components: {
- ArrayItems,
- Input,
- },
-})
+const { SchemaField, SchemaStringField, SchemaArrayField, SchemaObjectField } =
+ createSchemaField({
+ components: {
+ ArrayItems,
+ Input,
+ },
+ })
export default {
- components: { FormProvider, SchemaField, SchemaStringField, SchemaArrayField, SchemaObjectField },
+ components: {
+ FormProvider,
+ SchemaField,
+ SchemaStringField,
+ SchemaArrayField,
+ SchemaObjectField,
+ },
data() {
return {
- form: createForm()
+ form: createForm(),
}
- }
+ },
}
diff --git a/packages/vue/src/__tests__/schema.markup.spec.ts b/packages/vue/src/__tests__/schema.markup.spec.ts
index a83fbf2a38a..d04f474f4ba 100644
--- a/packages/vue/src/__tests__/schema.markup.spec.ts
+++ b/packages/vue/src/__tests__/schema.markup.spec.ts
@@ -8,6 +8,7 @@ import {
Schema,
} from '../index'
import { render } from '@testing-library/vue'
+import { mount, createLocalVue } from '@vue/test-utils'
import Vue, { CreateElement } from 'vue'
import { defineComponent, h } from '@vue/composition-api'
@@ -570,87 +571,94 @@ describe('recursion field', () => {
expect(queryByTestId('input')).toBeNull()
})
- // test('schema reactions', async () => {
- // const form = createForm()
- // const components = createSchemaField({
- // components: {
- // Input,
- // },
- // })
- // const { queryByTestId } = render({
- // components: components,
- // data () {
- // return {
- // form,
- // reactions: [
- // {
- // when: '{{$form.values.aaa === "123"}}',
- // fulfill: {
- // state: {
- // visible: true,
- // },
- // },
- // otherwise: {
- // state: {
- // visible: false,
- // },
- // },
- // },
- // {
- // when: '{{$self.value === "123"}}',
- // target: 'ccc',
- // fulfill: {
- // schema: {
- // 'x-visible': true,
- // },
- // },
- // otherwise: {
- // schema: {
- // 'x-visible': false,
- // },
- // },
- // },
- // ]
- // }
- // },
- // template: `
- //
- //
- //
- //
- //
- // `
- // })
- // expect(queryByTestId('bbb')).toBeNull()
- // fireEvent.update(queryByTestId('aaa'), '123')
- // expect(form.query('aaa').get('value')).toEqual('123')
- // await waitFor(() => {
- // expect(queryByTestId('bbb')).toBeVisible()
- // })
- // expect(queryByTestId('ccc')).toBeNull()
- // fireEvent.update(queryByTestId('bbb'), '123')
- // expect(form.query('bbb').get('value')).toEqual('123')
- // await waitFor(() => {
- // expect(queryByTestId('ccc')).toBeVisible()
- // })
- // })
+ test('schema reactions', async () => {
+ const div = document.createElement('div')
+ document.body.appendChild(div)
+ const form = createForm()
+ const components = createSchemaField({
+ components: {
+ Input,
+ },
+ })
+ const localVue = createLocalVue()
+ localVue.component('FormProvider', FormProvider)
+ const TestComponent = {
+ components: components,
+ data() {
+ return {
+ form,
+ reactions: [
+ {
+ when: '{{$form.values.aaa === "123"}}',
+ fulfill: {
+ state: {
+ visible: true,
+ },
+ },
+ otherwise: {
+ state: {
+ visible: false,
+ },
+ },
+ },
+ {
+ when: '{{$self.value === "123"}}',
+ target: 'ccc',
+ fulfill: {
+ schema: {
+ 'x-visible': true,
+ },
+ },
+ otherwise: {
+ schema: {
+ 'x-visible': false,
+ },
+ },
+ },
+ ],
+ }
+ },
+ template: `
+
+
+
+
+
+ `,
+ } as any
+ const wrapper = mount(TestComponent, {
+ attachTo: div,
+ localVue,
+ })
+ expect(wrapper.find('.bbb').exists()).toBeFalsy()
+ wrapper.find('.aaa').setValue('123')
+ expect(form.query('aaa').get('value')).toEqual('123')
+ await wrapper.vm.$forceUpdate()
+ expect(wrapper.find('.bbb').exists()).toBeTruthy()
+ expect(wrapper.find('.ccc').exists()).toBeFalsy()
+ wrapper.find('.bbb').setValue('123')
+ expect(form.query('bbb').get('value')).toEqual('123')
+ await wrapper.vm.$forceUpdate()
+ expect(wrapper.find('.ccc').exists()).toBeTruthy()
+ wrapper.destroy()
+ })
})
diff --git a/packages/vue/src/components/ArrayField.ts b/packages/vue/src/components/ArrayField.ts
index 74a241e83ae..203ba50fdbd 100644
--- a/packages/vue/src/components/ArrayField.ts
+++ b/packages/vue/src/components/ArrayField.ts
@@ -81,24 +81,25 @@ export default observer(
provide(FieldSymbol, fieldRef)
- return () =>
- h(
- ReactiveField,
- {
- props: {
- field: fieldRef.value,
- },
+ return () => {
+ const field = fieldRef.value
+ const componentData = {
+ props: {
+ field,
},
- {
- ...slots,
- default: () =>
- slots.default &&
- slots.default({
- field: fieldRef.value,
- form: fieldRef.value.form,
- }),
- }
- )
+ }
+ const children = {
+ ...slots,
+ }
+ if (slots.default) {
+ children.default = () =>
+ slots.default({
+ field: field,
+ form: field.form,
+ })
+ }
+ return h(ReactiveField, componentData, children)
+ }
},
}) as unknown as DefineComponent
)
diff --git a/packages/vue/src/components/Field.ts b/packages/vue/src/components/Field.ts
index 7608a9c3b03..476e1364ef1 100644
--- a/packages/vue/src/components/Field.ts
+++ b/packages/vue/src/components/Field.ts
@@ -78,23 +78,22 @@ export default defineComponent>({
return () => {
const field = fieldRef.value
- return h(
- ReactiveField,
- {
- props: {
- field,
- },
+ const componentData = {
+ props: {
+ field,
},
- {
- ...slots,
- default: () =>
- slots.default &&
- slots.default({
- field,
- form: field.form,
- }),
- }
- )
+ }
+ const children = {
+ ...slots,
+ }
+ if (slots.default) {
+ children.default = () =>
+ slots.default({
+ field,
+ form: field.form,
+ })
+ }
+ return h(ReactiveField, componentData, children)
}
},
}) as unknown as DefineComponent>
diff --git a/packages/vue/src/components/FormConsumer.ts b/packages/vue/src/components/FormConsumer.ts
index 39d713fa0e0..4a412bc586f 100644
--- a/packages/vue/src/components/FormConsumer.ts
+++ b/packages/vue/src/components/FormConsumer.ts
@@ -8,19 +8,20 @@ export default observer(
defineComponent({
name: 'FormConsumer',
inheritAttrs: false,
- setup(props, { attrs, slots }) {
+ setup(props, { slots }) {
const formRef = useForm()
- return () =>
- h(
- Fragment,
- { attrs },
- {
- default: () =>
- slots.default?.({
- form: formRef.value,
- }),
- }
- )
+ return () => {
+ const children = {
+ ...slots,
+ }
+ if (slots.default) {
+ children.default = () =>
+ slots.default({
+ form: formRef.value,
+ })
+ }
+ return h(Fragment, {}, children)
+ }
},
}) as unknown as DefineComponent
)
diff --git a/packages/vue/src/components/ObjectField.ts b/packages/vue/src/components/ObjectField.ts
index 84087c573a6..ca8c1e43522 100644
--- a/packages/vue/src/components/ObjectField.ts
+++ b/packages/vue/src/components/ObjectField.ts
@@ -82,24 +82,25 @@ export default observer(
provide(FieldSymbol, fieldRef)
- return () =>
- h(
- ReactiveField,
- {
- props: {
- field: fieldRef.value,
- },
+ return () => {
+ const field = fieldRef.value
+ const componentData = {
+ props: {
+ field,
},
- {
- ...slots,
- default: () =>
- slots.default &&
- slots.default({
- field: fieldRef.value,
- form: fieldRef.value.form,
- }),
- }
- )
+ }
+ const children = {
+ ...slots,
+ }
+ if (slots.default) {
+ children.default = () =>
+ slots.default({
+ field: field,
+ form: field.form,
+ })
+ }
+ return h(ReactiveField, componentData, children)
+ }
},
}) as unknown as DefineComponent
)
diff --git a/packages/vue/src/components/ReactiveField.ts b/packages/vue/src/components/ReactiveField.ts
index 23eac422e76..376fcde5aa8 100644
--- a/packages/vue/src/components/ReactiveField.ts
+++ b/packages/vue/src/components/ReactiveField.ts
@@ -3,6 +3,7 @@ import { defineComponent, DefineComponent } from 'vue-demi'
import { isVoidField } from '@formily/core'
import { clone } from '@formily/shared'
import { observer } from '@formily/reactive-vue'
+import { toJS } from '@formily/reactive'
import h from '../shared/h'
import { Fragment } from '../shared/fragment'
@@ -111,22 +112,25 @@ export default observer(
? field.pattern === 'readOnly'
: undefined,
...originData,
- value: !isVoidField(field) ? field.value : undefined,
+ // toJS is used to avoid some render loop.
+ value: !isVoidField(field) ? toJS(field.value) : undefined,
}
const componentData = {
attrs: attrs,
on: events,
}
-
- return h(component, componentData, {
+ const children = {
...slots,
- default: () =>
- slots.default &&
+ }
+ if (slots.default) {
+ children.default = () =>
slots.default({
field: props.field,
form: props.field.form,
- }),
- })
+ })
+ }
+
+ return h(component, componentData, children)
}
children = renderDecorator([renderComponent()])
diff --git a/packages/vue/src/components/RecursionField.ts b/packages/vue/src/components/RecursionField.ts
index 6b52f2ee6da..598062fb62e 100644
--- a/packages/vue/src/components/RecursionField.ts
+++ b/packages/vue/src/components/RecursionField.ts
@@ -1,8 +1,9 @@
import {
inject,
provide,
+ watch,
defineComponent,
- computed,
+ shallowRef,
DefineComponent,
} from 'vue-demi'
import { isFn, isValid } from '@formily/shared'
@@ -56,20 +57,30 @@ const RecursionField = observer(
filterProperties: {},
},
setup(props: IRecursionFieldProps) {
- // const { track } = useObserver()
const parentRef = useField()
const options = inject(SchemaOptionsSymbol)
- const scope = inject(SchemaExpressionScopeSymbol)
- const schemaRef = computed(() => new Schema(props.schema))
- const fieldSchemaRef = computed(() =>
- schemaRef.value.compile?.({
+ const scopeRef = inject(SchemaExpressionScopeSymbol)
+ const createSchema = (schemaProp: IRecursionFieldProps['schema']) =>
+ new Schema(schemaProp)
+ const createFieldSchema = (schema: Schema) =>
+ schema.compile?.({
...options.scope,
- ...scope,
+ ...scopeRef.value,
})
- )
- const fieldPropsRef = computed(() =>
- schemaRef.value?.toFieldProps?.(options)
- )
+ const schemaRef = shallowRef(createSchema(props.schema))
+ const fieldSchemaRef = shallowRef(createFieldSchema(schemaRef.value))
+ watch([() => props.schema, scopeRef], () => {
+ schemaRef.value = createSchema(props.schema)
+ fieldSchemaRef.value = createFieldSchema(schemaRef.value)
+ })
+
+ const getPropsFromSchema = (schema: Schema) =>
+ schema?.toFieldProps?.(options)
+ const fieldPropsRef = shallowRef(getPropsFromSchema(fieldSchemaRef.value))
+ watch(fieldSchemaRef, () => {
+ fieldPropsRef.value = getPropsFromSchema(fieldSchemaRef.value)
+ })
+
const getBasePath = () => {
if (props.onlyRenderProperties) {
return props.basePath || parentRef?.value?.address.concat(props.name)
@@ -115,8 +126,10 @@ const RecursionField = observer(
}
)
- const slots = {
- default: () => [...children],
+ const slots: Record any> = {}
+
+ if (children.length > 0) {
+ slots.default = () => [...children]
}
const xContent = fieldSchemaRef.value['x-content']
@@ -192,7 +205,7 @@ const RecursionField = observer(
)
}
- const slots = {}
+ const slots: Record any> = {}
const xContent = fieldSchemaRef.value['x-content']
@@ -213,6 +226,23 @@ const RecursionField = observer(
})
}
+ if (typeof xContent === 'string') {
+ slots['default'] = () => [xContent]
+ } else if (isVueOptions(xContent) || typeof xContent === 'function') {
+ // is vue component or functional component
+ slots['default'] = () => [h(xContent, {}, {})]
+ } else if (xContent && typeof xContent === 'object') {
+ // for named slots
+ Object.keys(xContent).forEach((key) => {
+ const child = xContent[key]
+ if (typeof child === 'string') {
+ slots[key] = () => [child]
+ } else if (isVueOptions(child) || typeof child === 'function') {
+ slots[key] = () => [h(child, {}, {})]
+ }
+ })
+ }
+
return h(
Field,
{
diff --git a/packages/vue/src/components/SchemaField.ts b/packages/vue/src/components/SchemaField.ts
index b3b464c7ff9..a8d744040a7 100644
--- a/packages/vue/src/components/SchemaField.ts
+++ b/packages/vue/src/components/SchemaField.ts
@@ -248,9 +248,11 @@ export function createSchemaField<
})
)
+ const scopeRef = computed(() => props.scope)
+
provide(SchemaMarkupSymbol, schemaRef)
provide(SchemaOptionsSymbol, options)
- provide(SchemaExpressionScopeSymbol, props.scope)
+ provide(SchemaExpressionScopeSymbol, scopeRef)
return () => {
env.nonameId = 0
@@ -301,23 +303,17 @@ export function createSchemaField<
>({
name: 'MarkupField',
props: Object.assign({}, markupProps, { type: String }),
- setup(
- props: ISchemaMarkupFieldProps<
- Components,
- ComponentPath,
- ComponentPath
- >,
- { slots }
- ) {
+ setup(props, { slots }) {
const parentRef = inject(SchemaMarkupSymbol, null)
if (!parentRef || !parentRef.value) return () => h(Fragment, {}, {})
+ const resolvedProps = resolveSchemaProps(props)
const name = props.name || getRandomName()
const appendArraySchema = (schema: ISchema) => {
if (parentRef.value.items) {
return parentRef.value.addProperty(name, schema)
} else {
- return parentRef.value.setItems(resolveSchemaProps(props))
+ return parentRef.value.setItems(resolvedProps)
}
}
@@ -330,12 +326,9 @@ export function createSchemaField<
parentRef.value.type === 'object' ||
parentRef.value.type === 'void'
) {
- schemaRef.value = parentRef.value.addProperty(
- name,
- resolveSchemaProps(props)
- )
+ schemaRef.value = parentRef.value.addProperty(name, resolvedProps)
} else if (parentRef.value.type === 'array') {
- const schema = appendArraySchema(resolveSchemaProps(props))
+ const schema = appendArraySchema(resolvedProps)
schemaRef.value = Array.isArray(schema) ? schema[0] : schema
}
},
@@ -343,14 +336,13 @@ export function createSchemaField<
)
provide(SchemaMarkupSymbol, schemaRef)
- return () =>
- h(
- Fragment,
- {},
- {
- default: () => slots.default && slots.default(),
- }
- )
+ return () => {
+ const children: Record any> = {}
+ if (slots.default) {
+ children.default = () => slots.default()
+ }
+ return h(Fragment, {}, children)
+ }
},
})
diff --git a/packages/vue/src/components/VoidField.ts b/packages/vue/src/components/VoidField.ts
index 95988add283..22b5e5edb86 100644
--- a/packages/vue/src/components/VoidField.ts
+++ b/packages/vue/src/components/VoidField.ts
@@ -64,23 +64,24 @@ export default defineComponent>({
provide(FieldSymbol, fieldRef)
- return () =>
- h(
- ReactiveField,
- {
- props: {
- field: fieldRef.value,
- },
+ return () => {
+ const field = fieldRef.value
+ const componentData = {
+ props: {
+ field,
},
- {
- ...slots,
- default: () =>
- slots.default &&
- slots.default({
- field: fieldRef.value,
- form: fieldRef.value.form,
- }),
- }
- )
+ }
+ const children = {
+ ...slots,
+ }
+ if (slots.default) {
+ children.default = () =>
+ slots.default({
+ field: field,
+ form: field.form,
+ })
+ }
+ return h(ReactiveField, componentData, children)
+ }
},
}) as unknown as DefineComponent>
diff --git a/packages/vue/src/hooks/useAttach.ts b/packages/vue/src/hooks/useAttach.ts
index 8cff0f2ef86..2ff8121faf4 100644
--- a/packages/vue/src/hooks/useAttach.ts
+++ b/packages/vue/src/hooks/useAttach.ts
@@ -1,4 +1,4 @@
-import { Ref, shallowRef, watch } from 'vue-demi'
+import { onBeforeMount, onMounted, Ref, shallowRef, watch } from 'vue-demi'
interface IRecycleTarget {
onMount: () => void
@@ -10,23 +10,29 @@ export const useAttach = (
dependencies: Parameters[0]
): Ref => {
const oldTargetRef = shallowRef(null)
+ const target = creator()
+ oldTargetRef.value = target
- watch(
- dependencies,
- (cur, prev, onInvalidate) => {
- const target = creator()
- if (oldTargetRef.value && target !== oldTargetRef.value) {
- oldTargetRef.value.onUnmount()
- }
- oldTargetRef.value = target
- target.onMount()
+ onMounted(() => {
+ target.onMount()
+ })
- onInvalidate(() => {
- target.onUnmount()
- })
- },
- { immediate: true }
- )
+ onBeforeMount(() => {
+ oldTargetRef.value?.onUnmount()
+ })
+
+ watch(dependencies, (cur, prev, onInvalidate) => {
+ const target = creator()
+ if (oldTargetRef.value && target !== oldTargetRef.value) {
+ oldTargetRef.value.onUnmount()
+ }
+ oldTargetRef.value = target
+ target.onMount()
+
+ onInvalidate(() => {
+ oldTargetRef.value?.onUnmount()
+ })
+ })
return oldTargetRef
}
diff --git a/packages/vue/src/shared/context.ts b/packages/vue/src/shared/context.ts
index a0ab9f851b0..171e5666842 100644
--- a/packages/vue/src/shared/context.ts
+++ b/packages/vue/src/shared/context.ts
@@ -8,7 +8,8 @@ export const FieldSymbol: InjectionKey[> =
export const SchemaMarkupSymbol: InjectionKey][> =
Symbol('schemaMarkup')
export const SchemaSymbol: InjectionKey][> = Symbol('schema')
-export const SchemaExpressionScopeSymbol: InjectionKey =
- Symbol('schemaExpression')
+export const SchemaExpressionScopeSymbol: InjectionKey<
+ Ref>
+> = Symbol('schemaExpression')
export const SchemaOptionsSymbol: InjectionKey =
Symbol('schemaOptions')
diff --git a/packages/vue/src/utils/resolveSchemaProps.ts b/packages/vue/src/utils/resolveSchemaProps.ts
index ce6983e21f9..7c928a95c25 100644
--- a/packages/vue/src/utils/resolveSchemaProps.ts
+++ b/packages/vue/src/utils/resolveSchemaProps.ts
@@ -3,7 +3,7 @@ import { paramCase } from '@formily/shared'
export const resolveSchemaProps = (props: Record) => {
const newProps = {}
Object.keys(props).forEach((key) => {
- if (key.indexOf('x') === 0) {
+ if (key.indexOf('x') === 0 && key.indexOf('x-') === -1) {
newProps[paramCase(key)] = props[key]
} else {
newProps[key] = props[key]
diff --git a/yarn.lock b/yarn.lock
index cccab366c91..97ae2708e4a 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2382,7 +2382,7 @@
"@babel/runtime" "^7.12.5"
"@testing-library/dom" "^7.28.1"
-"@testing-library/vue@^5.6.1":
+"@testing-library/vue@^5.6.2":
version "5.6.2"
resolved "https://registry.yarnpkg.com/@testing-library/vue/-/vue-5.6.2.tgz#b6cf64e1781fc334e5ce38c64b7027e5971bc8b3"
integrity sha512-GcbKYmID7NMcpQllMRw+op/oUFA6dp4zzaYOz7fsv+lNKC1G4RQCjkBWo9vYRQyt40imbFSNYb7JgEZnPYvrXg==
@@ -3227,7 +3227,7 @@
dependencies:
lodash "^4.17.4"
-"@vue/test-utils@^1.1.0":
+"@vue/test-utils@^1.1.0", "@vue/test-utils@^1.2.0":
version "1.2.0"
resolved "https://registry.yarnpkg.com/@vue/test-utils/-/test-utils-1.2.0.tgz#3bc8c17ed549157275f0aec6b95da40887f7297f"
integrity sha512-poBTLqeJYNq1TXVhtVfnY8vELUVOFdJY8KZZoUuaAkIqPTWsxonU1M8nMWpZT+xEMrM+49+YcuEqtMHVD9Q9gw==
]