diff --git a/.eslintrc b/.eslintrc index e12a6e611..d83133fcf 100644 --- a/.eslintrc +++ b/.eslintrc @@ -12,6 +12,7 @@ "comma-dangle": [2, "always-multiline"], "no-var": "error", "no-unused-vars": "warn", - "camelcase": "off" + "camelcase": "off", + "no-extra-boolean-cast": "off" } -} \ No newline at end of file +} diff --git a/CHANGELOG.en-US.md b/CHANGELOG.en-US.md index ce74f0657..fc095d189 100644 --- a/CHANGELOG.en-US.md +++ b/CHANGELOG.en-US.md @@ -2,6 +2,33 @@ --- +## 1.1.10 + +`2018-12-7` +- 🔥🔥🔥 In the 1.1.10 version, the `Form` component better supports the single-file tempalte syntax. In previous versions, complex component requirements were required to be implemented using JSX. In order to better use the automatic collection and validation of Form forms in the template, we have optimized the way components are used. All Demo files are refactored using the latest syntax. +However, for the previous API, continue to support, you can not worry about the API changes, resulting in problems in the existing system. +````html + + +```` +- 🐞 Fix `Steps` component `labelPlacement` does not work [#281](https://github.com/vueComponent/ant-design-vue/issues/281) +- 🐞 Fix the `Timeline` component style problem, add `reverse` `mode` props [#8e37cd](https://github.com/vueComponent/ant-design-vue/commit/8e37cd89f92ee2541f641fd860785cfd2361b2b3) +- `Tree` + - 🐞 Fix `treeDefaultExpandedKeys` does not work [#284](https://github.com/vueComponent/ant-design-vue/issues/284) + - 🐞 Fixes the component not update when other array attributes such as `expandedKeys` `selectedKeys` changed by array’s mutation methods. [#239](https://github.com/vueComponent/ant-design-vue/issues/239) + ## 1.1.9 `2018-11-26` diff --git a/CHANGELOG.zh-CN.md b/CHANGELOG.zh-CN.md index a6ce15043..b49d7f92a 100644 --- a/CHANGELOG.zh-CN.md +++ b/CHANGELOG.zh-CN.md @@ -1,5 +1,35 @@ # 更新日志 +--- + +## 1.1.10 + +`2018-12-7` +- 🔥🔥🔥 在1.1.10版本中`Form`组件更好地支持单文件tempalte语法,在以往版本中,对于复杂的组件需求,需要使用JSX才可以实现。为了更好地在template中使用Form表单的自动收集校验功能,我们优化了组件的使用方式。文档全部Demo使用最新语法重构。 +不过对于以往API,还是继续支持,你可以不用担心API的改变,导致已有系统出现问题。 +````html + + +```` +- 🐞 修复`Steps`组件`labelPlacement`不生效问题 [#281](https://github.com/vueComponent/ant-design-vue/issues/281) +- 🐞 修复`Timeline`组件样式问题,添加`reverse` `mode`属性 [#8e37cd](https://github.com/vueComponent/ant-design-vue/commit/8e37cd89f92ee2541f641fd860785cfd2361b2b3) +- `Tree` + - 🐞 修复`treeDefaultExpandedKeys`不生效问题 [#284](https://github.com/vueComponent/ant-design-vue/issues/284) + - 🐞 修复`expandedKeys` `selectedKeys`等其它数组属性通过组件变异方法改变时组件不更新问题 [#239](https://github.com/vueComponent/ant-design-vue/issues/239) + + --- ## 1.1.9 diff --git a/components/_util/FormDecoratorDirective.js b/components/_util/FormDecoratorDirective.js new file mode 100644 index 000000000..1fc7ecf23 --- /dev/null +++ b/components/_util/FormDecoratorDirective.js @@ -0,0 +1,7 @@ +export default { + // just for tag + install: (Vue, options) => { + Vue.directive('decorator', { + }) + }, +} diff --git a/components/_util/props-util.js b/components/_util/props-util.js index ca17fae78..9bb66df42 100644 --- a/components/_util/props-util.js +++ b/components/_util/props-util.js @@ -49,7 +49,7 @@ const getSlots = (ele) => { if (ele.$vnode) { componentOptions = ele.$vnode.componentOptions || {} } - const children = componentOptions.children || [] + const children = ele.children || componentOptions.children || [] const slots = {} children.forEach(child => { const name = (child.data && child.data.slot) || 'default' @@ -58,6 +58,13 @@ const getSlots = (ele) => { }) return slots } +const getAllChildren = (ele) => { + let componentOptions = ele.componentOptions || {} + if (ele.$vnode) { + componentOptions = ele.$vnode.componentOptions || {} + } + return ele.children || componentOptions.children || [] +} const getSlotOptions = (ele) => { if (ele.fnOptions) { // 函数式组件 return ele.fnOptions @@ -258,5 +265,6 @@ export { camelize, getSlots, getAllProps, + getAllChildren, } export default hasProp diff --git a/components/form/Form.jsx b/components/form/Form.jsx index e2e44833e..bf27ecc96 100755 --- a/components/form/Form.jsx +++ b/components/form/Form.jsx @@ -1,6 +1,8 @@ import PropTypes from '../_util/vue-types' import classNames from 'classnames' +import Vue from 'vue' import isRegExp from 'lodash/isRegExp' +import warning from '../_util/warning' import createDOMForm from '../vc-form/src/createDOMForm' import createFormField from '../vc-form/src/createFormField' import FormItem from './FormItem' @@ -54,7 +56,7 @@ export const WrappedFormUtils = { export const FormProps = { layout: PropTypes.oneOf(['horizontal', 'inline', 'vertical']), - form: PropTypes.shape(WrappedFormUtils).loose, + form: PropTypes.object, // onSubmit: React.FormEventHandler; prefixCls: PropTypes.string, hideRequiredMark: PropTypes.bool, @@ -110,29 +112,13 @@ export const ValidationRule = { // validateFirst?: boolean; // }; -export default { +const Form = { name: 'AForm', props: initDefaultProps(FormProps, { prefixCls: 'ant-form', layout: 'horizontal', hideRequiredMark: false, }), - // static defaultProps = { - // prefixCls: 'ant-form', - // layout: 'horizontal', - // hideRequiredMark: false, - // onSubmit (e) { - // e.preventDefault() - // }, - // }; - - // static propTypes = { - // prefixCls: PropTypes.string, - // layout: PropTypes.oneOf(['horizontal', 'inline', 'vertical']), - // children: PropTypes.any, - // onSubmit: PropTypes.func, - // hideRequiredMark: PropTypes.bool, - // }; Item: FormItem, @@ -146,11 +132,19 @@ export default { fieldDataProp: FIELD_DATA_PROP, }) }, + createForm (context, options = {}) { + return new Vue(Form.create({ ...options, templateContext: context })()) + }, provide () { return { FormProps: this.$props, } }, + watch: { + form () { + this.$forceUpdate() + }, + }, methods: { onSubmit (e) { const { $listeners } = this @@ -174,6 +168,10 @@ export default { [`${prefixCls}-hide-required-mark`]: hideRequiredMark, }) if (autoFormCreate) { + warning( + false, + '`autoFormCreate` is deprecated. please use `form` instead.' + ) const DomForm = this.DomForm || createDOMForm({ fieldNameProp: 'id', ...options, @@ -214,3 +212,5 @@ export default { return
{$slots.default}
}, } + +export default Form diff --git a/components/form/FormItem.jsx b/components/form/FormItem.jsx index adc20f6c2..dd7e1bca8 100644 --- a/components/form/FormItem.jsx +++ b/components/form/FormItem.jsx @@ -1,14 +1,15 @@ import intersperse from 'intersperse' import PropTypes from '../_util/vue-types' import classNames from 'classnames' +import find from 'lodash/find' import Row from '../grid/Row' import Col, { ColProps } from '../grid/Col' import warning from '../_util/warning' import { FIELD_META_PROP, FIELD_DATA_PROP } from './constants' -import { initDefaultProps, getComponentFromProp, filterEmpty, getSlotOptions, getSlots, isValidElement } from '../_util/props-util' +import { initDefaultProps, getComponentFromProp, filterEmpty, getSlotOptions, isValidElement, getSlots, getAllChildren } from '../_util/props-util' import getTransitionProps from '../_util/getTransitionProps' import BaseMixin from '../_util/BaseMixin' -import { cloneElement } from '../_util/vnode' +import { cloneElement, cloneVNodes } from '../_util/vnode' export const FormItemProps = { id: PropTypes.string, prefixCls: PropTypes.string, @@ -47,6 +48,10 @@ export default { '`Form.Item` cannot generate `validateStatus` and `help` automatically, ' + 'while there are more than one `getFieldDecorator` in it.', ) + warning( + !this.fieldDecoratorId, + '`fieldDecoratorId` is deprecated. please use `v-decorator={id, options}` instead.' + ) }, methods: { getHelpMessage () { @@ -81,15 +86,12 @@ export default { if (getSlotOptions(child).__ANT_FORM_ITEM) { continue } - const attrs = child.data && child.data.attrs - if (!attrs) { - continue - } - const slots = getSlots(child) + const children = getAllChildren(child) + const attrs = child.data && child.data.attrs || {} if (FIELD_META_PROP in attrs) { // And means FIELD_DATA_PROP in child.props, too. controls.push(child) - } else if (slots.default) { - controls = controls.concat(this.getControls(slots.default, recursively)) + } else if (children) { + controls = controls.concat(this.getControls(children, recursively)) } } return controls @@ -339,11 +341,39 @@ export default { ) }, + decoratorOption (vnode) { + if (vnode.data && vnode.data.directives) { + const directive = find(vnode.data.directives, ['name', 'decorator']) + warning( + !directive || (directive && Array.isArray(directive.value)), + `Invalid directive: type check failed for directive "decorator". Expected Array, got ${typeof directive.value}. At ${vnode.tag}.`, + ) + return directive ? directive.value : null + } else { + return null + } + }, + decoratorChildren (vnodes) { + const { FormProps } = this + const getFieldDecorator = FormProps.form.getFieldDecorator + vnodes.forEach((vnode, index) => { + if (vnode.children) { + vnode.children = this.decoratorChildren(cloneVNodes(vnode.children)) + } else if (vnode.componentOptions && vnode.componentOptions.children) { + vnode.componentOptions.children = this.decoratorChildren(cloneVNodes(vnode.componentOptions.children)) + } + const option = this.decoratorOption(vnode) + if (option && option[0]) { + vnodes[index] = getFieldDecorator(option[0], option[1])(vnode) + } + }) + return vnodes + }, }, render () { - const { $slots, decoratorFormProps, fieldDecoratorId, fieldDecoratorOptions = {}} = this - const child = filterEmpty($slots.default || []) + const { $slots, decoratorFormProps, fieldDecoratorId, fieldDecoratorOptions = {}, FormProps } = this + let child = filterEmpty($slots.default || []) if (decoratorFormProps.form && fieldDecoratorId && child.length) { const getFieldDecorator = decoratorFormProps.form.getFieldDecorator child[0] = getFieldDecorator(fieldDecoratorId, fieldDecoratorOptions)(child[0]) @@ -351,9 +381,14 @@ export default { !(child.length > 1), '`autoFormCreate` just `decorator` then first children. but you can use JSX to support multiple children', ) + this.slotDefault = child + } else if (FormProps.form) { + child = cloneVNodes(child) + this.slotDefault = this.decoratorChildren(child) + } else { + this.slotDefault = child } - this.slotDefault = child const children = this.renderChildren() return this.renderFormItem(children) }, diff --git a/components/form/__tests__/__snapshots__/demo.test.js.snap b/components/form/__tests__/__snapshots__/demo.test.js.snap index 5dfd328f9..d2708d096 100644 --- a/components/form/__tests__/__snapshots__/demo.test.js.snap +++ b/components/form/__tests__/__snapshots__/demo.test.js.snap @@ -2,18 +2,8 @@ exports[`renders ./components/form/demo/advanced-search.vue correctly 1`] = `