diff --git a/components/form/FormItem.jsx b/components/form/FormItem.jsx
index 4041f9d06..cff6fa92f 100644
--- a/components/form/FormItem.jsx
+++ b/components/form/FormItem.jsx
@@ -97,6 +97,9 @@ export default {
getChildAttr (prop) {
const child = this.getOnlyControl()
let data = {}
+ if (!child) {
+ return undefined
+ }
if (child.data) {
data = child.data
} else if (child.$vnode && child.$vnode.data) {
diff --git a/components/form/demo/coordinated.md b/components/form/demo/coordinated.md
new file mode 100644
index 000000000..f57276ca2
--- /dev/null
+++ b/components/form/demo/coordinated.md
@@ -0,0 +1,82 @@
+
+#### 表单联动
+使用 `setFieldsValue` 来动态设置其他控件的值。
+
+
+
+#### Coordinated Controls
+Use `setFieldsValue` to set other control's value programmaticly.
+
+
+```html
+
+```
+
+
+
diff --git a/components/form/demo/customized-form-controls.md b/components/form/demo/customized-form-controls.md
new file mode 100644
index 000000000..aec358d5c
--- /dev/null
+++ b/components/form/demo/customized-form-controls.md
@@ -0,0 +1,129 @@
+
+#### 自定义表单控件
+自定义或第三方的表单控件,也可以与 Form 组件一起使用。只要该组件遵循以下的约定:
+> * 提供受控属性 `value` 或其它与 [`valuePropName`](/ant-design/components/form-cn/#getFieldDecorator(id,-options)-参数) 的值同名的属性。
+> * 提供 `onChange` 事件或 [`trigger`](/ant-design/components/form-cn/#getFieldDecorator(id,-options)-参数) 的值同名的事件。
+> * 不能是函数式组件。
+
+
+
+#### Customized Form Controls
+Customized or third-party form controls can be used in Form, too. Controls must follow these conventions:
+> * It has a controlled property `value` or other name which is equal to the value of [`valuePropName`](/ant-design/components/form/#getFieldDecorator(id,-options)-parameters).
+> * It has event `onChange` or an event which name is equal to the value of [`trigger`](/ant-design/components/form/#getFieldDecorator(id,-options)-parameters).
+> * It must be a class component.
+
+
+```html
+
+```
+
+
+
diff --git a/components/form/demo/dynamic-form-item.md b/components/form/demo/dynamic-form-item.md
new file mode 100644
index 000000000..91d6a5f40
--- /dev/null
+++ b/components/form/demo/dynamic-form-item.md
@@ -0,0 +1,144 @@
+
+#### 动态增减表单项
+动态增加、减少表单项。
+
+
+
+#### Dynamic Form Item
+Add or remove form items dynamically.
+
+
+```html
+
+
+
+```
+
+
+
diff --git a/components/form/demo/dynamic-rule.md b/components/form/demo/dynamic-rule.md
new file mode 100644
index 000000000..38648fe7b
--- /dev/null
+++ b/components/form/demo/dynamic-rule.md
@@ -0,0 +1,94 @@
+
+#### 动态校验规则
+根据不同情况执行不同的校验规则。
+
+
+
+#### Dynamic Rules
+Perform different check rules according to different situations.
+
+
+```html
+
+```
+
+
+
diff --git a/components/form/demo/form-in-modal.md b/components/form/demo/form-in-modal.md
new file mode 100644
index 000000000..bade491cc
--- /dev/null
+++ b/components/form/demo/form-in-modal.md
@@ -0,0 +1,105 @@
+
+#### 弹出层中的新建表单
+当用户访问一个展示了某个列表的页面,想新建一项但又不想跳转页面时,可以用 Modal 弹出一个表单,用户填写必要信息后创建新的项。
+
+
+
+#### Form in Modal to Create
+When user visit a page with a list of items, and want to create a new item. The page can popup a form in Modal, then let user fill in the form to create an item.
+
+
+```html
+
+```
+
+
+
diff --git a/components/form/demo/global-state.md b/components/form/demo/global-state.md
new file mode 100644
index 000000000..b3d5a1f47
--- /dev/null
+++ b/components/form/demo/global-state.md
@@ -0,0 +1,92 @@
+
+#### 表单数据存储于上层组件
+通过使用 `onFieldsChange` 与 `mapPropsToFields`,可以把表单的数据存储到上层组件。
+**注意:**
+`mapPropsToFields` 里面返回的表单域数据必须使用 `Form.createFormField` 包装。
+上层组件传递的属性,必须在`Form.create({ props: ...})`的props中声明。
+
+
+
+#### Store Form Data into Upper Component
+We can store form data into upper component.
+**Note:**
+You must wrap field data with `Form.createFormField` in `mapPropsToFields`.
+The properties passed by the upper component must be declared in the props of `Form.create({ props: ...})`.
+
+
+```html
+
+
+```
+
+
+
diff --git a/components/form/demo/horizontal-login.md b/components/form/demo/horizontal-login.md
new file mode 100644
index 000000000..f24b1add9
--- /dev/null
+++ b/components/form/demo/horizontal-login.md
@@ -0,0 +1,82 @@
+
+#### 水平登录栏
+水平登录栏,常用在顶部导航栏中。
+
+
+
+#### Horizontal Login Form
+Horizontal login form is often used in navigation bar.
+
+
+```html
+
+```
+
+
+
diff --git a/components/form/demo/layout.md b/components/form/demo/layout.md
new file mode 100644
index 000000000..174c860f4
--- /dev/null
+++ b/components/form/demo/layout.md
@@ -0,0 +1,81 @@
+
+#### 表单布局
+表单有三种布局。
+
+
+
+#### Form Layout
+There are three layout for form: `horizontal`, `vertical`, `inline`.
+
+
+```html
+
+
+
+
+
+ Horizontal
+ Vertical
+ Inline
+
+
+
+
+
+
+
+
+
+ Submit
+
+
+
+
+
+
+```
+
+
+
diff --git a/components/form/demo/test.vue b/components/form/demo/test.vue
index decc789f7..026703bca 100644
--- a/components/form/demo/test.vue
+++ b/components/form/demo/test.vue
@@ -1,64 +1,67 @@
-
-
\ No newline at end of file
+
diff --git a/components/vc-form/src/createBaseForm.jsx b/components/vc-form/src/createBaseForm.jsx
index eacd387f4..107985c61 100644
--- a/components/vc-form/src/createBaseForm.jsx
+++ b/components/vc-form/src/createBaseForm.jsx
@@ -7,7 +7,7 @@ import createFieldsStore from './createFieldsStore'
import { cloneElement } from '../../_util/vnode'
import BaseMixin from '../../_util/BaseMixin'
import { getOptionProps, getEvents } from '../../_util/props-util'
-// import PropTypes from '../../_util/vue-types'
+import PropTypes from '../../_util/vue-types'
import {
argumentContainer,
@@ -34,17 +34,24 @@ function createBaseForm (option = {}, mixins = []) {
fieldMetaProp,
fieldDataProp,
formPropName = 'form',
- // @deprecated
- withRef,
+ props = {},
} = option
return function decorate (WrappedComponent) {
+ let formProps = {}
+ if (Array.isArray(props)) {
+ props.forEach((prop) => {
+ formProps[prop] = PropTypes.any
+ })
+ } else {
+ formProps = props
+ }
const Form = {
mixins: [BaseMixin, ...mixins],
- // props: {
- // hideRequiredMark: PropTypes.bool,
- // layout: PropTypes.string,
- // },
+ props: {
+ ...formProps,
+ wrappedComponentRef: PropTypes.func.def(() => {}),
+ },
data () {
const fields = mapPropsToFields && mapPropsToFields(this.$props)
this.fieldsStore = createFieldsStore(fields || {})
@@ -81,6 +88,9 @@ function createBaseForm (option = {}, mixins = []) {
deep: true,
},
},
+ mounted () {
+ this.wrappedComponentRef(this.$refs.WrappedComponent)
+ },
methods: {
onCollectCommon (name, action, args) {
const fieldMeta = this.fieldsStore.getFieldMeta(name)
@@ -554,17 +564,22 @@ function createBaseForm (option = {}, mixins = []) {
...props,
}),
on: $listeners,
- }
- if (withRef) {
- wrappedComponentProps.ref = 'wrappedComponent'
+ ref: 'WrappedComponent',
}
return
},
}
- if (!(WrappedComponent.props && formPropName in WrappedComponent.props)) {
- WrappedComponent.props = {
- ...WrappedComponent.props,
- [formPropName]: Object,
+ if (Array.isArray(WrappedComponent.props)) {
+ const newProps = {}
+ WrappedComponent.props.forEach((prop) => {
+ newProps[prop] = PropTypes.any
+ })
+ newProps[formPropName] = Object
+ WrappedComponent.props = newProps
+ } else {
+ WrappedComponent.props = WrappedComponent.props || {}
+ if (!(formPropName in WrappedComponent.props)) {
+ WrappedComponent.props[formPropName] = Object
}
}
return argumentContainer(Form, WrappedComponent)