Skip to content

Commit

Permalink
fix(vue): fix FormConsumer not update correctly (#2888)
Browse files Browse the repository at this point in the history
  • Loading branch information
MisicDemone authored Mar 1, 2022
1 parent 3fae57e commit 4e39c08
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 32 deletions.
65 changes: 46 additions & 19 deletions packages/vue/src/__tests__/form.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import Vue from 'vue'
import { render, fireEvent } from '@testing-library/vue'
import { mount } from '@vue/test-utils'
import { createForm } from '@formily/core'
import {
FormProvider,
Expand Down Expand Up @@ -98,25 +99,23 @@ test('useParentForm', () => {
test('useInjectionCleaner', async () => {
const form = createForm()

const { getByTestId } = render(
defineComponent({
name: 'TestComponent',
setup() {
return {
form,
Input,
}
},
template: `<FormProvider :form="form">
<Field name="parent">
<FormProvider :form="form">
<Field name="inner" :component="[Input]" />
</FormProvider>
<Field name="outer" :component="[Input]" />
</Field>
</FormProvider>`,
})
)
const { getByTestId } = render({
name: 'TestComponent',
setup() {
return {
form,
Input,
}
},
template: `<FormProvider :form="form">
<Field name="parent">
<FormProvider :form="form">
<Field name="inner" :component="[Input]" />
</FormProvider>
<Field name="outer" :component="[Input]" />
</Field>
</FormProvider>`,
})
expect(form.mounted).toBeTruthy()
expect(form.query('inner').take().mounted).toBeTruthy()
expect(form.query('parent.outer').take().mounted).toBeTruthy()
Expand All @@ -125,3 +124,31 @@ test('useInjectionCleaner', async () => {
await fireEvent.update(getByTestId('inner'), '123')
expect(form.getValuesIn('inner')).toBe('123')
})

test('FormConsumer', async () => {
const form = createForm({
values: {
a: 'abc',
},
})
const wrapper = mount({
data() {
return { form, Input }
},
template: `<FormProvider :form="form">
<Field name="a" :component="[Input]" />
<FormConsumer ref="consumer">
<template #default="{ form }">
<div class="consumer">{{JSON.stringify(form.values)}}</div>
</template>
</FormConsumer>
</FormProvider>`,
})
expect(form.getValuesIn('a')).toBe('abc')
expect(wrapper.find('.consumer').text()).toBe('{"a":"abc"}')
form.setDisplay('none')
expect(form.getValuesIn('a')).toBeUndefined()
const $consumer = wrapper.vm.$refs.consumer as Vue
$consumer.$forceUpdate()
expect(wrapper.find('.consumer').text()).toBe('{}')
})
29 changes: 17 additions & 12 deletions packages/vue/src/components/FormConsumer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { defineComponent } from 'vue-demi'
import { observer } from '@formily/reactive-vue'
import { useForm } from '../hooks'
import h from '../shared/h'
import { Fragment } from '../shared/fragment'

export default observer(
defineComponent({
Expand All @@ -11,17 +10,23 @@ export default observer(
setup(props, { slots }) {
const formRef = useForm()
return () => {
const children = {
...slots,
}
if (slots.default) {
children.default = () =>
slots.default({
form: formRef.value,
})
}
return h(Fragment, {}, children)
// just like <Fragment>
return h(
'div',
{ style: { display: 'contents' } },
{
default: () =>
slots.default?.({
form: formRef.value,
}),
}
)
}
},
})
}),
{
// make sure observables updated <cannot be tracked by tests>
scheduler: /* istanbul ignore next */ (update) =>
Promise.resolve().then(update),
}
)
3 changes: 2 additions & 1 deletion packages/vue/src/vue2-components.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// This file just converts types
import * as components from './components'

import type Vue from 'vue'
Expand Down Expand Up @@ -61,7 +62,7 @@ const VoidField = _VoidField as unknown as DefineComponent<
const RecursionField = _RecursionField as unknown as DefineComponent<
Omit<IRecursionFieldProps, 'name'>
>
const FormConsumer = _FormConsumer as unknown as Vue
const FormConsumer = _FormConsumer as unknown as DefineComponent<{}>
const FormProvider = _FormProvider as unknown as DefineComponent<IProviderProps>
const createSchemaField = _createSchemaField as unknown as CreateSchemaField

Expand Down

0 comments on commit 4e39c08

Please sign in to comment.