Merge branch 'master' into feat-3.10.3
# Conflicts: # components/form/__tests__/__snapshots__/demo.test.js.snap # components/timeline/__tests__/__snapshots__/demo.test.js.snappull/309/head
commit
7aa46bbdf8
|
@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
<template>
|
||||
<a-form :form="form">
|
||||
<a-form-item>
|
||||
<a-input v-decorator="[id, options]">
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
beforeCreate () {
|
||||
this.form = this.$form.createForm(this, options)
|
||||
},
|
||||
}
|
||||
</script>
|
||||
````
|
||||
- ๐ 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`
|
||||
|
|
|
@ -1,5 +1,35 @@
|
|||
# ๆดๆฐๆฅๅฟ
|
||||
|
||||
---
|
||||
|
||||
## 1.1.10
|
||||
|
||||
`2018-12-7`
|
||||
- ๐ฅ๐ฅ๐ฅ ๅจ1.1.10็ๆฌไธญ`Form`็ปไปถๆดๅฅฝๅฐๆฏๆๅๆไปถtempalte่ฏญๆณ๏ผๅจไปฅๅพ็ๆฌไธญ๏ผๅฏนไบๅคๆ็็ปไปถ้ๆฑ๏ผ้่ฆไฝฟ็จJSXๆๅฏไปฅๅฎ็ฐใไธบไบๆดๅฅฝๅฐๅจtemplateไธญไฝฟ็จForm่กจๅ็่ชๅจๆถ้ๆ ก้ชๅ่ฝ๏ผๆไปฌไผๅไบ็ปไปถ็ไฝฟ็จๆนๅผใๆๆกฃๅ
จ้จDemoไฝฟ็จๆๆฐ่ฏญๆณ้ๆใ
|
||||
ไธ่ฟๅฏนไบไปฅๅพAPI๏ผ่ฟๆฏ็ปง็ปญๆฏๆ๏ผไฝ ๅฏไปฅไธ็จๆ
ๅฟAPI็ๆนๅ๏ผๅฏผ่ดๅทฒๆ็ณป็ปๅบ็ฐ้ฎ้ขใ
|
||||
````html
|
||||
<template>
|
||||
<a-form :form="form">
|
||||
<a-form-item>
|
||||
<a-input v-decorator="[id, options]">
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
beforeCreate () {
|
||||
this.form = this.$form.createForm(this, options)
|
||||
},
|
||||
}
|
||||
</script>
|
||||
````
|
||||
- ๐ ไฟฎๅค`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
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
export default {
|
||||
// just for tag
|
||||
install: (Vue, options) => {
|
||||
Vue.directive('decorator', {
|
||||
})
|
||||
},
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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<any>;
|
||||
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 <form onSubmit={onSubmit} class={formClassName}>{$slots.default}</form>
|
||||
},
|
||||
}
|
||||
|
||||
export default Form
|
||||
|
|
|
@ -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 {
|
|||
</Row>
|
||||
)
|
||||
},
|
||||
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)
|
||||
},
|
||||
|
|
|
@ -2,18 +2,8 @@
|
|||
|
||||
exports[`renders ./components/form/demo/advanced-search.vue correctly 1`] = `
|
||||
<div id="components-form-demo-advanced-search">
|
||||
<form class="ant-form ant-form-horizontal ant-advanced-search-form">
|
||||
<form class="ant-advanced-search-form ant-form ant-form-horizontal">
|
||||
<div class="ant-row" style="margin-left: -12px; margin-right: -12px;">
|
||||
<div class="ant-col-8" style="display: block; padding-left: 12px; padding-right: 12px;">
|
||||
<div class="ant-row ant-form-item">
|
||||
<div class="ant-form-item-label"><label for="field-0" title="Field 0" class="ant-form-item-required">Field 0</label></div>
|
||||
<div class="ant-form-item-control-wrapper">
|
||||
<div class="ant-form-item-control"><span class="ant-form-item-children"><input placeholder="placeholder" type="text" data-__meta="[object Object]" data-__field="[object Object]" id="field-0" class="ant-input"></span>
|
||||
<!---->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ant-col-8" style="display: block; padding-left: 12px; padding-right: 12px;">
|
||||
<div class="ant-row ant-form-item">
|
||||
<div class="ant-form-item-label"><label for="field-1" title="Field 1" class="ant-form-item-required">Field 1</label></div>
|
||||
|
@ -64,7 +54,7 @@ exports[`renders ./components/form/demo/advanced-search.vue correctly 1`] = `
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ant-col-8" style="display: none; padding-left: 12px; padding-right: 12px;">
|
||||
<div class="ant-col-8" style="display: block; padding-left: 12px; padding-right: 12px;">
|
||||
<div class="ant-row ant-form-item">
|
||||
<div class="ant-form-item-label"><label for="field-6" title="Field 6" class="ant-form-item-required">Field 6</label></div>
|
||||
<div class="ant-form-item-control-wrapper">
|
||||
|
@ -104,11 +94,20 @@ exports[`renders ./components/form/demo/advanced-search.vue correctly 1`] = `
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ant-col-8" style="display: none; padding-left: 12px; padding-right: 12px;">
|
||||
<div class="ant-row ant-form-item">
|
||||
<div class="ant-form-item-label"><label for="field-10" title="Field 10" class="ant-form-item-required">Field 10</label></div>
|
||||
<div class="ant-form-item-control-wrapper">
|
||||
<div class="ant-form-item-control"><span class="ant-form-item-children"><input placeholder="placeholder" type="text" data-__meta="[object Object]" data-__field="[object Object]" id="field-10" class="ant-input"></span>
|
||||
<!---->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ant-row">
|
||||
<div class="ant-col-24" style="text-align: right;"><button type="submit" class="ant-btn ant-btn-primary"><span>Search</span></button><button type="button" class="ant-btn ant-btn-default" style="margin-left: 8px;"><span>Clear</span></button><a style="margin-left: 8px; font-size: 12px;">Collapse <i class="anticon anticon-down"><svg viewBox="64 64 896 896" data-icon="down" width="1em" height="1em" fill="currentColor" aria-hidden="true" class="">
|
||||
<path d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"></path>
|
||||
</svg></i></a></div>
|
||||
<div class="ant-col-24" style="text-align: right;"><button type="submit" class="ant-btn ant-btn-primary"><span>Search</span></button> <button type="button" class="ant-btn ant-btn-default" style="margin-left: 8px;"><span>Clear</span></button> <a style="margin-left: 8px; font-size: 12px;">
|
||||
Collapse <i class="anticon anticon-down"></i></a></div>
|
||||
</div>
|
||||
</form>
|
||||
<div class="search-result-list">Search Result List</div>
|
||||
|
@ -223,26 +222,18 @@ exports[`renders ./components/form/demo/dynamic-rule.vue correctly 1`] = `
|
|||
|
||||
exports[`renders ./components/form/demo/form-in-modal.vue correctly 1`] = `
|
||||
<div><button type="button" class="ant-btn ant-btn-primary"><span>New Collection</span></button>
|
||||
<!---->
|
||||
<!--function (a, b, c, d) { return createElement(vm, a, b, c, d, true); }-->
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/form/demo/global-state.vue correctly 1`] = `
|
||||
<div id="components-form-demo-global-state">
|
||||
<form class="ant-form ant-form-inline">
|
||||
<div class="ant-row ant-form-item">
|
||||
<div class="ant-form-item-label"><label for="username" title="Username" class="ant-form-item-required">Username</label></div>
|
||||
<div class="ant-form-item-control-wrapper">
|
||||
<div class="ant-form-item-control has-success"><span class="ant-form-item-children"><input value="benjycui" type="text" data-__meta="[object Object]" data-__field="[object Object]" id="username" class="ant-input"></span>
|
||||
<!---->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form><pre class="language-bash">{
|
||||
<!--function (a, b, c, d) { return createElement(vm, a, b, c, d, true); }--> <pre class="language-bash"> {
|
||||
"username": {
|
||||
"value": "benjycui"
|
||||
}
|
||||
}</pre>
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
`;
|
||||
|
||||
|
@ -311,7 +302,7 @@ exports[`renders ./components/form/demo/layout.vue correctly 1`] = `
|
|||
`;
|
||||
|
||||
exports[`renders ./components/form/demo/normal-login.vue correctly 1`] = `
|
||||
<form class="ant-form ant-form-horizontal login-form" id="components-form-demo-normal-login">
|
||||
<form class="login-form ant-form ant-form-horizontal" id="components-form-demo-normal-login">
|
||||
<div class="ant-row ant-form-item">
|
||||
<div class="ant-form-item-control-wrapper">
|
||||
<div class="ant-form-item-control"><span class="ant-form-item-children"><span class="ant-input-affix-wrapper"><span class="ant-input-prefix"><i class="anticon anticon-user"><svg viewBox="64 64 896 896" data-icon="user" width="1em" height="1em" fill="currentColor" aria-hidden="true" class=""><path d="M858.5 763.6a374 374 0 0 0-80.6-119.5 375.63 375.63 0 0 0-119.5-80.6c-.4-.2-.8-.3-1.2-.5C719.5 518 760 444.7 760 362c0-137-111-248-248-248S264 225 264 362c0 82.7 40.5 156 102.8 201.1-.4.2-.8.3-1.2.5-44.8 18.9-85 46-119.5 80.6a375.63 375.63 0 0 0-80.6 119.5A371.7 371.7 0 0 0 136 901.8a8 8 0 0 0 8 8.2h60c4.4 0 7.9-3.5 8-7.8 2-77.2 33-149.5 87.8-204.3 56.7-56.7 132-87.9 212.2-87.9s155.5 31.2 212.2 87.9C779 752.7 810 825 812 902.2c.1 4.4 3.6 7.8 8 7.8h60a8 8 0 0 0 8-8.2c-1-47.8-10.9-94.3-29.5-138.2zM512 534c-45.9 0-89.1-17.9-121.6-50.4S340 407.9 340 362c0-45.9 17.9-89.1 50.4-121.6S466.1 190 512 190s89.1 17.9 121.6 50.4S684 316.1 684 362c0 45.9-17.9 89.1-50.4 121.6S557.9 534 512 534z"></path></svg></i></span><input placeholder="Username" type="text" data-__meta="[object Object]" data-__field="[object Object]" id="userName" class="ant-input"></span></span>
|
||||
|
@ -328,7 +319,10 @@ exports[`renders ./components/form/demo/normal-login.vue correctly 1`] = `
|
|||
</div>
|
||||
<div class="ant-row ant-form-item">
|
||||
<div class="ant-form-item-control-wrapper">
|
||||
<div class="ant-form-item-control has-success"><span class="ant-form-item-children"><label class="ant-checkbox-wrapper"><span class="ant-checkbox ant-checkbox-checked"><input id="remember" type="checkbox" class="ant-checkbox-input" value=""><span class="ant-checkbox-inner"></span></span><span>Remember me</span></label><a href="" class="login-form-forgot">Forgot password</a><button type="submit" class="ant-btn ant-btn-primary login-form-button"><span>Log in</span></button>Or <a href="">register now!</a></span>
|
||||
<div class="ant-form-item-control has-success"><span class="ant-form-item-children"><label class="ant-checkbox-wrapper"><span class="ant-checkbox ant-checkbox-checked"><input id="remember" type="checkbox" class="ant-checkbox-input" value=""><span class="ant-checkbox-inner"></span></span><span>
|
||||
Remember me
|
||||
</span></label><a href="" class="login-form-forgot">Forgot password</a><button type="submit" class="login-form-button ant-btn ant-btn-primary"><span>Log in</span></button>
|
||||
Or <a href="">register now!</a></span>
|
||||
<!---->
|
||||
</div>
|
||||
</div>
|
||||
|
@ -585,7 +579,7 @@ exports[`renders ./components/form/demo/validate-other.vue correctly 1`] = `
|
|||
</div>
|
||||
</div>
|
||||
<div class="ant-row ant-form-item">
|
||||
<div class="ant-col-6 ant-form-item-label"><label title="Dragger" class="">Dragger</label></div>
|
||||
<div class="ant-col-6 ant-form-item-label"><label for="dragger" title="Dragger" class="">Dragger</label></div>
|
||||
<div class="ant-col-14 ant-form-item-control-wrapper">
|
||||
<div class="ant-form-item-control"><span class="ant-form-item-children"><div class="dropbox"><span data-__meta="[object Object]" data-__field="[object Object]" id="dragger" class=""><div class="ant-upload ant-upload-drag"><!----></div><div class="ant-upload-list ant-upload-list-text"></div></span></div></span>
|
||||
<!---->
|
||||
|
|
|
@ -10,16 +10,60 @@ Three columns layout is often used for advanced searching of data table.
|
|||
Because the width of label is not fixed, you may need to adjust it by customizing its style.
|
||||
</us>
|
||||
|
||||
|
||||
<template>
|
||||
<div id='components-form-demo-advanced-search'>
|
||||
<a-form
|
||||
class='ant-advanced-search-form'
|
||||
@submit="handleSearch"
|
||||
:form="form"
|
||||
>
|
||||
<a-row :gutter="24">
|
||||
<a-col v-for="i in 10" :span="8" :key="i" :style="{ display: i < count ? 'block' : 'none' }">
|
||||
<a-form-item :label="`Field ${i}`">
|
||||
<a-input
|
||||
v-decorator="[
|
||||
`field-${i}`,
|
||||
{
|
||||
rules: [{
|
||||
required: true,
|
||||
message: 'Input something!',
|
||||
}],
|
||||
}
|
||||
]"
|
||||
placeholder='placeholder'
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row>
|
||||
<a-col :span="24" :style="{ textAlign: 'right' }">
|
||||
<a-button type='primary' htmlType='submit'>Search</a-button>
|
||||
<a-button :style="{ marginLeft: '8px' }" @click="handleReset">
|
||||
Clear
|
||||
</a-button>
|
||||
<a :style="{ marginLeft: '8px', fontSize: '12px' }" @click="toggle">
|
||||
Collapse <a-icon :type="expand ? 'up' : 'down'" />
|
||||
</a>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form>
|
||||
<div class='search-result-list'>Search Result List</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { Form } from 'ant-design-vue'
|
||||
|
||||
const AdvancedSearchForm = {
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
expand: false,
|
||||
form: this.$form.createForm(this),
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
count () {
|
||||
return this.expand ? 11 : 7
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
handleSearch (e) {
|
||||
e.preventDefault()
|
||||
|
@ -36,73 +80,8 @@ const AdvancedSearchForm = {
|
|||
toggle () {
|
||||
this.expand = !this.expand
|
||||
},
|
||||
|
||||
// To generate mock Form.Item
|
||||
getFields () {
|
||||
const count = this.expand ? 10 : 6
|
||||
const { getFieldDecorator } = this.form
|
||||
const children = []
|
||||
for (let i = 0; i < 10; i++) {
|
||||
children.push(
|
||||
<a-col span={8} key={i} style={{ display: i < count ? 'block' : 'none' }}>
|
||||
<a-form-item label={`Field ${i}`}>
|
||||
{getFieldDecorator(`field-${i}`, {
|
||||
rules: [{
|
||||
required: true,
|
||||
message: 'Input something!',
|
||||
}],
|
||||
})(
|
||||
<a-input placeholder='placeholder' />
|
||||
)}
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
)
|
||||
}
|
||||
return children
|
||||
},
|
||||
},
|
||||
|
||||
render () {
|
||||
return (
|
||||
<a-form
|
||||
class='ant-advanced-search-form'
|
||||
onSubmit={this.handleSearch}
|
||||
>
|
||||
<a-row gutter={24}>{this.getFields()}</a-row>
|
||||
<a-row>
|
||||
<a-col span={24} style={{ textAlign: 'right' }}>
|
||||
<a-button type='primary' htmlType='submit'>Search</a-button>
|
||||
<a-button style={{ marginLeft: '8px' }} onClick={this.handleReset}>
|
||||
Clear
|
||||
</a-button>
|
||||
<a style={{ marginLeft: '8px', fontSize: '12px' }} onClick={this.toggle}>
|
||||
Collapse <a-icon type={this.expand ? 'up' : 'down'} />
|
||||
</a>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form>
|
||||
)
|
||||
},
|
||||
}
|
||||
|
||||
const WrappedAdvancedSearchForm = Form.create()(AdvancedSearchForm)
|
||||
|
||||
export default {
|
||||
methods: {
|
||||
saveFormRef (inst) {
|
||||
this.formRef = inst
|
||||
},
|
||||
},
|
||||
render () {
|
||||
return (
|
||||
<div id='components-form-demo-advanced-search'>
|
||||
<WrappedAdvancedSearchForm wrappedComponentRef={(inst) => this.saveFormRef(inst)}/>
|
||||
<div class='search-result-list'>Search Result List</div>
|
||||
</div>
|
||||
)
|
||||
},
|
||||
}
|
||||
|
||||
</script>
|
||||
<style>
|
||||
.ant-advanced-search-form {
|
||||
|
|
|
@ -10,24 +10,29 @@ Use `setFieldsValue` to set other control's value programmaticly.
|
|||
|
||||
|
||||
<template>
|
||||
<a-form @submit="handleSubmit" :autoFormCreate="(form)=>{this.form = form}">
|
||||
<a-form @submit="handleSubmit" :form="form">
|
||||
<a-form-item
|
||||
label='Note'
|
||||
:labelCol="{ span: 5 }"
|
||||
:wrapperCol="{ span: 12 }"
|
||||
fieldDecoratorId="note"
|
||||
:fieldDecoratorOptions="{rules: [{ required: true, message: 'Please input your note!' }]}"
|
||||
>
|
||||
<a-input />
|
||||
<a-input
|
||||
v-decorator="[
|
||||
'note',
|
||||
{rules: [{ required: true, message: 'Please input your note!' }]}
|
||||
]"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
label='Gender'
|
||||
:labelCol="{ span: 5 }"
|
||||
:wrapperCol="{ span: 12 }"
|
||||
fieldDecoratorId="gender"
|
||||
:fieldDecoratorOptions="{rules: [{ required: true, message: 'Please select your gender!' }]}"
|
||||
>
|
||||
<a-select
|
||||
v-decorator="[
|
||||
'gender',
|
||||
{rules: [{ required: true, message: 'Please select your gender!' }]}
|
||||
]"
|
||||
placeholder='Select a option and change input text above'
|
||||
@change="this.handleSelectChange"
|
||||
>
|
||||
|
@ -50,6 +55,7 @@ export default {
|
|||
data () {
|
||||
return {
|
||||
formLayout: 'horizontal',
|
||||
form: this.$form.createForm(this),
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
|
|
@ -15,9 +15,26 @@ Customized or third-party form controls can be used in Form, too. Controls must
|
|||
</us>
|
||||
|
||||
|
||||
<script>
|
||||
import { Form } from 'ant-design-vue'
|
||||
<template>
|
||||
<a-form layout='inline' @submit="handleSubmit" :form="form">
|
||||
<a-form-item label='Price'>
|
||||
<price-input
|
||||
v-decorator="[
|
||||
'price',
|
||||
{
|
||||
initialValue: { number: 0, currency: 'rmb' },
|
||||
rules: [{ validator: checkPrice }],
|
||||
}
|
||||
]"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item>
|
||||
<a-button type='primary' htmlType='submit'>Submit</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
const hasProp = (instance, prop) => {
|
||||
const $options = instance.$options || {}
|
||||
const propsData = $options.propsData || {}
|
||||
|
@ -25,6 +42,24 @@ const hasProp = (instance, prop) => {
|
|||
}
|
||||
const PriceInput = {
|
||||
props: ['value'],
|
||||
template: `
|
||||
<span>
|
||||
<a-input
|
||||
type='text'
|
||||
:value="number"
|
||||
@change="handleNumberChange"
|
||||
style="width: 63%; margin-right: 2%;"
|
||||
/>
|
||||
<a-select
|
||||
:value="currency"
|
||||
style="width: 32%"
|
||||
@change="handleCurrencyChange"
|
||||
>
|
||||
<a-select-option value='rmb'>RMB</a-select-option>
|
||||
<a-select-option value='dollar'>Dollar</a-select-option>
|
||||
</a-select>
|
||||
</span>
|
||||
`,
|
||||
data () {
|
||||
const value = this.value || {}
|
||||
return {
|
||||
|
@ -56,35 +91,16 @@ const PriceInput = {
|
|||
this.triggerChange({ currency })
|
||||
},
|
||||
triggerChange (changedValue) {
|
||||
// Should provide an event to pass value to Form.
|
||||
// Should provide an event to pass value to Form.
|
||||
this.$emit('change', Object.assign({}, this.$data, changedValue))
|
||||
},
|
||||
},
|
||||
|
||||
render () {
|
||||
const { number, currency } = this
|
||||
return (
|
||||
<span>
|
||||
<a-input
|
||||
type='text'
|
||||
value={number}
|
||||
onChange={this.handleNumberChange}
|
||||
style={{ width: '65%', marginRight: '3%' }}
|
||||
/>
|
||||
<a-select
|
||||
value={currency}
|
||||
style={{ width: '32%' }}
|
||||
onChange={this.handleCurrencyChange}
|
||||
>
|
||||
<a-select-option value='rmb'>RMB</a-select-option>
|
||||
<a-select-option value='dollar'>Dollar</a-select-option>
|
||||
</a-select>
|
||||
</span>
|
||||
)
|
||||
},
|
||||
}
|
||||
|
||||
const Demo = {
|
||||
export default {
|
||||
beforeCreate () {
|
||||
this.form = this.$form.createForm(this)
|
||||
},
|
||||
methods: {
|
||||
handleSubmit (e) {
|
||||
e.preventDefault()
|
||||
|
@ -102,26 +118,11 @@ const Demo = {
|
|||
callback('Price must greater than zero!')
|
||||
},
|
||||
},
|
||||
|
||||
render () {
|
||||
const { getFieldDecorator } = this.form
|
||||
return (
|
||||
<a-form layout='inline' onSubmit={this.handleSubmit}>
|
||||
<a-form-item label='Price'>
|
||||
{getFieldDecorator('price', {
|
||||
initialValue: { number: 0, currency: 'rmb' },
|
||||
rules: [{ validator: this.checkPrice }],
|
||||
})(<PriceInput />)}
|
||||
</a-form-item>
|
||||
<a-form-item>
|
||||
<a-button type='primary' htmlType='submit'>Submit</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
)
|
||||
components: {
|
||||
PriceInput,
|
||||
},
|
||||
}
|
||||
|
||||
export default Form.create()(Demo)
|
||||
</script>
|
||||
|
||||
|
||||
|
|
|
@ -9,11 +9,76 @@ Add or remove form items dynamically.
|
|||
</us>
|
||||
|
||||
|
||||
<script>
|
||||
import { Form } from 'ant-design-vue'
|
||||
<template>
|
||||
<a-form @submit="handleSubmit" :form="form">
|
||||
<a-form-item
|
||||
v-for="(k, index) in form.getFieldValue('keys')"
|
||||
v-bind="index === 0 ? formItemLayout : formItemLayoutWithOutLabel"
|
||||
:label="index === 0 ? 'Passengers' : ''"
|
||||
:required="false"
|
||||
:key="k"
|
||||
>
|
||||
<a-input
|
||||
v-decorator="[
|
||||
`names[${k}]`,
|
||||
{
|
||||
validateTrigger: ['change', 'blur'],
|
||||
rules: [{
|
||||
required: true,
|
||||
whitespace: true,
|
||||
message: 'Please input passenger\'s name or delete this field.',
|
||||
}],
|
||||
}
|
||||
]"
|
||||
placeholder='passenger name'
|
||||
style="width: 60%; margin-right: 8px"
|
||||
/>
|
||||
<a-icon
|
||||
v-if="form.getFieldValue('keys').length > 1"
|
||||
class='dynamic-delete-button'
|
||||
type='minus-circle-o'
|
||||
:disabled="form.getFieldValue('keys').length === 1"
|
||||
@click="() => remove(k)"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item v-bind="formItemLayoutWithOutLabel">
|
||||
<a-button type='dashed' @click="add" style="width: 60%">
|
||||
<a-icon type='plus' /> Add field
|
||||
</a-button>
|
||||
</a-form-item>
|
||||
<a-form-item v-bind="formItemLayoutWithOutLabel">
|
||||
<a-button type='primary' htmlType='submit'>Submit</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
let uuid = 0
|
||||
const DynamicFieldSet = {
|
||||
export default {
|
||||
beforeCreate () {
|
||||
this.form = this.$form.createForm(this)
|
||||
this.form.getFieldDecorator('keys', { initialValue: [] })
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
formItemLayout: {
|
||||
labelCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 4 },
|
||||
},
|
||||
wrapperCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 20 },
|
||||
},
|
||||
},
|
||||
formItemLayoutWithOutLabel: {
|
||||
wrapperCol: {
|
||||
xs: { span: 24, offset: 0 },
|
||||
sm: { span: 20, offset: 4 },
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
remove (k) {
|
||||
const { form } = this
|
||||
|
@ -52,73 +117,7 @@ const DynamicFieldSet = {
|
|||
})
|
||||
},
|
||||
},
|
||||
|
||||
render () {
|
||||
const { getFieldDecorator, getFieldValue } = this.form
|
||||
const formItemLayout = {
|
||||
labelCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 4 },
|
||||
},
|
||||
wrapperCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 20 },
|
||||
},
|
||||
}
|
||||
const formItemLayoutWithOutLabel = {
|
||||
wrapperCol: {
|
||||
xs: { span: 24, offset: 0 },
|
||||
sm: { span: 20, offset: 4 },
|
||||
},
|
||||
}
|
||||
getFieldDecorator('keys', { initialValue: [] })
|
||||
const keys = getFieldValue('keys')
|
||||
const formItems = keys.map((k, index) => {
|
||||
return (
|
||||
<a-form-item
|
||||
{...{ props: (index === 0 ? formItemLayout : formItemLayoutWithOutLabel) }}
|
||||
label={index === 0 ? 'Passengers' : ''}
|
||||
required={false}
|
||||
key={k}
|
||||
>
|
||||
{getFieldDecorator(`names[${k}]`, {
|
||||
validateTrigger: ['onChange', 'onBlur'],
|
||||
rules: [{
|
||||
required: true,
|
||||
whitespace: true,
|
||||
message: "Please input passenger's name or delete this field.",
|
||||
}],
|
||||
})(
|
||||
<a-input placeholder='passenger name' style={{ width: '60%', marginRight: '8px' }} />
|
||||
)}
|
||||
{keys.length > 1 ? (
|
||||
<a-icon
|
||||
class='dynamic-delete-button'
|
||||
type='minus-circle-o'
|
||||
disabled={keys.length === 1}
|
||||
onClick={() => this.remove(k)}
|
||||
/>
|
||||
) : null}
|
||||
</a-form-item>
|
||||
)
|
||||
})
|
||||
return (
|
||||
<a-form onSubmit={this.handleSubmit}>
|
||||
{formItems}
|
||||
<a-form-item {...{ props: formItemLayoutWithOutLabel }}>
|
||||
<a-button type='dashed' onClick={this.add} style={{ width: '60%' }}>
|
||||
<a-icon type='plus' /> Add field
|
||||
</a-button>
|
||||
</a-form-item>
|
||||
<a-form-item {...{ props: formItemLayoutWithOutLabel }}>
|
||||
<a-button type='primary' htmlType='submit'>Submit</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
)
|
||||
},
|
||||
}
|
||||
|
||||
export default Form.create()(DynamicFieldSet)
|
||||
</script>
|
||||
<style>
|
||||
.dynamic-delete-button {
|
||||
|
|
|
@ -10,24 +10,32 @@ Perform different check rules according to different situations.
|
|||
|
||||
|
||||
<template>
|
||||
<a-form :autoFormCreate="(form)=>{this.form = form}">
|
||||
<a-form :form="form">
|
||||
<a-form-item
|
||||
:labelCol="formItemLayout.labelCol"
|
||||
:wrapperCol="formItemLayout.wrapperCol"
|
||||
label='Name'
|
||||
fieldDecoratorId="username"
|
||||
:fieldDecoratorOptions="{rules: [{ required: true, message: 'Please input your name' }]}"
|
||||
>
|
||||
<a-input placeholder='Please input your name' />
|
||||
<a-input
|
||||
v-decorator="[
|
||||
'username',
|
||||
{rules: [{ required: true, message: 'Please input your name' }]}
|
||||
]"
|
||||
placeholder='Please input your name'
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
:labelCol="formItemLayout.labelCol"
|
||||
:wrapperCol="formItemLayout.wrapperCol"
|
||||
label='Nickname'
|
||||
fieldDecoratorId="nickname"
|
||||
:fieldDecoratorOptions="{rules: [{ required: checkNick, message: 'Please input your nickname' }]}"
|
||||
>
|
||||
<a-input placeholder='Please input your nickname' />
|
||||
<a-input
|
||||
v-decorator="[
|
||||
'nickname',
|
||||
{rules: [{ required: checkNick, message: 'Please input your nickname' }]}
|
||||
]"
|
||||
placeholder='Please input your nickname'
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
:labelCol="formTailLayout.labelCol"
|
||||
|
@ -64,6 +72,7 @@ export default {
|
|||
checkNick: false,
|
||||
formItemLayout,
|
||||
formTailLayout,
|
||||
form: this.$form.createForm(this),
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
|
|
@ -8,51 +8,66 @@
|
|||
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.
|
||||
</us>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<a-button type='primary' @click="showModal">New Collection</a-button>
|
||||
<collection-create-form
|
||||
ref="collectionForm"
|
||||
:visible="visible"
|
||||
@cancel="handleCancel"
|
||||
@create="handleCreate"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Form } from 'ant-design-vue'
|
||||
|
||||
const CollectionCreateForm = Form.create()(
|
||||
{
|
||||
props: ['visible'],
|
||||
render () {
|
||||
const { visible, form } = this
|
||||
const { getFieldDecorator } = form
|
||||
return (
|
||||
<a-modal
|
||||
visible={visible}
|
||||
title='Create a new collection'
|
||||
okText='Create'
|
||||
onCancel={() => { this.$emit('cancel') }}
|
||||
onOk={() => { this.$emit('create') }}
|
||||
>
|
||||
<a-form layout='vertical'>
|
||||
<a-form-item label='Title'>
|
||||
{getFieldDecorator('title', {
|
||||
const CollectionCreateForm = {
|
||||
props: ['visible'],
|
||||
beforeCreate () {
|
||||
this.form = this.$form.createForm(this)
|
||||
},
|
||||
template: `
|
||||
<a-modal
|
||||
:visible="visible"
|
||||
title='Create a new collection'
|
||||
okText='Create'
|
||||
@cancel="() => { $emit('cancel') }"
|
||||
@ok="() => { $emit('create') }"
|
||||
>
|
||||
<a-form layout='vertical' :form="form">
|
||||
<a-form-item label='Title'>
|
||||
<a-input
|
||||
v-decorator="[
|
||||
'title',
|
||||
{
|
||||
rules: [{ required: true, message: 'Please input the title of collection!' }],
|
||||
})(
|
||||
<a-input />
|
||||
)}
|
||||
</a-form-item>
|
||||
<a-form-item label='Description'>
|
||||
{getFieldDecorator('description')(<a-input type='textarea' />)}
|
||||
</a-form-item>
|
||||
<a-form-item class='collection-create-form_last-form-item'>
|
||||
{getFieldDecorator('modifier', {
|
||||
initialValue: 'public',
|
||||
})(
|
||||
<a-radio-group>
|
||||
<a-radio value='public'>Public</a-radio>
|
||||
<a-radio value='private'>Private</a-radio>
|
||||
</a-radio-group>
|
||||
)}
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-modal>
|
||||
)
|
||||
},
|
||||
}
|
||||
)
|
||||
}
|
||||
]"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label='Description'>
|
||||
<a-input
|
||||
type='textarea'
|
||||
v-decorator="['description']"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item class='collection-create-form_last-form-item'>
|
||||
<a-radio-group
|
||||
v-decorator="[
|
||||
'modifier',
|
||||
{
|
||||
initialValue: 'private',
|
||||
}
|
||||
]"
|
||||
>
|
||||
<a-radio value='public'>Public</a-radio>
|
||||
<a-radio value='private'>Private</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-modal>
|
||||
`,
|
||||
}
|
||||
|
||||
export default {
|
||||
data () {
|
||||
|
@ -68,38 +83,22 @@ export default {
|
|||
this.visible = false
|
||||
},
|
||||
handleCreate () {
|
||||
const form = this.formRef.form
|
||||
const form = this.$refs.collectionForm.form
|
||||
form.validateFields((err, values) => {
|
||||
if (err) {
|
||||
return
|
||||
}
|
||||
|
||||
console.log('Received values of form: ', values)
|
||||
form.resetFields()
|
||||
this.visible = false
|
||||
})
|
||||
},
|
||||
saveFormRef (formRef) {
|
||||
this.formRef = formRef
|
||||
},
|
||||
},
|
||||
|
||||
render () {
|
||||
return (
|
||||
<div>
|
||||
<a-button type='primary' onClick={this.showModal}>New Collection</a-button>
|
||||
<CollectionCreateForm
|
||||
wrappedComponentRef={this.saveFormRef}
|
||||
visible={this.visible}
|
||||
onCancel={this.handleCancel}
|
||||
onCreate={this.handleCreate}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
},
|
||||
components: { CollectionCreateForm },
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -3,52 +3,78 @@
|
|||
้่ฟไฝฟ็จ `onFieldsChange` ไธ `mapPropsToFields`๏ผๅฏไปฅๆ่กจๅ็ๆฐๆฎๅญๅจๅฐไธๅฑ็ปไปถใ
|
||||
**ๆณจๆ๏ผ**
|
||||
`mapPropsToFields` ้้ข่ฟๅ็่กจๅๅๆฐๆฎๅฟ
้กปไฝฟ็จ `Form.createFormField` ๅ
่ฃ
ใ
|
||||
ไธๅฑ็ปไปถไผ ้็ๅฑๆง๏ผๅฟ
้กปๅจ`Form.create({ props: ...})`็propsไธญๅฃฐๆใ
|
||||
ๅฆๆไฝ ไฝฟ็จ`Form.create`๏ผไธๅฑ็ปไปถไผ ้็ๅฑๆง๏ผๅฟ
้กปๅจ`Form.create({ props: ...})`็propsไธญๅฃฐๆใ
|
||||
ๅฆๆไฝฟ็จ`this.$form.createForm`๏ผไฝ ๅฏไปฅไฝฟ็จไปปไฝๆฐๆฎ๏ผไธไป
ไป
ๅฑ้ไบไธๅฑ็ปไปถ็ๅฑๆงใ
|
||||
</cn>
|
||||
|
||||
<us>
|
||||
#### 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`.
|
||||
If you use `Form.create`. 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: ...})`.
|
||||
But if you use `this.$form.createForm`, You can use any data, not just the properties of the upper components.
|
||||
</us>
|
||||
|
||||
|
||||
<template>
|
||||
<div id='components-form-demo-global-state'>
|
||||
<customized-form
|
||||
:username="fields.username"
|
||||
@change="handleFormChange"
|
||||
/>
|
||||
<pre class='language-bash'>
|
||||
{{JSON.stringify(fields, null, 2)}}
|
||||
</pre>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Form } from 'ant-design-vue'
|
||||
|
||||
const CustomizedForm = Form.create({
|
||||
props: ['username'], // must declare like vue `props` https://vuejs.org/v2/api/#props
|
||||
onFieldsChange (instance, changedFields) {
|
||||
instance.$emit('change', changedFields)
|
||||
const CustomizedForm = {
|
||||
props: ['username'],
|
||||
template: `
|
||||
<a-form layout='inline' :form="form">
|
||||
<a-form-item label='Username'>
|
||||
<a-input
|
||||
v-decorator="[
|
||||
'username',
|
||||
{
|
||||
rules: [{ required: true, message: 'Username is required!' }],
|
||||
}
|
||||
]"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
`,
|
||||
created () {
|
||||
this.form = this.$form.createForm(this, {
|
||||
onFieldsChange: (_, changedFields) => {
|
||||
this.$emit('change', changedFields)
|
||||
},
|
||||
mapPropsToFields: () => {
|
||||
return {
|
||||
username: this.$form.createFormField({
|
||||
...this.username,
|
||||
value: this.username.value,
|
||||
}),
|
||||
}
|
||||
},
|
||||
onValuesChange (_, values) {
|
||||
console.log(values)
|
||||
},
|
||||
})
|
||||
},
|
||||
mapPropsToFields (props) {
|
||||
return {
|
||||
username: Form.createFormField({
|
||||
...props.username,
|
||||
value: props.username.value,
|
||||
}),
|
||||
}
|
||||
watch: {
|
||||
username () {
|
||||
this.form.updateFields({
|
||||
username: this.$form.createFormField({
|
||||
...this.username,
|
||||
value: this.username.value,
|
||||
}),
|
||||
})
|
||||
},
|
||||
},
|
||||
onValuesChange (_, values) {
|
||||
console.log(values)
|
||||
},
|
||||
})({
|
||||
render () {
|
||||
const { getFieldDecorator } = this.form
|
||||
return (
|
||||
<a-form layout='inline'>
|
||||
<a-form-item label='Username'>
|
||||
{getFieldDecorator('username', {
|
||||
rules: [{ required: true, message: 'Username is required!' }],
|
||||
})(<a-input />)}
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
)
|
||||
},
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
export default {
|
||||
data () {
|
||||
|
@ -62,20 +88,12 @@ export default {
|
|||
},
|
||||
methods: {
|
||||
handleFormChange (changedFields) {
|
||||
console.log('changedFields', changedFields)
|
||||
this.fields = { ...this.fields, ...changedFields }
|
||||
},
|
||||
},
|
||||
|
||||
render () {
|
||||
const fields = this.fields
|
||||
return (
|
||||
<div id='components-form-demo-global-state'>
|
||||
<CustomizedForm {...{ props: fields }} onChange={this.handleFormChange} />
|
||||
<pre class='language-bash'>
|
||||
{JSON.stringify(fields, null, 2)}
|
||||
</pre>
|
||||
</div>
|
||||
)
|
||||
components: {
|
||||
CustomizedForm,
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
@ -90,3 +108,4 @@ export default {
|
|||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -10,38 +10,45 @@ Horizontal login form is often used in navigation bar.
|
|||
|
||||
|
||||
<template>
|
||||
<a-form layout='inline' @submit="handleSubmit" :autoFormCreate="(form)=>{this.form = form}">
|
||||
<template v-if="form">
|
||||
<a-form-item
|
||||
:validateStatus="userNameError() ? 'error' : ''"
|
||||
:help="userNameError() || ''"
|
||||
fieldDecoratorId="userName"
|
||||
:fieldDecoratorOptions="{rules: [{ required: true, message: 'Please input your username!' }]}"
|
||||
<a-form layout='inline' @submit="handleSubmit" :form="form">
|
||||
<a-form-item
|
||||
:validateStatus="userNameError() ? 'error' : ''"
|
||||
:help="userNameError() || ''"
|
||||
>
|
||||
<a-input
|
||||
placeholder='Username'
|
||||
v-decorator="[
|
||||
'userName',
|
||||
{rules: [{ required: true, message: 'Please input your username!' }]}
|
||||
]"
|
||||
>
|
||||
<a-input placeholder='Username'>
|
||||
<a-icon slot="prefix" type='user' style="color:rgba(0,0,0,.25)"/>
|
||||
</a-input>
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
:validateStatus="passwordError() ? 'error' : ''"
|
||||
:help="passwordError() || ''"
|
||||
fieldDecoratorId="password"
|
||||
:fieldDecoratorOptions="{rules: [{ required: true, message: 'Please input your Password!' }]}"
|
||||
<a-icon slot="prefix" type='user' style="color:rgba(0,0,0,.25)"/>
|
||||
</a-input>
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
:validateStatus="passwordError() ? 'error' : ''"
|
||||
:help="passwordError() || ''"
|
||||
>
|
||||
<a-input
|
||||
v-decorator="[
|
||||
'password',
|
||||
{rules: [{ required: true, message: 'Please input your Password!' }]}
|
||||
]"
|
||||
type='password'
|
||||
placeholder='Password'
|
||||
>
|
||||
<a-input type='password' placeholder='Password'>
|
||||
<a-icon slot="prefix" type='lock' style="color:rgba(0,0,0,.25)"/>
|
||||
</a-input>
|
||||
</a-form-item>
|
||||
<a-form-item>
|
||||
<a-button
|
||||
type='primary'
|
||||
htmlType='submit'
|
||||
:disabled="hasErrors(form.getFieldsError())"
|
||||
>
|
||||
Log in
|
||||
</a-button>
|
||||
</a-form-item>
|
||||
</template>
|
||||
<a-icon slot="prefix" type='lock' style="color:rgba(0,0,0,.25)"/>
|
||||
</a-input>
|
||||
</a-form-item>
|
||||
<a-form-item>
|
||||
<a-button
|
||||
type='primary'
|
||||
htmlType='submit'
|
||||
:disabled="hasErrors(form.getFieldsError())"
|
||||
>
|
||||
Log in
|
||||
</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</template>
|
||||
|
||||
|
@ -53,7 +60,7 @@ export default {
|
|||
data () {
|
||||
return {
|
||||
hasErrors,
|
||||
form: null,
|
||||
form: this.$form.createForm(this),
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
|
|
|
@ -8,11 +8,58 @@
|
|||
Normal login form which can contain more elements.
|
||||
</us>
|
||||
|
||||
<template>
|
||||
<a-form :form="form" id='components-form-demo-normal-login' @submit="handleSubmit" class='login-form'>
|
||||
<a-form-item>
|
||||
<a-input
|
||||
placeholder='Username'
|
||||
v-decorator="[
|
||||
'userName',
|
||||
{ rules: [{ required: true, message: 'Please input your username!' }] }
|
||||
]"
|
||||
>
|
||||
<a-icon slot="prefix" type='user' style="color: rgba(0,0,0,.25)" />
|
||||
</a-input>
|
||||
</a-form-item>
|
||||
<a-form-item>
|
||||
<a-input
|
||||
v-decorator="[
|
||||
'password',
|
||||
{ rules: [{ required: true, message: 'Please input your Password!' }] }
|
||||
]"
|
||||
type='password'
|
||||
placeholder='Password'
|
||||
>
|
||||
<a-icon slot="prefix" type='lock' style="color: rgba(0,0,0,.25)" />
|
||||
</a-input>
|
||||
</a-form-item>
|
||||
<a-form-item>
|
||||
<a-checkbox
|
||||
v-decorator="[
|
||||
'remember',
|
||||
{
|
||||
valuePropName: 'checked',
|
||||
initialValue: true,
|
||||
}
|
||||
]"
|
||||
>
|
||||
Remember me
|
||||
</a-checkbox>
|
||||
<a class='login-form-forgot' href=''>Forgot password</a>
|
||||
<a-button type='primary' htmlType='submit' class='login-form-button'>
|
||||
Log in
|
||||
</a-button>
|
||||
Or <a href=''>register now!</a>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Form } from 'ant-design-vue'
|
||||
|
||||
const NormalLoginForm = {
|
||||
export default {
|
||||
beforeCreate () {
|
||||
this.form = this.$form.createForm(this)
|
||||
},
|
||||
methods: {
|
||||
handleSubmit (e) {
|
||||
e.preventDefault()
|
||||
|
@ -23,44 +70,7 @@ const NormalLoginForm = {
|
|||
})
|
||||
},
|
||||
},
|
||||
|
||||
render () {
|
||||
const { getFieldDecorator } = this.form
|
||||
return (
|
||||
<a-form id='components-form-demo-normal-login' onSubmit={this.handleSubmit} class='login-form'>
|
||||
<a-form-item>
|
||||
{getFieldDecorator('userName', {
|
||||
rules: [{ required: true, message: 'Please input your username!' }],
|
||||
})(
|
||||
<a-input prefix={<a-icon type='user' style={{ color: 'rgba(0,0,0,.25)' }} />} placeholder='Username' />
|
||||
)}
|
||||
</a-form-item>
|
||||
<a-form-item>
|
||||
{getFieldDecorator('password', {
|
||||
rules: [{ required: true, message: 'Please input your Password!' }],
|
||||
})(
|
||||
<a-input prefix={<a-icon type='lock' style={{ color: 'rgba(0,0,0,.25)' }} />} type='password' placeholder='Password' />
|
||||
)}
|
||||
</a-form-item>
|
||||
<a-form-item>
|
||||
{getFieldDecorator('remember', {
|
||||
valuePropName: 'checked',
|
||||
initialValue: true,
|
||||
})(
|
||||
<a-checkbox>Remember me</a-checkbox>
|
||||
)}
|
||||
<a class='login-form-forgot' href=''>Forgot password</a>
|
||||
<a-button type='primary' htmlType='submit' class='login-form-button'>
|
||||
Log in
|
||||
</a-button>
|
||||
Or <a href=''>register now!</a>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
)
|
||||
},
|
||||
}
|
||||
|
||||
export default Form.create()(NormalLoginForm)
|
||||
</script>
|
||||
<style>
|
||||
#components-form-demo-normal-login .login-form {
|
||||
|
@ -77,3 +87,4 @@ export default Form.create()(NormalLoginForm)
|
|||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -8,10 +8,170 @@
|
|||
Fill in this form to create a new account for you.
|
||||
</us>
|
||||
|
||||
<template>
|
||||
<a-form @submit="handleSubmit" :form="form">
|
||||
<a-form-item
|
||||
v-bind="formItemLayout"
|
||||
label='E-mail'
|
||||
>
|
||||
<a-input
|
||||
v-decorator="[
|
||||
'email',
|
||||
{
|
||||
rules: [{
|
||||
type: 'email', message: 'The input is not valid E-mail!',
|
||||
}, {
|
||||
required: true, message: 'Please input your E-mail!',
|
||||
}]
|
||||
}
|
||||
]"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
v-bind="formItemLayout"
|
||||
label='Password'
|
||||
>
|
||||
<a-input
|
||||
v-decorator="[
|
||||
'password',
|
||||
{
|
||||
rules: [{
|
||||
required: true, message: 'Please input your password!',
|
||||
}, {
|
||||
validator: this.validateToNextPassword,
|
||||
}],
|
||||
}
|
||||
]"
|
||||
type='password'
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
v-bind="formItemLayout"
|
||||
label='Confirm Password'
|
||||
>
|
||||
<a-input
|
||||
v-decorator="[
|
||||
'confirm',
|
||||
{
|
||||
rules: [{
|
||||
required: true, message: 'Please confirm your password!',
|
||||
}, {
|
||||
validator: compareToFirstPassword,
|
||||
}],
|
||||
}
|
||||
]"
|
||||
type='password'
|
||||
@blur="handleConfirmBlur"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
v-bind="formItemLayout"
|
||||
>
|
||||
<span slot="label">
|
||||
Nickname
|
||||
<a-tooltip title='What do you want others to call you?'>
|
||||
<a-icon type='question-circle-o' />
|
||||
</a-tooltip>
|
||||
</span>
|
||||
<a-input
|
||||
v-decorator="[
|
||||
'nickname',
|
||||
{
|
||||
rules: [{ required: true, message: 'Please input your nickname!', whitespace: true }]
|
||||
}
|
||||
]"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
v-bind="formItemLayout"
|
||||
label='Habitual Residence'
|
||||
>
|
||||
<a-cascader
|
||||
v-decorator="[
|
||||
'residence',
|
||||
{
|
||||
initialValue: ['zhejiang', 'hangzhou', 'xihu'],
|
||||
rules: [{ type: 'array', required: true, message: 'Please select your habitual residence!' }],
|
||||
}
|
||||
]"
|
||||
:options="residences"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
v-bind="formItemLayout"
|
||||
label='Phone Number'
|
||||
>
|
||||
<a-input
|
||||
v-decorator="[
|
||||
'phone',
|
||||
{
|
||||
rules: [{ required: true, message: 'Please input your phone number!' }],
|
||||
}
|
||||
]"
|
||||
style="width: 100%"
|
||||
>
|
||||
<a-select
|
||||
v-decorator="[
|
||||
'prefix',
|
||||
{ initialValue: '86' }
|
||||
]"
|
||||
slot="addonBefore"
|
||||
style="width: 70px"
|
||||
>
|
||||
<a-select-option value='86'>+86</a-select-option>
|
||||
<a-select-option value='87'>+87</a-select-option>
|
||||
</a-select>
|
||||
</a-input>
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
v-bind="formItemLayout"
|
||||
label='Website'
|
||||
>
|
||||
<a-auto-complete
|
||||
v-decorator="[
|
||||
'website',
|
||||
{rules: [{ required: true, message: 'Please input website!' }]}
|
||||
]"
|
||||
@change="handleWebsiteChange"
|
||||
placeholder='website'
|
||||
>
|
||||
<template slot="dataSource">
|
||||
<a-select-option v-for="website in autoCompleteResult" :key="website">{{website}}</a-select-option>
|
||||
</template>
|
||||
<a-input />
|
||||
</a-auto-complete>
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
v-bind="formItemLayout"
|
||||
label='Captcha'
|
||||
extra='We must make sure that your are a human.'
|
||||
>
|
||||
<a-row :gutter="8">
|
||||
<a-col :span="12">
|
||||
<a-input
|
||||
v-decorator="[
|
||||
'captcha',
|
||||
{rules: [{ required: true, message: 'Please input the captcha you got!' }]}
|
||||
]"
|
||||
/>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-button>Get captcha</a-button>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form-item>
|
||||
<a-form-item v-bind="tailFormItemLayout">
|
||||
<a-checkbox
|
||||
v-decorator="['agreement', {valuePropName: 'checked'}]"
|
||||
>I have read the <a href=''>agreement</a></a-checkbox>
|
||||
</a-form-item>
|
||||
<a-form-item v-bind="tailFormItemLayout">
|
||||
<a-button type='primary' htmlType='submit'>Register</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Form } from 'ant-design-vue'
|
||||
|
||||
const residences = [{
|
||||
value: 'zhejiang',
|
||||
label: 'Zhejiang',
|
||||
|
@ -36,11 +196,37 @@ const residences = [{
|
|||
}],
|
||||
}]
|
||||
|
||||
const RegistrationForm = {
|
||||
export default {
|
||||
beforeCreate () {
|
||||
this.form = this.$form.createForm(this)
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
confirmDirty: false,
|
||||
residences,
|
||||
autoCompleteResult: [],
|
||||
formItemLayout: {
|
||||
labelCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 8 },
|
||||
},
|
||||
wrapperCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 16 },
|
||||
},
|
||||
},
|
||||
tailFormItemLayout: {
|
||||
wrapperCol: {
|
||||
xs: {
|
||||
span: 24,
|
||||
offset: 0,
|
||||
},
|
||||
sm: {
|
||||
span: 16,
|
||||
offset: 8,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
@ -81,180 +267,10 @@ const RegistrationForm = {
|
|||
this.autoCompleteResult = autoCompleteResult
|
||||
},
|
||||
},
|
||||
|
||||
render () {
|
||||
const { getFieldDecorator } = this.form
|
||||
const { autoCompleteResult } = this
|
||||
|
||||
const formItemLayout = {
|
||||
labelCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 8 },
|
||||
},
|
||||
wrapperCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 16 },
|
||||
},
|
||||
}
|
||||
const tailFormItemLayout = {
|
||||
wrapperCol: {
|
||||
xs: {
|
||||
span: 24,
|
||||
offset: 0,
|
||||
},
|
||||
sm: {
|
||||
span: 16,
|
||||
offset: 8,
|
||||
},
|
||||
},
|
||||
}
|
||||
const prefixSelector = getFieldDecorator('prefix', {
|
||||
initialValue: '86',
|
||||
})(
|
||||
<a-select style={{ width: '70px' }}>
|
||||
<a-select-option value='86'>+86</a-select-option>
|
||||
<a-select-option value='87'>+87</a-select-option>
|
||||
</a-select>
|
||||
)
|
||||
|
||||
const websiteOptions = autoCompleteResult.map(website => (
|
||||
<a-select-option key={website}>{website}</a-select-option>
|
||||
))
|
||||
|
||||
return (
|
||||
<a-form onSubmit={this.handleSubmit}>
|
||||
<a-form-item
|
||||
{...{ props: formItemLayout }}
|
||||
label='E-mail'
|
||||
>
|
||||
{getFieldDecorator('email', {
|
||||
rules: [{
|
||||
type: 'email', message: 'The input is not valid E-mail!',
|
||||
}, {
|
||||
required: true, message: 'Please input your E-mail!',
|
||||
}],
|
||||
})(
|
||||
<a-input />
|
||||
)}
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
{...{ props: formItemLayout }}
|
||||
label='Password'
|
||||
>
|
||||
{getFieldDecorator('password', {
|
||||
rules: [{
|
||||
required: true, message: 'Please input your password!',
|
||||
}, {
|
||||
validator: this.validateToNextPassword,
|
||||
}],
|
||||
})(
|
||||
<a-input type='password' />
|
||||
)}
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
{...{ props: formItemLayout }}
|
||||
label='Confirm Password'
|
||||
>
|
||||
{getFieldDecorator('confirm', {
|
||||
rules: [{
|
||||
required: true, message: 'Please confirm your password!',
|
||||
}, {
|
||||
validator: this.compareToFirstPassword,
|
||||
}],
|
||||
})(
|
||||
<a-input type='password' onBlur={this.handleConfirmBlur} />
|
||||
)}
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
{...{ props: formItemLayout }}
|
||||
label={(
|
||||
<span>
|
||||
Nickname
|
||||
<a-tooltip title='What do you want others to call you?'>
|
||||
<a-icon type='question-circle-o' />
|
||||
</a-tooltip>
|
||||
</span>
|
||||
)}
|
||||
>
|
||||
{getFieldDecorator('nickname', {
|
||||
rules: [{ required: true, message: 'Please input your nickname!', whitespace: true }],
|
||||
})(
|
||||
<a-input />
|
||||
)}
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
{...{ props: formItemLayout }}
|
||||
label='Habitual Residence'
|
||||
>
|
||||
{getFieldDecorator('residence', {
|
||||
initialValue: ['zhejiang', 'hangzhou', 'xihu'],
|
||||
rules: [{ type: 'array', required: true, message: 'Please select your habitual residence!' }],
|
||||
})(
|
||||
<a-cascader options={residences} />
|
||||
)}
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
{...{ props: formItemLayout }}
|
||||
label='Phone Number'
|
||||
>
|
||||
{getFieldDecorator('phone', {
|
||||
rules: [{ required: true, message: 'Please input your phone number!' }],
|
||||
})(
|
||||
<a-input addonBefore={prefixSelector} style={{ width: '100%' }} />
|
||||
)}
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
{...{ props: formItemLayout }}
|
||||
label='Website'
|
||||
>
|
||||
{getFieldDecorator('website', {
|
||||
rules: [{ required: true, message: 'Please input website!' }],
|
||||
})(
|
||||
<a-auto-complete
|
||||
dataSource={websiteOptions}
|
||||
onChange={this.handleWebsiteChange}
|
||||
placeholder='website'
|
||||
>
|
||||
<a-input />
|
||||
</a-auto-complete>
|
||||
)}
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
{...{ props: formItemLayout }}
|
||||
label='Captcha'
|
||||
extra='We must make sure that your are a human.'
|
||||
>
|
||||
<a-row gutter={8}>
|
||||
<a-col span={12}>
|
||||
{getFieldDecorator('captcha', {
|
||||
rules: [{ required: true, message: 'Please input the captcha you got!' }],
|
||||
})(
|
||||
<a-input />
|
||||
)}
|
||||
</a-col>
|
||||
<a-col span={12}>
|
||||
<a-button>Get captcha</a-button>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form-item>
|
||||
<a-form-item {...{ props: tailFormItemLayout }}>
|
||||
{getFieldDecorator('agreement', {
|
||||
valuePropName: 'checked',
|
||||
})(
|
||||
<a-checkbox>I have read the <a href=''>agreement</a></a-checkbox>
|
||||
)}
|
||||
</a-form-item>
|
||||
<a-form-item {...{ props: tailFormItemLayout }}>
|
||||
<a-button type='primary' htmlType='submit'>Register</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
)
|
||||
},
|
||||
}
|
||||
|
||||
export default Form.create()(RegistrationForm)
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -8,15 +8,83 @@
|
|||
the `value` of time-related components is `moment`. So, we need to pre-process those values.
|
||||
</us>
|
||||
|
||||
|
||||
<template>
|
||||
<a-form @submit="handleSubmit" :form="form">
|
||||
<a-form-item
|
||||
v-bind="formItemLayout"
|
||||
label='DatePicker'
|
||||
>
|
||||
<a-date-picker v-decorator="['date-picker', config]"/>
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
v-bind="formItemLayout"
|
||||
label='DatePicker[showTime]'
|
||||
>
|
||||
<a-date-picker v-decorator="['date-time-picker', config]" showTime format='YYYY-MM-DD HH:mm:ss' />
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
v-bind="formItemLayout"
|
||||
label='MonthPicker'
|
||||
>
|
||||
<a-monthPicker v-decorator="['month-picker', config]" />
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
v-bind="formItemLayout"
|
||||
label='RangePicker'
|
||||
>
|
||||
<a-range-picker v-decorator="['range-picker', rangeConfig]" />
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
v-bind="formItemLayout"
|
||||
label='RangePicker[showTime]'
|
||||
>
|
||||
<a-range-picker v-decorator="['range-time-picker', rangeConfig]" showTime format='YYYY-MM-DD HH:mm:ss' />
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
v-bind="formItemLayout"
|
||||
label='TimePicker'
|
||||
>
|
||||
<a-time-picker v-decorator="['time-picker', config]" />
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
:wrapperCol="{
|
||||
xs: { span: 24, offset: 0 },
|
||||
sm: { span: 16, offset: 8 },
|
||||
}"
|
||||
>
|
||||
<a-button type='primary' htmlType='submit'>Submit</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</template>
|
||||
<script>
|
||||
import { Form } from 'ant-design-vue'
|
||||
|
||||
const TimeRelatedForm = {
|
||||
export default {
|
||||
beforeCreate () {
|
||||
this.form = this.$form.createForm(this)
|
||||
},
|
||||
data () {
|
||||
window.form = this
|
||||
return {
|
||||
formItemLayout: {
|
||||
labelCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 8 },
|
||||
},
|
||||
wrapperCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 16 },
|
||||
},
|
||||
},
|
||||
config: {
|
||||
rules: [{ type: 'object', required: true, message: 'Please select time!' }],
|
||||
},
|
||||
rangeConfig: {
|
||||
rules: [{ type: 'array', required: true, message: 'Please select time!' }],
|
||||
},
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleSubmit (e) {
|
||||
e.preventDefault()
|
||||
|
||||
this.form.validateFields((err, fieldsValue) => {
|
||||
if (err) {
|
||||
return
|
||||
|
@ -41,91 +109,10 @@ const TimeRelatedForm = {
|
|||
})
|
||||
},
|
||||
},
|
||||
|
||||
render () {
|
||||
const { getFieldDecorator } = this.form
|
||||
const formItemLayout = {
|
||||
labelCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 8 },
|
||||
},
|
||||
wrapperCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 16 },
|
||||
},
|
||||
}
|
||||
const config = {
|
||||
rules: [{ type: 'object', required: true, message: 'Please select time!' }],
|
||||
}
|
||||
const rangeConfig = {
|
||||
rules: [{ type: 'array', required: true, message: 'Please select time!' }],
|
||||
}
|
||||
return (
|
||||
<a-form onSubmit={this.handleSubmit}>
|
||||
<a-form-item
|
||||
{...{ props: formItemLayout }}
|
||||
label='DatePicker'
|
||||
>
|
||||
{getFieldDecorator('date-picker', config)(
|
||||
<a-date-picker />
|
||||
)}
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
{...{ props: formItemLayout }}
|
||||
label='DatePicker[showTime]'
|
||||
>
|
||||
{getFieldDecorator('date-time-picker', config)(
|
||||
<a-date-picker showTime format='YYYY-MM-DD HH:mm:ss' />
|
||||
)}
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
{...{ props: formItemLayout }}
|
||||
label='MonthPicker'
|
||||
>
|
||||
{getFieldDecorator('month-picker', config)(
|
||||
<a-monthPicker />
|
||||
)}
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
{...{ props: formItemLayout }}
|
||||
label='RangePicker'
|
||||
>
|
||||
{getFieldDecorator('range-picker', rangeConfig)(
|
||||
<a-range-picker />
|
||||
)}
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
{...{ props: formItemLayout }}
|
||||
label='RangePicker[showTime]'
|
||||
>
|
||||
{getFieldDecorator('range-time-picker', rangeConfig)(
|
||||
<a-range-picker showTime format='YYYY-MM-DD HH:mm:ss' />
|
||||
)}
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
{...{ props: formItemLayout }}
|
||||
label='TimePicker'
|
||||
>
|
||||
{getFieldDecorator('time-picker', config)(
|
||||
<a-time-picker />
|
||||
)}
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
wrapperCol={{
|
||||
xs: { span: 24, offset: 0 },
|
||||
sm: { span: 16, offset: 8 },
|
||||
}}
|
||||
>
|
||||
<a-button type='primary' htmlType='submit'>Submit</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
)
|
||||
},
|
||||
}
|
||||
|
||||
export default Form.create()(TimeRelatedForm)
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -9,10 +9,162 @@ Demostration for validataion configuration for form controls which are not show
|
|||
</us>
|
||||
|
||||
|
||||
<script>
|
||||
import { Form } from 'ant-design-vue'
|
||||
<template>
|
||||
<a-form id='components-form-demo-validate-other' @submit="handleSubmit" :form="form">
|
||||
<a-form-item
|
||||
v-bind="formItemLayout"
|
||||
label='Plain Text'
|
||||
>
|
||||
<span class='ant-form-text'>China</span>
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
v-bind="formItemLayout"
|
||||
label='Select'
|
||||
hasFeedback
|
||||
>
|
||||
<a-select
|
||||
v-decorator="[
|
||||
'select',
|
||||
{rules: [{ required: true, message: 'Please select your country!' }]}
|
||||
]"
|
||||
placeholder='Please select a country'
|
||||
>
|
||||
<a-select-option value='china'>China</a-select-option>
|
||||
<a-select-option value='use'>U.S.A</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
|
||||
const Demo = {
|
||||
<a-form-item
|
||||
v-bind="formItemLayout"
|
||||
label='Select[multiple]'
|
||||
>
|
||||
<a-select
|
||||
v-decorator="[
|
||||
'select-multiple', {
|
||||
rules: [{ required: true, message: 'Please select your favourite colors!', type: 'array' }],
|
||||
}]"
|
||||
mode='multiple'
|
||||
placeholder='Please select favourite colors'
|
||||
>
|
||||
<a-select-option value='red'>Red</a-select-option>
|
||||
<a-select-option value='green'>Green</a-select-option>
|
||||
<a-select-option value='blue'>Blue</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item
|
||||
v-bind="formItemLayout"
|
||||
label='InputNumber'
|
||||
>
|
||||
<a-input-number v-decorator="['input-number', { initialValue: 3 }]" :min="1" :max="10" />
|
||||
<span class='ant-form-text'> machines</span>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item
|
||||
v-bind="formItemLayout"
|
||||
label='Switch'
|
||||
>
|
||||
<a-switch v-decorator="['switch', { valuePropName: 'checked' }]"/>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item
|
||||
v-bind="formItemLayout"
|
||||
label='Slider'
|
||||
>
|
||||
<a-slider v-decorator="['slider']" :marks="{ 0: 'A', 20: 'B', 40: 'C', 60: 'D', 80: 'E', 100: 'F' }" />
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item
|
||||
v-bind="formItemLayout"
|
||||
label='Radio.Group'
|
||||
>
|
||||
<a-radio-group v-decorator="['radio-group']">
|
||||
<a-radio value='a'>item 1</a-radio>
|
||||
<a-radio value='b'>item 2</a-radio>
|
||||
<a-radio value='c'>item 3</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item
|
||||
v-bind="formItemLayout"
|
||||
label='Radio.Button'
|
||||
>
|
||||
<a-radio-group v-decorator="['radio-button']">
|
||||
<a-radio-button value='a'>item 1</a-radio-button>
|
||||
<a-radio-button value='b'>item 2</a-radio-button>
|
||||
<a-radio-button value='c'>item 3</a-radio-button>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item
|
||||
v-bind="formItemLayout"
|
||||
label='Rate'
|
||||
>
|
||||
<a-rate allowHalf v-decorator="['rate', {initialValue: 3.5}]"/>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item
|
||||
v-bind="formItemLayout"
|
||||
label='Upload'
|
||||
extra='longgggggggggggggggggggggggggggggggggg'
|
||||
>
|
||||
<a-upload
|
||||
v-decorator="['upload', {
|
||||
valuePropName: 'fileList',
|
||||
getValueFromEvent: normFile,
|
||||
}]"
|
||||
name='logo'
|
||||
action='/upload.do'
|
||||
listType='picture'
|
||||
>
|
||||
<a-button>
|
||||
<a-icon type='upload' /> Click to upload
|
||||
</a-button>
|
||||
</a-upload>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item
|
||||
v-bind="formItemLayout"
|
||||
label='Dragger'
|
||||
>
|
||||
<div class='dropbox'>
|
||||
<a-upload-dragger
|
||||
v-decorator="['dragger', {
|
||||
valuePropName: 'fileList',
|
||||
getValueFromEvent: normFile,
|
||||
}]"
|
||||
name='files'
|
||||
action='/upload.do'
|
||||
>
|
||||
<p class='ant-upload-drag-icon'>
|
||||
<a-icon type='inbox' />
|
||||
</p>
|
||||
<p class='ant-upload-text'>Click or drag file to this area to upload</p>
|
||||
<p class='ant-upload-hint'>Support for a single or bulk upload.</p>
|
||||
</a-upload-dragger>
|
||||
</div>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item
|
||||
:wrapperCol="{ span: 12, offset: 6 }"
|
||||
>
|
||||
<a-button type='primary' htmlType='submit'>Submit</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
beforeCreate () {
|
||||
window.test = this
|
||||
this.form = this.$form.createForm(this)
|
||||
},
|
||||
data: () => ({
|
||||
formItemLayout: {
|
||||
labelCol: { span: 6 },
|
||||
wrapperCol: { span: 14 },
|
||||
},
|
||||
}),
|
||||
methods: {
|
||||
handleSubmit (e) {
|
||||
e.preventDefault()
|
||||
|
@ -30,168 +182,7 @@ const Demo = {
|
|||
return e && e.fileList
|
||||
},
|
||||
},
|
||||
|
||||
render () {
|
||||
const { getFieldDecorator } = this.form
|
||||
const formItemLayout = {
|
||||
labelCol: { span: 6 },
|
||||
wrapperCol: { span: 14 },
|
||||
}
|
||||
return (
|
||||
<a-form id='components-form-demo-validate-other' onSubmit={this.handleSubmit}>
|
||||
<a-form-item
|
||||
{...{ props: formItemLayout }}
|
||||
label='Plain Text'
|
||||
>
|
||||
<span class='ant-form-text'>China</span>
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
{...{ props: formItemLayout }}
|
||||
label='Select'
|
||||
hasFeedback
|
||||
>
|
||||
{getFieldDecorator('select', {
|
||||
rules: [
|
||||
{ required: true, message: 'Please select your country!' },
|
||||
],
|
||||
})(
|
||||
<a-select placeholder='Please select a country'>
|
||||
<a-select-option value='china'>China</a-select-option>
|
||||
<a-select-option value='use'>U.S.A</a-select-option>
|
||||
</a-select>
|
||||
)}
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item
|
||||
{...{ props: formItemLayout }}
|
||||
label='Select[multiple]'
|
||||
>
|
||||
{getFieldDecorator('select-multiple', {
|
||||
rules: [
|
||||
{ required: true, message: 'Please select your favourite colors!', type: 'array' },
|
||||
],
|
||||
})(
|
||||
<a-select mode='multiple' placeholder='Please select favourite colors'>
|
||||
<a-select-option value='red'>Red</a-select-option>
|
||||
<a-select-option value='green'>Green</a-select-option>
|
||||
<a-select-option value='blue'>Blue</a-select-option>
|
||||
</a-select>
|
||||
)}
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item
|
||||
{...{ props: formItemLayout }}
|
||||
label='InputNumber'
|
||||
>
|
||||
{getFieldDecorator('input-number', { initialValue: 3 })(
|
||||
<a-input-number min={1} max={10} />
|
||||
)}
|
||||
<span class='ant-form-text'> machines</span>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item
|
||||
{...{ props: formItemLayout }}
|
||||
label='Switch'
|
||||
>
|
||||
{getFieldDecorator('switch', { valuePropName: 'checked' })(
|
||||
<a-switch />
|
||||
)}
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item
|
||||
{...{ props: formItemLayout }}
|
||||
label='Slider'
|
||||
>
|
||||
{getFieldDecorator('slider')(
|
||||
<a-slider marks={{ 0: 'A', 20: 'B', 40: 'C', 60: 'D', 80: 'E', 100: 'F' }} />
|
||||
)}
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item
|
||||
{...{ props: formItemLayout }}
|
||||
label='Radio.Group'
|
||||
>
|
||||
{getFieldDecorator('radio-group')(
|
||||
<a-radio-group>
|
||||
<a-radio value='a'>item 1</a-radio>
|
||||
<a-radio value='b'>item 2</a-radio>
|
||||
<a-radio value='c'>item 3</a-radio>
|
||||
</a-radio-group>
|
||||
)}
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item
|
||||
{...{ props: formItemLayout }}
|
||||
label='Radio.Button'
|
||||
>
|
||||
{getFieldDecorator('radio-button')(
|
||||
<a-radio-group>
|
||||
<a-radio-button value='a'>item 1</a-radio-button>
|
||||
<a-radio-button value='b'>item 2</a-radio-button>
|
||||
<a-radio-button value='c'>item 3</a-radio-button>
|
||||
</a-radio-group>
|
||||
)}
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item
|
||||
{...{ props: formItemLayout }}
|
||||
label='Rate'
|
||||
>
|
||||
{getFieldDecorator('rate', {
|
||||
initialValue: 3.5,
|
||||
})(
|
||||
<a-rate allowHalf/>
|
||||
)}
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item
|
||||
{...{ props: formItemLayout }}
|
||||
label='Upload'
|
||||
extra='longgggggggggggggggggggggggggggggggggg'
|
||||
>
|
||||
{getFieldDecorator('upload', {
|
||||
valuePropName: 'fileList',
|
||||
getValueFromEvent: this.normFile,
|
||||
})(
|
||||
<a-upload name='logo' action='/upload.do' listType='picture'>
|
||||
<a-button>
|
||||
<a-icon type='upload' /> Click to upload
|
||||
</a-button>
|
||||
</a-upload>
|
||||
)}
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item
|
||||
{...{ props: formItemLayout }}
|
||||
label='Dragger'
|
||||
>
|
||||
<div class='dropbox'>
|
||||
{getFieldDecorator('dragger', {
|
||||
valuePropName: 'fileList',
|
||||
getValueFromEvent: this.normFile,
|
||||
})(
|
||||
<a-upload-dragger name='files' action='/upload.do'>
|
||||
<p class='ant-upload-drag-icon'>
|
||||
<a-icon type='inbox' />
|
||||
</p>
|
||||
<p class='ant-upload-text'>Click or drag file to this area to upload</p>
|
||||
<p class='ant-upload-hint'>Support for a single or bulk upload.</p>
|
||||
</a-upload-dragger>
|
||||
)}
|
||||
</div>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item
|
||||
wrapperCol={{ span: 12, offset: 6 }}
|
||||
>
|
||||
<a-button type='primary' htmlType='submit'>Submit</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
)
|
||||
},
|
||||
}
|
||||
|
||||
export default Form.create()(Demo)
|
||||
</script>
|
||||
<style>
|
||||
#components-form-demo-validate-other .dropbox {
|
||||
|
@ -203,3 +194,4 @@ export default Form.create()(Demo)
|
|||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,64 +1,53 @@
|
|||
|
||||
````html
|
||||
<Form.Item {...props}>
|
||||
{children}
|
||||
</Form.Item>
|
||||
````
|
||||
|
||||
## API
|
||||
|
||||
### Form
|
||||
|
||||
| Property | Description | Type | Default Value |
|
||||
| -------- | ----------- | ---- | ------------- |
|
||||
| form | Decorated by `Form.create()` will be automatically set `this.form` property, so just pass to form, you don't need to set it by yourself after 1.7.0. | object | n/a |
|
||||
| form | Decorated by `Form.create()` will be automatically set `this.form` property, so just pass to form. If you use the template syntax, you can use `this.$form.createForm(this, options)` | object | n/a |
|
||||
| hideRequiredMark | Hide required mark of all form items | Boolean | false |
|
||||
| layout | Define form layout(Support after 2.8) | 'horizontal'\|'vertical'\|'inline' | 'horizontal' |
|
||||
| autoFormCreate | Automate Form.create, Recommended for use under the `template` component, and cannot be used with `Form.create()` |Function(form)| |
|
||||
| options | The `options` corresponding to `Form.create(options)` | Object | {} |
|
||||
| autoFormCreate(deprecated) | Automate Form.create, Recommended for use under the `template` component, and cannot be used with `Form.create()`. You should use `$form.createForm` to instead it after 1.1.9. |Function(form)| |
|
||||
| options(deprecated) | The `options` corresponding to `Form.create(options)`. You should use `$form.createForm` to instead it after 1.1.9. | Object | {} |
|
||||
|
||||
### Events
|
||||
| Events Name | Description | Arguments |
|
||||
| --- | --- | --- |
|
||||
| submit | Defines a function will be called if form data validation is successful. | Function(e:Event) |
|
||||
|
||||
### autoFormCreate
|
||||
|
||||
````html
|
||||
<a-form :autoFormCreate="(form)=>{this.form = form}">
|
||||
...
|
||||
</a-form>
|
||||
````
|
||||
If you use the `template` syntax, you can use สปautoFormCreate` to turn on automatic validation and data collection, but each `Form.Item` only to `decorator` for its first child. More complex features suggest `JSX`.
|
||||
|
||||
Related examples are as follows:
|
||||
|
||||
[coordinated-controls](/ant-design-vue/components/form/#components-form-demo-coordinated-controls)
|
||||
|
||||
[dynamic-rules](/ant-design-vue/components/form/#components-form-demo-dynamic-rules)
|
||||
|
||||
[horizontal-login-form](/ant-design-vue/components/form/#components-form-demo-horizontal-login-form)
|
||||
|
||||
### Form.create(options)
|
||||
### Form.create(options) \| this.$form.createForm(this, options)
|
||||
|
||||
How to use๏ผ
|
||||
|
||||
#### Used in jsx, the usage is consistent with the React version of antd
|
||||
```jsx
|
||||
const CustomizedForm = {}
|
||||
|
||||
CustomizedForm = Form.create({})(CustomizedForm);
|
||||
```
|
||||
|
||||
Maintain an ref for wrapped component instance, use `wrappedComponentRef`.
|
||||
Example: [demo](#components-form-demo-advanced-search)
|
||||
|
||||
#### Single file template usage
|
||||
````html
|
||||
<template>
|
||||
<a-form :form="form" />
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
beforeCreate () {
|
||||
this.form = this.$form.createForm(this, options)
|
||||
},
|
||||
}
|
||||
</script>
|
||||
````
|
||||
|
||||
|
||||
The following `options` are available:
|
||||
|
||||
| Property | Description | Type |
|
||||
| -------- | ----------- | ---- |
|
||||
| props | declare props on form(ๅ[like vue props]( https://vuejs.org/v2/api/#props)) | {} |
|
||||
| mapPropsToFields | Convert props to field value(e.g. reading the values from Redux store). And you must mark returned fields with [`Form.createFormField`](#Form.createFormField) | (props) => Object{ fieldName: FormField { value } } |
|
||||
| props | Only supports the use of Form.create({})(CustomizedForm). declare props on form(ๅ[like vue props]( https://vuejs.org/v2/api/#props)) | {} |
|
||||
| mapPropsToFields | Convert props to field value(e.g. reading the values from Redux store). And you must mark returned fields with [`Form.createFormField`](#Form.createFormField). If you use `$form.createForm` to create a collector, you can map any data to the Field without being bound by the parent component. | (props) => Object{ fieldName: FormField { value } } |
|
||||
| validateMessages | Default validate message. And its format is similar with [newMessages](https://github.com/yiminghe/async-validator/blob/master/src/messages.js)'s returned value | Object { [nested.path]: String } |
|
||||
| onFieldsChange | Specify a function that will be called when the value a `Form.Item` gets changed. Usage example: saving the field's value to Redux store. | Function(props, fields) |
|
||||
| onValuesChange | A handler while value of any field is changed | (props, values) => void |
|
||||
|
@ -69,7 +58,7 @@ If the form has been decorated by `Form.create` then it has `this.form` property
|
|||
|
||||
| Method | Description | Type |
|
||||
| ------ | ----------- | ---- |
|
||||
| getFieldDecorator | Two-way binding for form, please read below for details. | |
|
||||
| getFieldDecorator | Two-way binding for form, single file template can be bound using the directive `v-decorator`. please read below for details. | |
|
||||
| getFieldError | Get the error of a field. | Function(name) |
|
||||
| getFieldsError | Get the specified fields' error. If you don't specify a parameter, you will get all fields' error. | Function(\[names: string\[]]) |
|
||||
| getFieldsValue | Get the specified fields' values. If you don't specify a parameter, you will get all fields' values. | Function(\[fieldNames: string\[]]) |
|
||||
|
@ -131,9 +120,9 @@ If the form has been decorated by `Form.create` then it has `this.form` property
|
|||
|
||||
To mark the returned fields data in `mapPropsToFields`, [demo](#components-form-demo-global-state).
|
||||
|
||||
### this.form.getFieldDecorator(id, options)
|
||||
### this.form.getFieldDecorator(id, options) and v-decorator="[id, options]"
|
||||
|
||||
After wrapped by `getFieldDecorator`, `value`(or other property defined by `valuePropName`) `onChange`(or other property defined by `trigger`) props will be added to form controls๏ผthe flow of form data will be handled by Form which will cause:
|
||||
After wrapped by `getFieldDecorator` or `v-decorator`, `value`(or other property defined by `valuePropName`) `onChange`(or other property defined by `trigger`) props will be added to form controls๏ผthe flow of form data will be handled by Form which will cause:
|
||||
|
||||
1. You shouldn't use `onChange` to collect data, but you still can listen to `onChange`(and so on) events.
|
||||
2. You can not set value of form control via `value` `defaultValue` prop, and you should set default value with `initialValue` in `getFieldDecorator` instead.
|
||||
|
@ -141,10 +130,10 @@ After wrapped by `getFieldDecorator`, `value`(or other property defined by `valu
|
|||
|
||||
#### Special attention
|
||||
|
||||
1. `getFieldDecorator` can not be used to decorate stateless component.
|
||||
2. you can't use `getFieldDecorator` in stateless component: <https://vuejs.org/v2/api/#functional>
|
||||
1. `getFieldDecorator` and `v-decorator` can not be used to decorate stateless component.
|
||||
2. you can't use `getFieldDecorator` and `v-decorator` in stateless component: <https://vuejs.org/v2/api/#functional>
|
||||
|
||||
#### getFieldDecorator(id, options) parameters
|
||||
#### getFieldDecorator(id, options) and v-decorator="[id, options]" parameters
|
||||
|
||||
| Property | Description | Type | Default Value |
|
||||
| -------- | ----------- | ---- | ------------- |
|
||||
|
@ -162,7 +151,7 @@ After wrapped by `getFieldDecorator`, `value`(or other property defined by `valu
|
|||
|
||||
Note:
|
||||
|
||||
- If Form.Item has multiple children that had been decorated by `getFieldDecorator`, `help` and `required` and `validateStatus` can't be generated automatically.
|
||||
- If Form.Item has multiple children that had been decorated by `getFieldDecorator` or `v-decorator`, `help` and `required` and `validateStatus` can't be generated automatically.
|
||||
|
||||
| Property | Description | Type | Default Value |
|
||||
| -------- | ----------- | ---- | ------------- |
|
||||
|
@ -175,8 +164,6 @@ Note:
|
|||
| required | Whether provided or not, it will be generated by the validation rule. | boolean | false |
|
||||
| validateStatus | The validation status. If not provided, it will be generated by validation rule. options: 'success' 'warning' 'error' 'validating' | string | |
|
||||
| wrapperCol | The layout for input controls, same as `labelCol` | [object](/ant-design-vue/components/grid/#Col) | |
|
||||
| fieldDecoratorId | Corresponds to the first parameter `id` of `getFieldDecorator(id, options)`. If you need to collect data, you need to set this field. | string | |
|
||||
| fieldDecoratorOptions | Corresponds to the second parameter `options` of `getFieldDecorator(id, options)`. | object | {} |
|
||||
|
||||
### Validation Rules
|
||||
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
import Vue from 'vue'
|
||||
import Form from './Form'
|
||||
import ref from 'vue-ref'
|
||||
import FormDecoratorDirective from '../_util/FormDecoratorDirective'
|
||||
|
||||
Vue.use(ref, { name: 'ant-ref' })
|
||||
Vue.use(FormDecoratorDirective)
|
||||
|
||||
export { FormProps, FormCreateOption, ValidationRule } from './Form'
|
||||
export { FormItemProps } from './FormItem'
|
||||
|
@ -11,6 +13,7 @@ export { FormItemProps } from './FormItem'
|
|||
Form.install = function (Vue) {
|
||||
Vue.component(Form.name, Form)
|
||||
Vue.component(Form.Item.name, Form.Item)
|
||||
Vue.prototype.$form = Form
|
||||
}
|
||||
|
||||
export default Form
|
||||
|
|
|
@ -1,64 +1,51 @@
|
|||
|
||||
````html
|
||||
<Form.Item {...props}>
|
||||
{children}
|
||||
</Form.Item>
|
||||
````
|
||||
|
||||
## API
|
||||
|
||||
### Form
|
||||
|
||||
| ๅๆฐ | ่ฏดๆ | ็ฑปๅ | ้ป่ฎคๅผ |
|
||||
| --- | --- | --- | --- |
|
||||
| form | ็ป `Form.create()` ๅ
่ฃ
่ฟ็็ปไปถไผ่ชๅธฆ `this.form` ๅฑๆง๏ผ็ดๆฅไผ ็ป Form ๅณๅฏใๆ ้ๆๅจ่ฎพ็ฝฎ | object | ๆ |
|
||||
| form | ็ป `Form.create()` ๅ
่ฃ
่ฟ็็ปไปถไผ่ชๅธฆ `this.form` ๅฑๆง๏ผๅฆๆไฝฟ็จtemplate่ฏญๆณ๏ผๅฏไปฅไฝฟ็จthis.$form.createForm(this, options) | object | ๆ |
|
||||
| hideRequiredMark | ้่ๆๆ่กจๅ้กน็ๅฟ
้ๆ ่ฎฐ | Boolean | false |
|
||||
| layout | ่กจๅๅธๅฑ | 'horizontal'\|'vertical'\|'inline' | 'horizontal' |
|
||||
| autoFormCreate | ่ชๅจๆง่กForm.create๏ผๅปบ่ฎฎๅจtemplate็ปไปถไธไฝฟ็จ๏ผๅนถไธไธๅฏไปฅๅ`Form.create()`ๅๆถไฝฟ็จ |Function(form)| ๆ |
|
||||
| options | ๅฏนๅบForm.create(options)็`options` | Object | {} |
|
||||
|
||||
### ไบไปถ
|
||||
| ไบไปถๅ็งฐ | ่ฏดๆ | ๅ่ฐๅๆฐ |
|
||||
| --- | --- | --- |
|
||||
| submit | ๆฐๆฎ้ช่ฏๆๅๅๅ่ฐไบไปถ | Function(e:Event) |
|
||||
|
||||
### autoFormCreate
|
||||
|
||||
````html
|
||||
<a-form :autoFormCreate="(form)=>{this.form = form}">
|
||||
...
|
||||
</a-form>
|
||||
````
|
||||
ๅฆๆไฝฟ็จ`template`่ฏญๆณ๏ผๅฏไปฅไฝฟ็จ`autoFormCreate`ๅผๅฏ่ชๅจๆ ก้ชๅๆฐๆฎๆถ้ๅ่ฝ๏ผไฝๆฏไธไธช`Form.Item`ไป
ไป
ๅฏนๅ
ถ็ฌฌไธไธชๅญ็ปไปถ่ฟ่ก`decorator`ใๆดๅ ๅคๆ็ๅ่ฝๅปบ่ฎฎไฝฟ็จ`JSX`ใ
|
||||
|
||||
็ธๅ
ณ็คบไพๅฆไธ๏ผ
|
||||
|
||||
[coordinated-controls](/ant-design-vue/components/form-cn/#components-form-demo-coordinated-controls)
|
||||
|
||||
[dynamic-rules](/ant-design-vue/components/form-cn/#components-form-demo-dynamic-rules)
|
||||
|
||||
[horizontal-login-form](/ant-design-vue/components/form-cn/#components-form-demo-horizontal-login-form)
|
||||
|
||||
### Form.create(options)
|
||||
### Form.create(options) \| this.$form.createForm(this, options)
|
||||
|
||||
ไฝฟ็จๆนๅผๅฆไธ๏ผ
|
||||
|
||||
#### jsxไฝฟ็จๆนๅผ๏ผไฝฟ็จๆนๅผๅReact็antdไธ่ด
|
||||
```jsx
|
||||
const CustomizedForm = {}
|
||||
|
||||
CustomizedForm = Form.create({})(CustomizedForm);
|
||||
```
|
||||
|
||||
ๅฆๆ้่ฆไธบๅ
่ฃ
็ปไปถๅฎไพ็ปดๆคไธไธชref๏ผๅฏไปฅไฝฟ็จ`wrappedComponentRef`ใ
|
||||
ๅ่[็คบไพ](#components-form-demo-advanced-search)
|
||||
|
||||
#### ๅๆไปถtemplateไฝฟ็จๆนๅผ
|
||||
````html
|
||||
<template>
|
||||
<a-form :form="form" />
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
beforeCreate () {
|
||||
this.form = this.$form.createForm(this, options)
|
||||
},
|
||||
}
|
||||
</script>
|
||||
````
|
||||
|
||||
|
||||
`options` ็้
็ฝฎ้กนๅฆไธใ
|
||||
|
||||
| ๅๆฐ | ่ฏดๆ | ็ฑปๅ |
|
||||
| --- | --- | --- |
|
||||
| props | ็ถ็ปไปถ้่ฆๆ ๅฐๅฐ่กจๅ้กนไธ็ๅฑๆงๅฃฐๆ(ๅ[vue็ปไปถpropsไธ่ด]( https://vuejs.org/v2/api/#props)) | {} |
|
||||
| mapPropsToFields | ๆ็ถ็ปไปถ็ๅฑๆงๆ ๅฐๅฐ่กจๅ้กนไธ๏ผๅฆ๏ผๆ Redux store ไธญ็ๅผ่ฏปๅบ๏ผ๏ผ้่ฆๅฏน่ฟๅๅผไธญ็่กจๅๅๆฐๆฎ็จ [`Form.createFormField`](#Form.createFormField) ๆ ่ฎฐ | (props) => Object{ fieldName: FormField { value } } |
|
||||
| props | ไป
ไป
ๆฏๆForm.create({})(CustomizedForm)็ไฝฟ็จๆนๅผ๏ผ็ถ็ปไปถ้่ฆๆ ๅฐๅฐ่กจๅ้กนไธ็ๅฑๆงๅฃฐๆ(ๅ[vue็ปไปถpropsไธ่ด]( https://vuejs.org/v2/api/#props)) | {} |
|
||||
| mapPropsToFields | ๆ็ถ็ปไปถ็ๅฑๆงๆ ๅฐๅฐ่กจๅ้กนไธ๏ผๅฆ๏ผๆ Redux store ไธญ็ๅผ่ฏปๅบ๏ผ๏ผ้่ฆๅฏน่ฟๅๅผไธญ็่กจๅๅๆฐๆฎ็จ [`Form.createFormField`](#Form.createFormField) ๆ ่ฎฐ๏ผๅฆๆไฝฟ็จ$form.createFormๅๅปบๆถ้ๅจ๏ผไฝ ๅฏไปฅๅฐไปปไฝๆฐๆฎๆ ๅฐๅฐFieldไธญ๏ผไธๅ็ถ็ปไปถ็บฆๆ | (props) => Object{ fieldName: FormField { value } } |
|
||||
| validateMessages | ้ป่ฎคๆ ก้ชไฟกๆฏ๏ผๅฏ็จไบๆ้ป่ฎค้่ฏฏไฟกๆฏๆนไธบไธญๆ็ญ๏ผๆ ผๅผไธ [newMessages](https://github.com/yiminghe/async-validator/blob/master/src/messages.js) ่ฟๅๅผไธ่ด | Object { [nested.path]: String } |
|
||||
| onFieldsChange | ๅฝ `Form.Item` ๅญ่็น็ๅผๅ็ๆนๅๆถ่งฆๅ๏ผๅฏไปฅๆๅฏนๅบ็ๅผ่ฝฌๅญๅฐ Redux store | Function(props, fields) |
|
||||
| onValuesChange | ไปปไธ่กจๅๅ็ๅผๅ็ๆนๅๆถ็ๅ่ฐ | (props, values) => void |
|
||||
|
@ -69,7 +56,7 @@ CustomizedForm = Form.create({})(CustomizedForm);
|
|||
|
||||
| ๆนๆณย ย ย | ่ฏดๆ ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย | ็ฑปๅ ย ย ย |
|
||||
| ------- | -------------------------------------- | -------- |
|
||||
| getFieldDecorator | ็จไบๅ่กจๅ่ฟ่กๅๅ็ปๅฎ๏ผ่ฏฆ่งไธๆนๆ่ฟฐ | |
|
||||
| getFieldDecorator | ็จไบๅ่กจๅ่ฟ่กๅๅ็ปๅฎ๏ผๅๆไปถtemplateๅฏไปฅไฝฟ็จๆไปค`v-decorator`่ฟ่ก็ปๅฎ๏ผ่ฏฆ่งไธๆนๆ่ฟฐ | |
|
||||
| getFieldError | ่ทๅๆไธช่พๅ
ฅๆงไปถ็ Error | Function(name) |
|
||||
| getFieldsError | ่ทๅไธ็ป่พๅ
ฅๆงไปถ็ Error ๏ผๅฆไธไผ ๅ
ฅๅๆฐ๏ผๅ่ทๅๅ
จ้จ็ปไปถ็ Error | Function(\[names: string\[]]) |
|
||||
| getFieldsValue | ่ทๅไธ็ป่พๅ
ฅๆงไปถ็ๅผ๏ผๅฆไธไผ ๅ
ฅๅๆฐ๏ผๅ่ทๅๅ
จ้จ็ปไปถ็ๅผ | Function(\[fieldNames: string\[]]) |
|
||||
|
@ -131,9 +118,9 @@ CustomizedForm = Form.create({})(CustomizedForm);
|
|||
|
||||
็จไบๆ ่ฎฐ `mapPropsToFields` ่ฟๅ็่กจๅๅๆฐๆฎ๏ผ[ไพๅญ](#components-form-demo-global-state)ใ
|
||||
|
||||
### this.form.getFieldDecorator(id, options)
|
||||
### this.form.getFieldDecorator(id, options) ๅ v-decorator="[id, options]"
|
||||
|
||||
็ป่ฟ `getFieldDecorator` ๅ
่ฃ
็ๆงไปถ๏ผ่กจๅๆงไปถไผ่ชๅจๆทปๅ `value`๏ผๆ `valuePropName` ๆๅฎ็ๅ
ถไปๅฑๆง๏ผ `onChange`๏ผๆ `trigger` ๆๅฎ็ๅ
ถไปๅฑๆง๏ผ๏ผๆฐๆฎๅๆญฅๅฐ่ขซ Form ๆฅ็ฎก๏ผ่ฟไผๅฏผ่ดไปฅไธ็ปๆ๏ผ
|
||||
็ป่ฟ `getFieldDecorator`ๆ`v-decorator` ๅ
่ฃ
็ๆงไปถ๏ผ่กจๅๆงไปถไผ่ชๅจๆทปๅ `value`๏ผๆ `valuePropName` ๆๅฎ็ๅ
ถไปๅฑๆง๏ผ `onChange`๏ผๆ `trigger` ๆๅฎ็ๅ
ถไปๅฑๆง๏ผ๏ผๆฐๆฎๅๆญฅๅฐ่ขซ Form ๆฅ็ฎก๏ผ่ฟไผๅฏผ่ดไปฅไธ็ปๆ๏ผ
|
||||
|
||||
1. ไฝ **ไธๅ้่ฆไนไธๅบ่ฏฅ**็จ `onChange` ๆฅๅๅๆญฅ๏ผไฝ่ฟๆฏๅฏไปฅ็ปง็ปญ็ๅฌ `onChange` ็ญไบไปถใ
|
||||
2. ไฝ ไธ่ฝ็จๆงไปถ็ `value` `defaultValue` ็ญๅฑๆงๆฅ่ฎพ็ฝฎ่กจๅๅ็ๅผ๏ผ้ป่ฎคๅผๅฏไปฅ็จ `getFieldDecorator` ้็ `initialValue`ใ
|
||||
|
@ -141,10 +128,10 @@ CustomizedForm = Form.create({})(CustomizedForm);
|
|||
|
||||
#### ็นๅซๆณจๆ
|
||||
|
||||
1. `getFieldDecorator` ไธ่ฝ็จไบ่ฃ
้ฅฐ็บฏๅฝๆฐ็ปไปถใ
|
||||
2. `getFieldDecorator` ่ฐ็จไธ่ฝไฝไบ็บฏๅฝๆฐ็ปไปถไธญ <https://cn.vuejs.org/v2/api/#functional>ใ
|
||||
1. `getFieldDecorator`ๅ`v-decorator` ไธ่ฝ็จไบ่ฃ
้ฅฐ็บฏๅฝๆฐ็ปไปถใ
|
||||
2. `getFieldDecorator`ๅ`v-decorator` ่ฐ็จไธ่ฝไฝไบ็บฏๅฝๆฐ็ปไปถไธญ <https://cn.vuejs.org/v2/api/#functional>ใ
|
||||
|
||||
#### getFieldDecorator(id, options) ๅๆฐ
|
||||
#### getFieldDecorator(id, options) ๅ v-decorator="[id, options]" ๅๆฐ
|
||||
|
||||
| ๅๆฐ | ่ฏดๆ | ็ฑปๅ | ้ป่ฎคๅผ |
|
||||
| --- | --- | --- | --- |
|
||||
|
@ -162,7 +149,7 @@ CustomizedForm = Form.create({})(CustomizedForm);
|
|||
|
||||
ๆณจๆ๏ผ
|
||||
|
||||
- ไธไธช Form.Item ๅปบ่ฎฎๅชๆพไธไธช่ขซ getFieldDecorator ่ฃ
้ฅฐ่ฟ็ child๏ผๅฝๆๅคไธช่ขซ่ฃ
้ฅฐ่ฟ็ child ๆถ๏ผ`help` `required` `validateStatus` ๆ ๆณ่ชๅจ็ๆใ
|
||||
- ไธไธช Form.Item ๅปบ่ฎฎๅชๆพไธไธช่ขซ getFieldDecoratorๆv-decorator ่ฃ
้ฅฐ่ฟ็ child๏ผๅฝๆๅคไธช่ขซ่ฃ
้ฅฐ่ฟ็ child ๆถ๏ผ`help` `required` `validateStatus` ๆ ๆณ่ชๅจ็ๆใ
|
||||
|
||||
| ๅๆฐ | ่ฏดๆ | ็ฑปๅ | ้ป่ฎคๅผ |
|
||||
| --- | --- | --- | --- |
|
||||
|
@ -175,8 +162,6 @@ CustomizedForm = Form.create({})(CustomizedForm);
|
|||
| required | ๆฏๅฆๅฟ
ๅกซ๏ผๅฆไธ่ฎพ็ฝฎ๏ผๅไผๆ นๆฎๆ ก้ช่งๅ่ชๅจ็ๆ | boolean | false |
|
||||
| validateStatus | ๆ ก้ช็ถๆ๏ผๅฆไธ่ฎพ็ฝฎ๏ผๅไผๆ นๆฎๆ ก้ช่งๅ่ชๅจ็ๆ๏ผๅฏ้๏ผ'success' 'warning' 'error' 'validating' | string | |
|
||||
| wrapperCol | ้่ฆไธบ่พๅ
ฅๆงไปถ่ฎพ็ฝฎๅธๅฑๆ ทๅผๆถ๏ผไฝฟ็จ่ฏฅๅฑๆง๏ผ็จๆณๅ labelCol | [object](/ant-design-vue/components/grid-cn/#Col) | |
|
||||
| fieldDecoratorId | ๅฏนๅบ`getFieldDecorator(id, options)`็็ฌฌไธไธชๅๆฐ`id`๏ผๅฆ้ๆถ้ๆฐๆฎ้่ฆ่ฎพ็ฝฎ่ฏฅๅญๆฎต | string | ๆ |
|
||||
| fieldDecoratorOptions | ๅฏนๅบ`getFieldDecorator(id, options)`็็ฌฌไบไธชๅๆฐ`options` | object | {} |
|
||||
|
||||
### ๆ ก้ช่งๅ
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@ const getStepsProps = (defaultProps = {}) => {
|
|||
PropTypes.bool,
|
||||
PropTypes.func,
|
||||
]),
|
||||
labelPlacement: PropTypes.string.def('horizontal'),
|
||||
}
|
||||
return initDefaultProps(props, defaultProps)
|
||||
}
|
||||
|
|
|
@ -10,31 +10,37 @@ export const TimelineProps = {
|
|||
/** ๆๅฎๆๅไธไธชๅนฝ็ต่็นๆฏๅฆๅญๅจๆๅ
ๅฎน */
|
||||
pending: PropTypes.any,
|
||||
pendingDot: PropTypes.string,
|
||||
reverse: PropTypes.bool,
|
||||
mode: PropTypes.oneOf(['left', 'alternate', 'right']),
|
||||
}
|
||||
|
||||
export default {
|
||||
name: 'ATimeline',
|
||||
props: initDefaultProps(TimelineProps, {
|
||||
prefixCls: 'ant-timeline',
|
||||
reverse: false,
|
||||
}),
|
||||
render () {
|
||||
const { prefixCls, ...restProps } = getOptionProps(this)
|
||||
const { prefixCls, reverse, mode, ...restProps } = getOptionProps(this)
|
||||
const pendingDot = getComponentFromProp(this, 'pendingDot')
|
||||
const pending = getComponentFromProp(this, 'pending')
|
||||
const pendingNode = typeof pending === 'boolean' ? null : pending
|
||||
const classString = classNames(prefixCls, {
|
||||
[`${prefixCls}-pending`]: !!pending,
|
||||
[`${prefixCls}-reverse`]: !!reverse,
|
||||
[`${prefixCls}-${mode}`]: !!mode,
|
||||
})
|
||||
// Remove falsy items
|
||||
const falsylessItems = filterEmpty(this.$slots.default)
|
||||
const items = falsylessItems.map((item, idx) => {
|
||||
return cloneElement(item, {
|
||||
props: {
|
||||
last: falsylessItems.length - 1 === idx,
|
||||
},
|
||||
})
|
||||
})
|
||||
const pendingItem = (pending) ? (
|
||||
const children = filterEmpty(this.$slots.default)
|
||||
// // Remove falsy items
|
||||
// const falsylessItems = filterEmpty(this.$slots.default)
|
||||
// const items = falsylessItems.map((item, idx) => {
|
||||
// return cloneElement(item, {
|
||||
// props: {
|
||||
// last: falsylessItems.length - 1 === idx,
|
||||
// },
|
||||
// })
|
||||
// })
|
||||
const pendingItem = !!pending ? (
|
||||
<TimelineItem
|
||||
pending={!!pending}
|
||||
>
|
||||
|
@ -44,6 +50,28 @@ export default {
|
|||
{pendingNode}
|
||||
</TimelineItem>
|
||||
) : null
|
||||
|
||||
const timeLineItems = !!reverse
|
||||
? [pendingItem, ...children.reverse()]
|
||||
: [...children, pendingItem]
|
||||
|
||||
// Remove falsy items
|
||||
const truthyItems = timeLineItems.filter(item => !!item)
|
||||
const itemsCount = truthyItems.length
|
||||
const lastCls = `${prefixCls}-item-last`
|
||||
const items = truthyItems.map((ele, idx) =>
|
||||
cloneElement(ele, {
|
||||
class: classNames([
|
||||
(!reverse && !!pending)
|
||||
? (idx === itemsCount - 2) ? lastCls : ''
|
||||
: (idx === itemsCount - 1) ? lastCls : '',
|
||||
(mode === 'alternate')
|
||||
? (idx % 2 === 0) ? `${prefixCls}-item-left` : `${prefixCls}-item-right`
|
||||
: (mode === 'right') ? `${prefixCls}-item-right` : '',
|
||||
]),
|
||||
}),
|
||||
)
|
||||
|
||||
const timelineProps = {
|
||||
props: {
|
||||
...restProps,
|
||||
|
@ -54,7 +82,6 @@ export default {
|
|||
return (
|
||||
<ul {...timelineProps}>
|
||||
{items}
|
||||
{pendingItem}
|
||||
</ul>
|
||||
)
|
||||
},
|
||||
|
|
|
@ -1,5 +1,44 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`renders ./components/timeline/demo/alternate.md correctly 1`] = `
|
||||
<ul class="ant-timeline ant-timeline-alternate">
|
||||
<li class="ant-timeline-item ant-timeline-item-left">
|
||||
<div class="ant-timeline-item-tail"></div>
|
||||
<div class="ant-timeline-item-head ant-timeline-item-head-blue"></div>
|
||||
<div class="ant-timeline-item-content">Create a services site 2015-09-01</div>
|
||||
</li>
|
||||
<li class="ant-timeline-item ant-timeline-item-right">
|
||||
<div class="ant-timeline-item-tail"></div>
|
||||
<div class="ant-timeline-item-head ant-timeline-item-head-green"></div>
|
||||
<div class="ant-timeline-item-content">Solve initial network problems 2015-09-01</div>
|
||||
</li>
|
||||
<li class="ant-timeline-item ant-timeline-item-left">
|
||||
<div class="ant-timeline-item-tail"></div>
|
||||
<div class="ant-timeline-item-head ant-timeline-item-head-custom ant-timeline-item-head-blue"><i class="anticon anticon-clock-circle-o" style="font-size: 16px;"></i></div>
|
||||
<div class="ant-timeline-item-content">
|
||||
Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo.
|
||||
</div>
|
||||
</li>
|
||||
<li class="ant-timeline-item ant-timeline-item-right">
|
||||
<div class="ant-timeline-item-tail"></div>
|
||||
<div class="ant-timeline-item-head ant-timeline-item-head-red"></div>
|
||||
<div class="ant-timeline-item-content">Network problems being solved 2015-09-01</div>
|
||||
</li>
|
||||
<li class="ant-timeline-item ant-timeline-item-left">
|
||||
<div class="ant-timeline-item-tail"></div>
|
||||
<div class="ant-timeline-item-head ant-timeline-item-head-blue"></div>
|
||||
<div class="ant-timeline-item-content">Create a services site 2015-09-01</div>
|
||||
</li>
|
||||
<li class="ant-timeline-item ant-timeline-item-last ant-timeline-item-right">
|
||||
<div class="ant-timeline-item-tail"></div>
|
||||
<div class="ant-timeline-item-head ant-timeline-item-head-custom ant-timeline-item-head-blue"><i class="anticon anticon-clock-circle-o" style="font-size: 16px;"></i></div>
|
||||
<div class="ant-timeline-item-content">
|
||||
Technical testing 2015-09-01
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/timeline/demo/basic.md correctly 1`] = `
|
||||
<ul class="ant-timeline">
|
||||
<li class="ant-timeline-item">
|
||||
|
@ -17,7 +56,7 @@ exports[`renders ./components/timeline/demo/basic.md correctly 1`] = `
|
|||
<div class="ant-timeline-item-head ant-timeline-item-head-blue"></div>
|
||||
<div class="ant-timeline-item-content">Technical testing 2015-09-01</div>
|
||||
</li>
|
||||
<li class="ant-timeline-item">
|
||||
<li class="ant-timeline-item ant-timeline-item-last">
|
||||
<div class="ant-timeline-item-tail"></div>
|
||||
<div class="ant-timeline-item-head ant-timeline-item-head-blue"></div>
|
||||
<div class="ant-timeline-item-content">Network problems being solved 2015-09-01</div>
|
||||
|
@ -46,7 +85,7 @@ exports[`renders ./components/timeline/demo/color.md correctly 1`] = `
|
|||
<p>Solve initial network problems 3 2015-09-01</p>
|
||||
</div>
|
||||
</li>
|
||||
<li class="ant-timeline-item">
|
||||
<li class="ant-timeline-item ant-timeline-item-last">
|
||||
<div class="ant-timeline-item-tail"></div>
|
||||
<div class="ant-timeline-item-head ant-timeline-item-head-blue"></div>
|
||||
<div class="ant-timeline-item-content">
|
||||
|
@ -80,7 +119,7 @@ exports[`renders ./components/timeline/demo/custom.md correctly 1`] = `
|
|||
Technical testing 2015-09-01
|
||||
</div>
|
||||
</li>
|
||||
<li class="ant-timeline-item">
|
||||
<li class="ant-timeline-item ant-timeline-item-last">
|
||||
<div class="ant-timeline-item-tail"></div>
|
||||
<div class="ant-timeline-item-head ant-timeline-item-head-blue"></div>
|
||||
<div class="ant-timeline-item-content">Network problems being solved 2015-09-01</div>
|
||||
|
@ -89,23 +128,52 @@ exports[`renders ./components/timeline/demo/custom.md correctly 1`] = `
|
|||
`;
|
||||
|
||||
exports[`renders ./components/timeline/demo/pending.md correctly 1`] = `
|
||||
<ul class="ant-timeline ant-timeline-pending">
|
||||
<li class="ant-timeline-item">
|
||||
<div>
|
||||
<ul class="ant-timeline ant-timeline-pending">
|
||||
<li class="ant-timeline-item">
|
||||
<div class="ant-timeline-item-tail"></div>
|
||||
<div class="ant-timeline-item-head ant-timeline-item-head-blue"></div>
|
||||
<div class="ant-timeline-item-content">Create a services site 2015-09-01</div>
|
||||
</li>
|
||||
<li class="ant-timeline-item">
|
||||
<div class="ant-timeline-item-tail"></div>
|
||||
<div class="ant-timeline-item-head ant-timeline-item-head-blue"></div>
|
||||
<div class="ant-timeline-item-content">Solve initial network problems 2015-09-01</div>
|
||||
</li>
|
||||
<li class="ant-timeline-item ant-timeline-item-last">
|
||||
<div class="ant-timeline-item-tail"></div>
|
||||
<div class="ant-timeline-item-head ant-timeline-item-head-blue"></div>
|
||||
<div class="ant-timeline-item-content">Technical testing 2015-09-01</div>
|
||||
</li>
|
||||
<li class="ant-timeline-item ant-timeline-item-pending">
|
||||
<div class="ant-timeline-item-tail"></div>
|
||||
<div class="ant-timeline-item-head ant-timeline-item-head-custom ant-timeline-item-head-blue"><i class="anticon anticon-loading anticon-spin"></i></div>
|
||||
<div class="ant-timeline-item-content">Recording...</div>
|
||||
</li>
|
||||
</ul> <button type="button" class="ant-btn ant-btn-primary" style="margin-top: 16px;"><span>Toggle Reverse</span></button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/timeline/demo/right.md correctly 1`] = `
|
||||
<ul class="ant-timeline ant-timeline-right">
|
||||
<li class="ant-timeline-item ant-timeline-item-right">
|
||||
<div class="ant-timeline-item-tail"></div>
|
||||
<div class="ant-timeline-item-head ant-timeline-item-head-blue"></div>
|
||||
<div class="ant-timeline-item-content">Create a services site 2015-09-01</div>
|
||||
</li>
|
||||
<li class="ant-timeline-item">
|
||||
<li class="ant-timeline-item ant-timeline-item-right">
|
||||
<div class="ant-timeline-item-tail"></div>
|
||||
<div class="ant-timeline-item-head ant-timeline-item-head-blue"></div>
|
||||
<div class="ant-timeline-item-content">Solve initial network problems 2015-09-01</div>
|
||||
</li>
|
||||
<li class="ant-timeline-item">
|
||||
<li class="ant-timeline-item ant-timeline-item-right">
|
||||
<div class="ant-timeline-item-tail"></div>
|
||||
<div class="ant-timeline-item-head ant-timeline-item-head-blue"></div>
|
||||
<div class="ant-timeline-item-content">Technical testing 2015-09-01</div>
|
||||
<div class="ant-timeline-item-head ant-timeline-item-head-custom ant-timeline-item-head-blue"><i class="anticon anticon-clock-circle-o" style="font-size: 16px;"></i></div>
|
||||
<div class="ant-timeline-item-content">
|
||||
Technical testing 2015-09-01
|
||||
</div>
|
||||
</li>
|
||||
<li class="ant-timeline-item ant-timeline-item-pending">
|
||||
<li class="ant-timeline-item ant-timeline-item-last ant-timeline-item-right">
|
||||
<div class="ant-timeline-item-tail"></div>
|
||||
<div class="ant-timeline-item-head ant-timeline-item-head-custom ant-timeline-item-head-blue"><i class="anticon anticon-loading"><svg viewBox="0 0 1024 1024" data-icon="loading" width="1em" height="1em" fill="currentColor" aria-hidden="true" class="anticon-spin">
|
||||
<path d="M988 548c-19.9 0-36-16.1-36-36 0-59.4-11.6-117-34.6-171.3a440.45 440.45 0 0 0-94.3-139.9 437.71 437.71 0 0 0-139.9-94.3C629 83.6 571.4 72 512 72c-19.9 0-36-16.1-36-36s16.1-36 36-36c69.1 0 136.2 13.5 199.3 40.3C772.3 66 827 103 874 150c47 47 83.9 101.8 109.7 162.7 26.7 63.1 40.2 130.2 40.2 199.3.1 19.9-16 36-35.9 36z"></path>
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
<cn>
|
||||
#### ไบคๆฟๅฑ็ฐ
|
||||
ๅ
ๅฎนๅจๆถ้ด่ฝดไธคไพง่ฝฎๆตๅบ็ฐใ
|
||||
</cn>
|
||||
|
||||
<us>
|
||||
#### Alternate
|
||||
Alternate timeline.
|
||||
</us>
|
||||
|
||||
```html
|
||||
<template>
|
||||
<a-timeline mode="alternate">
|
||||
<a-timeline-item>Create a services site 2015-09-01</a-timeline-item>
|
||||
<a-timeline-item color="green">Solve initial network problems 2015-09-01</a-timeline-item>
|
||||
<a-timeline-item>
|
||||
<a-icon slot="dot" type="clock-circle-o" style="font-size: 16px;" />
|
||||
Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo.
|
||||
</a-timeline-item>
|
||||
<a-timeline-item color="red">Network problems being solved 2015-09-01</a-timeline-item>
|
||||
<a-timeline-item>Create a services site 2015-09-01</a-timeline-item>
|
||||
<a-timeline-item>
|
||||
<a-icon slot="dot" type="clock-circle-o" style="font-size: 16px;" />
|
||||
Technical testing 2015-09-01
|
||||
</a-timeline-item>
|
||||
</a-timeline>
|
||||
</template>
|
||||
```
|
||||
|
||||
|
|
@ -3,6 +3,8 @@ import Basic from './basic.md'
|
|||
import Color from './color.md'
|
||||
import Pending from './pending.md'
|
||||
import Custom from './custom.md'
|
||||
import Alternate from './alternate'
|
||||
import Right from './right'
|
||||
import CN from '../index.zh-CN.md'
|
||||
import US from '../index.en-US.md'
|
||||
|
||||
|
@ -32,15 +34,12 @@ export default {
|
|||
return (
|
||||
<div>
|
||||
<md cn={md.cn} us={md.us}/>
|
||||
<br/>
|
||||
<Basic />
|
||||
<br/>
|
||||
<Color />
|
||||
<br/>
|
||||
<Pending />
|
||||
<br/>
|
||||
<Custom />
|
||||
<br/>
|
||||
<Alternate />
|
||||
<Right />
|
||||
<api>
|
||||
<template slot='cn'>
|
||||
<CN/>
|
||||
|
|
|
@ -1,21 +1,39 @@
|
|||
<cn>
|
||||
#### ๆๅไธไธช
|
||||
ๅฝไปปๅก็ถๆๆญฃๅจๅ็๏ผ่ฟๅจ่ฎฐๅฝ่ฟ็จไธญ๏ผๅฏ็จๅนฝ็ต่็นๆฅ่กจ็คบๅฝๅ็ๆถ้ด่็น๏ผ็จไบๆถ้ดๆญฃๅบๆๅ๏ผใๅฝ pending ๅผไธบ false ๏ผๅฏ็จๅฎๅถๅ
ไปถๆฟๆข้ป่ฎคๆถ้ดๅพ็นใ
|
||||
#### ๆๅไธไธชๅๆๅบ
|
||||
ๅฝไปปๅก็ถๆๆญฃๅจๅ็๏ผ่ฟๅจ่ฎฐๅฝ่ฟ็จไธญ๏ผๅฏ็จๅนฝ็ต่็นๆฅ่กจ็คบๅฝๅ็ๆถ้ด่็น๏ผๅฝ pending ไธบ็ๅผๆถๅฑ็คบๅนฝ็ต่็น๏ผๅฆๆ pending ๆฏ React ๅ
็ด ๅฏ็จไบๅฎๅถ่ฏฅ่็นๅ
ๅฎน๏ผๅๆถ pendingDot ๅฐๅฏไปฅ็จไบๅฎๅถๅ
ถ่ฝด็นใreverse ๅฑๆง็จไบๆงๅถ่็นๆๅบ๏ผไธบ false ๆถๆๆญฃๅบๆๅ๏ผไธบ true ๆถๆๅๅบๆๅใ
|
||||
</cn>
|
||||
|
||||
<us>
|
||||
#### Last node
|
||||
When the timeline is incomplete and ongoing, put a ghost node at last. set `pending={true}` or `pending={a VNode Element}` or `slot="pending"`. Used in ascend chronological order. When `pending` is not false, set `pendingDot={a VNode Element}` or `slot="pendingDot"` to replace the default pending dot.
|
||||
When the timeline is incomplete and ongoing, put a ghost node at last. Set `pending` as truthy value to enable displaying pending item. You can customize the pending content by passing a React Element. Meanwhile, `slot="pendingDot"` is used to customize the dot of the pending item.
|
||||
`reverse={true}` is used for reversing nodes.
|
||||
</us>
|
||||
|
||||
```html
|
||||
<template>
|
||||
<a-timeline pending="Recording...">
|
||||
<div>
|
||||
<a-timeline pending="Recording..." :reverse="reverse">
|
||||
<a-timeline-item>Create a services site 2015-09-01</a-timeline-item>
|
||||
<a-timeline-item>Solve initial network problems 2015-09-01</a-timeline-item>
|
||||
<a-timeline-item>Technical testing 2015-09-01</a-timeline-item>
|
||||
</a-timeline>
|
||||
<a-button type="primary" style="margin-top: 16px" @click="handleClick">Toggle Reverse</a-button>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
reverse: false,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleClick(){
|
||||
this.reverse = !this.reverse
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
<cn>
|
||||
#### ๅณไพงๆถ้ด่ฝด็น
|
||||
ๆถ้ด่ฝด็นๅฏไปฅๅจๅ
ๅฎน็ๅณ่พนใ
|
||||
</cn>
|
||||
|
||||
<us>
|
||||
#### Right alternate
|
||||
Right alternate timeline.
|
||||
</us>
|
||||
|
||||
```html
|
||||
<template>
|
||||
<a-timeline mode="right">
|
||||
<a-timeline-item>Create a services site 2015-09-01</a-timeline-item>
|
||||
<a-timeline-item>Solve initial network problems 2015-09-01</a-timeline-item>
|
||||
<a-timeline-item>
|
||||
<a-icon slot="dot" type="clock-circle-o" style="font-size: 16px;" />
|
||||
Technical testing 2015-09-01
|
||||
</a-timeline-item>
|
||||
<a-timeline-item>Network problems being solved 2015-09-01</a-timeline-item>
|
||||
</a-timeline>
|
||||
</template>
|
||||
```
|
||||
|
||||
|
|
@ -17,6 +17,9 @@ Timeline
|
|||
| -------- | ----------- | ---- | ------- |
|
||||
| pending | Set the last ghost node's existence or its content | boolean\|string\|slot | `false` |
|
||||
| pendingDot | Set the dot of the last ghost node when pending is true | string\|slot | `<Icon type="loading" />` |
|
||||
| reverse | reverse nodes or not | boolean | false |
|
||||
| mode | By sending `alternate` the timeline will distribute the nodes to the left and right. | `left` \| `alternate` \| `right` | `left` |
|
||||
|
||||
|
||||
### Timeline.Item
|
||||
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
| --- | --- | --- | --- |
|
||||
| pending | ๆๅฎๆๅไธไธชๅนฝ็ต่็นๆฏๅฆๅญๅจๆๅ
ๅฎน | boolean\|string\|slot | false |
|
||||
| pendingDot | ๅฝๆๅไธไธชๅนฝ็ต่็นๅญๅจๆ๏ผๆๅฎๅ
ถๆถ้ดๅพ็น | string\|slot | `<Icon type="loading" />` |
|
||||
| reverse | ่็นๆๅบ | boolean | false |
|
||||
| mode | ้่ฟ่ฎพ็ฝฎ `mode` ๅฏไปฅๆนๅๆถ้ด่ฝดๅๅ
ๅฎน็็ธๅฏนไฝ็ฝฎ | `left` \| `alternate` \| `right` |
|
||||
|
||||
### Timeline.Item
|
||||
|
||||
|
|
|
@ -37,7 +37,6 @@ function createBaseForm (option = {}, mixins = []) {
|
|||
props = {},
|
||||
templateContext,
|
||||
} = option
|
||||
|
||||
return function decorate (WrappedComponent) {
|
||||
let formProps = {}
|
||||
if (Array.isArray(props)) {
|
||||
|
@ -83,7 +82,7 @@ function createBaseForm (option = {}, mixins = []) {
|
|||
submitting: false,
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
watch: templateContext ? {} : {
|
||||
'$props': {
|
||||
handler: function (nextProps) {
|
||||
if (mapPropsToFields) {
|
||||
|
@ -105,6 +104,12 @@ function createBaseForm (option = {}, mixins = []) {
|
|||
this.wrappedComponentRef(null)
|
||||
},
|
||||
methods: {
|
||||
updateFields (fields = {}) {
|
||||
this.fieldsStore.updateFields(mapPropsToFields(fields))
|
||||
if (templateContext) {
|
||||
templateContext.$forceUpdate()
|
||||
}
|
||||
},
|
||||
onCollectCommon (name, action, args) {
|
||||
const fieldMeta = this.fieldsStore.getFieldMeta(name)
|
||||
if (fieldMeta[action]) {
|
||||
|
@ -607,9 +612,11 @@ function createBaseForm (option = {}, mixins = []) {
|
|||
on: $listeners,
|
||||
ref: 'WrappedComponent',
|
||||
}
|
||||
return <WrappedComponent {...wrappedComponentProps}>{$slots.default}</WrappedComponent>
|
||||
|
||||
return WrappedComponent ? <WrappedComponent {...wrappedComponentProps}>{$slots.default}</WrappedComponent> : null
|
||||
},
|
||||
}
|
||||
if (!WrappedComponent) return Form
|
||||
if (Array.isArray(WrappedComponent.props)) {
|
||||
const newProps = {}
|
||||
WrappedComponent.props.forEach((prop) => {
|
||||
|
|
|
@ -92,6 +92,7 @@ export const SelectPropTypes = {
|
|||
treeIcon: PropTypes.bool,
|
||||
treeLine: PropTypes.bool,
|
||||
treeDefaultExpandAll: PropTypes.bool,
|
||||
treeDefaultExpandedKeys: PropTypes.arrayOf(String),
|
||||
treeCheckable: PropTypes.any, // bool vnode
|
||||
treeNodeLabelProp: PropTypes.string,
|
||||
treeNodeFilterProp: PropTypes.string,
|
||||
|
|
|
@ -21,6 +21,16 @@ import {
|
|||
* other props can pass with context for future refactor.
|
||||
*/
|
||||
|
||||
function getWatch (keys = []) {
|
||||
const watch = {}
|
||||
keys.forEach(k => {
|
||||
watch[k] = function () {
|
||||
this.needSyncKeys[k] = true
|
||||
}
|
||||
})
|
||||
return watch
|
||||
}
|
||||
|
||||
const Tree = {
|
||||
name: 'Tree',
|
||||
mixins: [BaseMixin],
|
||||
|
@ -91,6 +101,7 @@ const Tree = {
|
|||
}),
|
||||
|
||||
data () {
|
||||
this.needSyncKeys = {}
|
||||
const state = {
|
||||
_posEntities: {},
|
||||
_keyEntities: {},
|
||||
|
@ -124,8 +135,10 @@ const Tree = {
|
|||
},
|
||||
|
||||
watch: {
|
||||
...getWatch(['treeData', 'children', 'expandedKeys', 'autoExpandParent', 'selectedKeys', 'checkedKeys', 'loadedKeys']),
|
||||
__propsSymbol__ () {
|
||||
this.setState(this.getDerivedStateFromProps(getOptionProps(this), this.$data))
|
||||
this.needSyncKeys = {}
|
||||
},
|
||||
},
|
||||
|
||||
|
@ -135,9 +148,9 @@ const Tree = {
|
|||
const newState = {
|
||||
_prevProps: { ...props },
|
||||
}
|
||||
|
||||
const self = this
|
||||
function needSync (name) {
|
||||
return (!_prevProps && name in props) || (_prevProps && _prevProps[name] !== props[name])
|
||||
return (!_prevProps && name in props) || (_prevProps && self.needSyncKeys[name])
|
||||
}
|
||||
|
||||
// ================== Tree Node ==================
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "ant-design-vue",
|
||||
"version": "1.1.9",
|
||||
"version": "1.1.10",
|
||||
"title": "Ant Design Vue",
|
||||
"description": "An enterprise-class UI design language and Vue-based implementation",
|
||||
"keywords": [
|
||||
|
@ -181,7 +181,7 @@
|
|||
"resize-observer-polyfill": "^1.5.0",
|
||||
"shallow-equal": "^1.0.0",
|
||||
"shallowequal": "^1.0.2",
|
||||
"vue-ref": "^1.0.2",
|
||||
"vue-ref": "^1.0.3",
|
||||
"warning": "^3.0.0"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,11 +18,13 @@
|
|||
</style>
|
||||
<script>
|
||||
var _hmt = _hmt || [];
|
||||
var isGithub = location.host.indexOf('github') !== -1;
|
||||
var src = isGithub ? 'https://hm.baidu.com/hm.js?b3ef688fa86bfb75027f1b410180a867' : 'https://hm.baidu.com/hm.js?1564b57c5b8f74933e4fedca9dc75b0d';
|
||||
(function() {
|
||||
const hm = document.createElement('script')
|
||||
hm.src = 'https://hm.baidu.com/hm.js?b3ef688fa86bfb75027f1b410180a867'
|
||||
const s = document.getElementsByTagName('script')[0]
|
||||
s.parentNode.insertBefore(hm, s)
|
||||
var hm = document.createElement('script');
|
||||
hm.src = src;
|
||||
var s = document.getElementsByTagName('script')[0];
|
||||
s.parentNode.insertBefore(hm, s);
|
||||
})()
|
||||
</script>
|
||||
</head>
|
||||
|
@ -50,4 +52,4 @@
|
|||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
</html>
|
||||
|
|
Loadingโฆ
Reference in New Issue