From c9d3f7b79ce66f94cff23cff7bd7f7cac33b7a58 Mon Sep 17 00:00:00 2001 From: tangjinzhou <415800467@qq.com> Date: Sun, 27 Jan 2019 21:47:27 +0800 Subject: [PATCH] fix: formItem not update when a-form-item in child component #446 --- components/form/Form.jsx | 30 ++++++++++++++++++++++- components/form/FormItem.jsx | 6 +++++ components/vc-form/src/createBaseForm.jsx | 2 +- 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/components/form/Form.jsx b/components/form/Form.jsx index e278823f0..2c9030756 100755 --- a/components/form/Form.jsx +++ b/components/form/Form.jsx @@ -139,9 +139,31 @@ const Form = { createForm(context, options = {}) { return new Vue(Form.create({ ...options, templateContext: context })()); }, + created() { + this.formItemContexts = new Map(); + }, provide() { return { FormProps: this.$props, + // https://github.com/vueComponent/ant-design-vue/issues/446 + collectFormItemContext: + this.form && this.form.templateContext + ? (c, type = 'add') => { + const formItemContexts = this.formItemContexts; + const number = formItemContexts.get(c) || 0; + if (type === 'delete') { + if (number <= 1) { + formItemContexts.delete(c); + } else { + formItemContexts.set(c, number - 1); + } + } else { + if (c !== this.form.templateContext) { + formItemContexts.set(c, number + 1); + } + } + } + : () => {}, }; }, watch: { @@ -149,6 +171,13 @@ const Form = { this.$forceUpdate(); }, }, + beforeUpdate() { + this.formItemContexts.forEach((number, c) => { + if (c.$forceUpdate) { + c.$forceUpdate(); + } + }); + }, updated() { if (this.form && this.form.cleanUpUselessFields) { this.form.cleanUpUselessFields(); @@ -232,7 +261,6 @@ const Form = { /> ); } - return (
{$slots.default} diff --git a/components/form/FormItem.jsx b/components/form/FormItem.jsx index 4a972ebd0..ced703971 100644 --- a/components/form/FormItem.jsx +++ b/components/form/FormItem.jsx @@ -19,6 +19,7 @@ import BaseMixin from '../_util/BaseMixin'; import { cloneElement, cloneVNodes } from '../_util/vnode'; import Icon from '../icon'; +function noop(){} export const FormItemProps = { id: PropTypes.string, prefixCls: PropTypes.string, @@ -47,10 +48,15 @@ export default { inject: { FormProps: { default: {} }, decoratorFormProps: { default: {} }, + collectFormItemContext: { default: () => noop }, }, data() { + this.collectFormItemContext(this.$vnode.context); return { helpShow: false }; }, + beforeDestroy() { + this.collectFormItemContext(this.$vnode.context, 'delete'); + }, mounted() { warning( this.getControls(this.slotDefault, true).length <= 1, diff --git a/components/vc-form/src/createBaseForm.jsx b/components/vc-form/src/createBaseForm.jsx index 226b5b61d..3d9c916c4 100644 --- a/components/vc-form/src/createBaseForm.jsx +++ b/components/vc-form/src/createBaseForm.jsx @@ -56,7 +56,7 @@ function createBaseForm(option = {}, mixins = []) { data() { const fields = mapPropsToFields && mapPropsToFields(this.$props); this.fieldsStore = createFieldsStore(fields || {}); - + this.templateContext = templateContext; this.instances = {}; this.cachedBind = {}; this.clearedFieldMetaCache = {};