|
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