|
1 | 1 | import intersperse from 'intersperse' |
2 | 2 | import PropTypes from '../_util/vue-types' |
3 | 3 | import classNames from 'classnames' |
| 4 | +import find from 'lodash/find' |
4 | 5 | import Row from '../grid/Row' |
5 | 6 | import Col, { ColProps } from '../grid/Col' |
6 | 7 | import warning from '../_util/warning' |
7 | 8 | import { FIELD_META_PROP, FIELD_DATA_PROP } from './constants' |
8 | | -import { initDefaultProps, getComponentFromProp, filterEmpty, getSlotOptions, getSlots, isValidElement } from '../_util/props-util' |
| 9 | +import { initDefaultProps, getComponentFromProp, filterEmpty, getSlotOptions, isValidElement, getSlots, getAllChildren } from '../_util/props-util' |
9 | 10 | import getTransitionProps from '../_util/getTransitionProps' |
10 | 11 | import BaseMixin from '../_util/BaseMixin' |
11 | | -import { cloneElement } from '../_util/vnode' |
| 12 | +import { cloneElement, cloneVNodes } from '../_util/vnode' |
12 | 13 | export const FormItemProps = { |
13 | 14 | id: PropTypes.string, |
14 | 15 | prefixCls: PropTypes.string, |
@@ -47,6 +48,10 @@ export default { |
47 | 48 | '`Form.Item` cannot generate `validateStatus` and `help` automatically, ' + |
48 | 49 | 'while there are more than one `getFieldDecorator` in it.', |
49 | 50 | ) |
| 51 | + warning( |
| 52 | + !this.fieldDecoratorId, |
| 53 | + '`fieldDecoratorId` is deprecated. please use `v-decorator={id, options}` instead.' |
| 54 | + ) |
50 | 55 | }, |
51 | 56 | methods: { |
52 | 57 | getHelpMessage () { |
@@ -81,15 +86,12 @@ export default { |
81 | 86 | if (getSlotOptions(child).__ANT_FORM_ITEM) { |
82 | 87 | continue |
83 | 88 | } |
84 | | - const attrs = child.data && child.data.attrs |
85 | | - if (!attrs) { |
86 | | - continue |
87 | | - } |
88 | | - const slots = getSlots(child) |
| 89 | + const children = getAllChildren(child) |
| 90 | + const attrs = child.data && child.data.attrs || {} |
89 | 91 | if (FIELD_META_PROP in attrs) { // And means FIELD_DATA_PROP in child.props, too. |
90 | 92 | controls.push(child) |
91 | | - } else if (slots.default) { |
92 | | - controls = controls.concat(this.getControls(slots.default, recursively)) |
| 93 | + } else if (children) { |
| 94 | + controls = controls.concat(this.getControls(children, recursively)) |
93 | 95 | } |
94 | 96 | } |
95 | 97 | return controls |
@@ -339,21 +341,54 @@ export default { |
339 | 341 | </Row> |
340 | 342 | ) |
341 | 343 | }, |
| 344 | + decoratorOption (vnode) { |
| 345 | + if (vnode.data && vnode.data.directives) { |
| 346 | + const directive = find(vnode.data.directives, ['name', 'decorator']) |
| 347 | + warning( |
| 348 | + !directive || (directive && Array.isArray(directive.value)), |
| 349 | + `Invalid directive: type check failed for directive "decorator". Expected Array, got ${typeof directive.value}. At ${vnode.tag}.`, |
| 350 | + ) |
| 351 | + return directive ? directive.value : null |
| 352 | + } else { |
| 353 | + return null |
| 354 | + } |
| 355 | + }, |
| 356 | + decoratorChildren (vnodes) { |
| 357 | + const { FormProps } = this |
| 358 | + const getFieldDecorator = FormProps.form.getFieldDecorator |
| 359 | + vnodes.forEach((vnode, index) => { |
| 360 | + if (vnode.children) { |
| 361 | + vnode.children = this.decoratorChildren(cloneVNodes(vnode.children)) |
| 362 | + } else if (vnode.componentOptions && vnode.componentOptions.children) { |
| 363 | + vnode.componentOptions.children = this.decoratorChildren(cloneVNodes(vnode.componentOptions.children)) |
| 364 | + } |
| 365 | + const option = this.decoratorOption(vnode) |
| 366 | + if (option && option[0]) { |
| 367 | + vnodes[index] = getFieldDecorator(option[0], option[1])(vnode) |
| 368 | + } |
| 369 | + }) |
| 370 | + return vnodes |
| 371 | + }, |
342 | 372 | }, |
343 | 373 |
|
344 | 374 | render () { |
345 | | - const { $slots, decoratorFormProps, fieldDecoratorId, fieldDecoratorOptions = {}} = this |
346 | | - const child = filterEmpty($slots.default || []) |
| 375 | + const { $slots, decoratorFormProps, fieldDecoratorId, fieldDecoratorOptions = {}, FormProps } = this |
| 376 | + let child = filterEmpty($slots.default || []) |
347 | 377 | if (decoratorFormProps.form && fieldDecoratorId && child.length) { |
348 | 378 | const getFieldDecorator = decoratorFormProps.form.getFieldDecorator |
349 | 379 | child[0] = getFieldDecorator(fieldDecoratorId, fieldDecoratorOptions)(child[0]) |
350 | 380 | warning( |
351 | 381 | !(child.length > 1), |
352 | 382 | '`autoFormCreate` just `decorator` then first children. but you can use JSX to support multiple children', |
353 | 383 | ) |
| 384 | + this.slotDefault = child |
| 385 | + } else if (FormProps.form) { |
| 386 | + child = cloneVNodes(child) |
| 387 | + this.slotDefault = this.decoratorChildren(child) |
| 388 | + } else { |
| 389 | + this.slotDefault = child |
354 | 390 | } |
355 | 391 |
|
356 | | - this.slotDefault = child |
357 | 392 | const children = this.renderChildren() |
358 | 393 | return this.renderFormItem(children) |
359 | 394 | }, |
|
0 commit comments