Browse Source

feat: update vc-form

pull/22/head
tangjinzhou 7 years ago
parent
commit
07b0d46864
  1. 1
      antd-tools/getBabelCommonConfig.js
  2. 66
      components/vc-form/demo/input-array.jsx
  3. 11
      components/vc-form/demo/styles.js
  4. 822
      components/vc-form/src/createBaseForm.jsx
  5. 71
      components/vc-form/src/createDOMForm.jsx
  6. 44
      components/vc-form/src/createForm.jsx
  7. 9
      components/vc-form/src/utils.js
  8. 325
      package.json
  9. 2
      site/routes.js

1
antd-tools/getBabelCommonConfig.js

@ -7,6 +7,7 @@ module.exports = function (modules) {
require.resolve('babel-plugin-transform-es3-property-literals'),
require.resolve('babel-plugin-transform-object-assign'),
require.resolve('babel-plugin-transform-object-rest-spread'),
require.resolve('babel-plugin-transform-class-properties'),
]
plugins.push([require.resolve('babel-plugin-transform-runtime'), {
polyfill: false,

66
components/vc-form/demo/input-array.jsx

@ -0,0 +1,66 @@
/* eslint no-console:0 */
import { createForm } from '../index'
import { regionStyle } from './styles'
let uuid = 0
const Form = {
props: {
form: Object,
},
methods: {
remove (k) {
const { form } = this
// can use data-binding to get
let keys = form.getFieldValue('keys')
keys = keys.filter((key) => {
return key !== k
})
// can use data-binding to set
form.setFieldsValue({
keys,
})
},
add () {
uuid++
const { form } = this
// can use data-binding to get
let keys = form.getFieldValue('keys')
keys = keys.concat(uuid)
// can use data-binding to set
// important! notify form to detect changes
form.setFieldsValue({
keys,
})
},
submit (e) {
e.preventDefault()
console.log(this.form.getFieldsValue())
},
},
render () {
const { getFieldProps, getFieldValue } = this.form
getFieldProps('keys', {
initialValue: [],
})
const inputs = getFieldValue('keys').map((k) => {
return (<div key={k} style={ regionStyle }>
<input {...getFieldProps(`name${k}`)}/>
<a
onClick={this.remove.bind(this, k)}
>delete</a></div>)
})
return (<div>
{inputs}
<div style={ regionStyle }>
<button onClick={this.submit}>submit</button>
<button onClick={this.add}>add</button>
</div>
</div>)
},
}
export default createForm()(Form)

11
components/vc-form/demo/styles.js

@ -0,0 +1,11 @@
export const regionStyle = {
border: '1px solid red',
marginTop: '10px',
padding: '10px',
}
export const errorStyle = {
color: 'red',
marginTop: '10px',
padding: '10px',
}

822
components/vc-form/src/createBaseForm.jsx

@ -1,10 +1,11 @@
import createReactClass from 'create-react-class'
import AsyncValidator from 'async-validator'
import warning from 'warning'
import get from 'lodash/get'
import set from 'lodash/set'
import createFieldsStore from './createFieldsStore'
import { cloneElement } from '../../_util/vnode'
import BaseMixin from '../../_util/BaseMixin'
import PropTypes from '../../_util/vue-types'
import {
argumentContainer,
identity,
@ -35,11 +36,14 @@ function createBaseForm (option = {}, mixins = []) {
} = option
return function decorate (WrappedComponent) {
const Form = createReactClass({
mixins,
getInitialState () {
const fields = mapPropsToFields && mapPropsToFields(this.props)
const Form = {
mixins: [BaseMixin, ...mixins],
props: {
hideRequiredMark: PropTypes.bool,
layout: PropTypes.string,
},
data () {
const fields = mapPropsToFields && mapPropsToFields(this.$props)
this.fieldsStore = createFieldsStore(fields || {})
this.instances = {}
@ -56,13 +60,6 @@ function createBaseForm (option = {}, mixins = []) {
'isFieldsTouched',
'isFieldTouched'].forEach(key => {
this[key] = (...args) => {
if (process.env.NODE_ENV !== 'production') {
warning(
false,
'you should not use `ref` on enhanced form, please use `wrappedComponentRef`. ' +
'See: https://github.com/react-component/form#note-use-wrappedcomponentref-instead-of-withref-after-rc-form140'
)
}
return this.fieldsStore[key](...args)
}
})
@ -71,456 +68,465 @@ function createBaseForm (option = {}, mixins = []) {
submitting: false,
}
},
componentWillReceiveProps (nextProps) {
if (mapPropsToFields) {
this.fieldsStore.updateFields(mapPropsToFields(nextProps))
}
watch: {
'$props': {
handler: function (nextProps) {
if (mapPropsToFields) {
this.fieldsStore.updateFields(mapPropsToFields(nextProps))
}
},
deep: true,
},
},
methods: {
onCollectCommon (name, action, args) {
const fieldMeta = this.fieldsStore.getFieldMeta(name)
if (fieldMeta[action]) {
fieldMeta[action](...args)
} else if (fieldMeta.originalProps && fieldMeta.originalProps[action]) {
fieldMeta.originalProps[action](...args)
}
const value = fieldMeta.getValueFromEvent
? fieldMeta.getValueFromEvent(...args)
: getValueFromEvent(...args)
if (onValuesChange && value !== this.fieldsStore.getFieldValue(name)) {
const valuesAll = this.fieldsStore.getAllValues()
const valuesAllSet = {}
valuesAll[name] = value
Object.keys(valuesAll).forEach(key => set(valuesAllSet, key, valuesAll[key]))
onValuesChange(this.props, set({}, name, value), valuesAllSet)
}
const field = this.fieldsStore.getField(name)
return ({ name, field: { ...field, value, touched: true }, fieldMeta })
},
onCollectCommon (name, action, args) {
const fieldMeta = this.fieldsStore.getFieldMeta(name)
if (fieldMeta[action]) {
fieldMeta[action](...args)
} else if (fieldMeta.originalProps && fieldMeta.originalProps[action]) {
fieldMeta.originalProps[action](...args)
}
const value = fieldMeta.getValueFromEvent
? fieldMeta.getValueFromEvent(...args)
: getValueFromEvent(...args)
if (onValuesChange && value !== this.fieldsStore.getFieldValue(name)) {
const valuesAll = this.fieldsStore.getAllValues()
const valuesAllSet = {}
valuesAll[name] = value
Object.keys(valuesAll).forEach(key => set(valuesAllSet, key, valuesAll[key]))
onValuesChange(this.props, set({}, name, value), valuesAllSet)
}
const field = this.fieldsStore.getField(name)
return ({ name, field: { ...field, value, touched: true }, fieldMeta })
},
onCollect (name_, action, ...args) {
const { name, field, fieldMeta } = this.onCollectCommon(name_, action, args)
const { validate } = fieldMeta
const newField = {
...field,
dirty: hasRules(validate),
}
this.setFields({
[name]: newField,
})
},
onCollect (name_, action, ...args) {
const { name, field, fieldMeta } = this.onCollectCommon(name_, action, args)
const { validate } = fieldMeta
const newField = {
...field,
dirty: hasRules(validate),
}
this.setFields({
[name]: newField,
})
},
onCollectValidate (name_, action, ...args) {
const { field, fieldMeta } = this.onCollectCommon(name_, action, args)
const newField = {
...field,
dirty: true,
}
this.validateFieldsInternal([newField], {
action,
options: {
firstFields: !!fieldMeta.validateFirst,
},
})
},
onCollectValidate (name_, action, ...args) {
const { field, fieldMeta } = this.onCollectCommon(name_, action, args)
const newField = {
...field,
dirty: true,
}
this.validateFieldsInternal([newField], {
action,
options: {
firstFields: !!fieldMeta.validateFirst,
},
})
},
getCacheBind (name, action, fn) {
if (!this.cachedBind[name]) {
this.cachedBind[name] = {}
}
const cache = this.cachedBind[name]
if (!cache[action]) {
cache[action] = fn.bind(this, name, action)
}
return cache[action]
},
getCacheBind (name, action, fn) {
if (!this.cachedBind[name]) {
this.cachedBind[name] = {}
}
const cache = this.cachedBind[name]
if (!cache[action]) {
cache[action] = fn.bind(this, name, action)
}
return cache[action]
},
recoverClearedField (name) {
if (this.clearedFieldMetaCache[name]) {
this.fieldsStore.setFields({
[name]: this.clearedFieldMetaCache[name].field,
})
this.fieldsStore.setFieldMeta(name, this.clearedFieldMetaCache[name].meta)
delete this.clearedFieldMetaCache[name]
}
},
recoverClearedField (name) {
if (this.clearedFieldMetaCache[name]) {
this.fieldsStore.setFields({
[name]: this.clearedFieldMetaCache[name].field,
})
this.fieldsStore.setFieldMeta(name, this.clearedFieldMetaCache[name].meta)
delete this.clearedFieldMetaCache[name]
}
},
getFieldDecorator (name, fieldOption) {
const { ref, ...restProps } = this.getFieldProps(name, fieldOption)
return (fieldElem) => {
const fieldMeta = this.fieldsStore.getFieldMeta(name)
const originalProps = fieldElem.props
if (process.env.NODE_ENV !== 'production') {
const valuePropName = fieldMeta.valuePropName
warning(
!(valuePropName in originalProps),
`\`getFieldDecorator\` will override \`${valuePropName}\`, ` +
`so please don't set \`${valuePropName}\` directly ` +
`and use \`setFieldsValue\` to set it.`
)
const defaultValuePropName =
`default${valuePropName[0].toUpperCase()}${valuePropName.slice(1)}`
warning(
!(defaultValuePropName in originalProps),
`\`${defaultValuePropName}\` is invalid ` +
`for \`getFieldDecorator\` will set \`${valuePropName}\`,` +
` please use \`option.initialValue\` instead.`
)
}
fieldMeta.originalProps = originalProps
fieldMeta.ref = fieldElem.ref
return cloneElement(fieldElem, {
props: {
...restProps,
...this.fieldsStore.getFieldValuePropValue(fieldMeta),
},
ref,
})
}
},
getFieldDecorator (name, fieldOption) {
const props = this.getFieldProps(name, fieldOption)
return (fieldElem) => {
const fieldMeta = this.fieldsStore.getFieldMeta(name)
const originalProps = fieldElem.props
getFieldProps (name, usersFieldOption = {}) {
if (!name) {
throw new Error('Must call `getFieldProps` with valid name string!')
}
if (process.env.NODE_ENV !== 'production') {
const valuePropName = fieldMeta.valuePropName
warning(
!(valuePropName in originalProps),
`\`getFieldDecorator\` will override \`${valuePropName}\`, ` +
`so please don't set \`${valuePropName}\` directly ` +
`and use \`setFieldsValue\` to set it.`
this.fieldsStore.isValidNestedFieldName(name),
'One field name cannot be part of another, e.g. `a` and `a.b`.'
)
const defaultValuePropName =
`default${valuePropName[0].toUpperCase()}${valuePropName.slice(1)}`
warning(
!(defaultValuePropName in originalProps),
`\`${defaultValuePropName}\` is invalid ` +
`for \`getFieldDecorator\` will set \`${valuePropName}\`,` +
` please use \`option.initialValue\` instead.`
!('exclusive' in usersFieldOption),
'`option.exclusive` of `getFieldProps`|`getFieldDecorator` had been remove.'
)
}
fieldMeta.originalProps = originalProps
fieldMeta.ref = fieldElem.ref
return cloneElement(fieldElem, {
...props,
...this.fieldsStore.getFieldValuePropValue(fieldMeta),
})
}
},
getFieldProps (name, usersFieldOption = {}) {
if (!name) {
throw new Error('Must call `getFieldProps` with valid name string!')
}
if (process.env.NODE_ENV !== 'production') {
warning(
this.fieldsStore.isValidNestedFieldName(name),
'One field name cannot be part of another, e.g. `a` and `a.b`.'
)
warning(
!('exclusive' in usersFieldOption),
'`option.exclusive` of `getFieldProps`|`getFieldDecorator` had been remove.'
)
}
delete this.clearedFieldMetaCache[name]
const fieldOption = {
name,
trigger: DEFAULT_TRIGGER,
valuePropName: 'value',
validate: [],
...usersFieldOption,
}
const {
rules,
trigger,
validateTrigger = trigger,
validate,
} = fieldOption
const fieldMeta = this.fieldsStore.getFieldMeta(name)
if ('initialValue' in fieldOption) {
fieldMeta.initialValue = fieldOption.initialValue
}
const inputProps = {
...this.fieldsStore.getFieldValuePropValue(fieldOption),
ref: this.getCacheBind(name, `${name}__ref`, this.saveRef),
}
if (fieldNameProp) {
inputProps[fieldNameProp] = name
}
delete this.clearedFieldMetaCache[name]
const validateRules = normalizeValidateRules(validate, rules, validateTrigger)
const validateTriggers = getValidateTriggers(validateRules)
validateTriggers.forEach((action) => {
if (inputProps[action]) return
inputProps[action] = this.getCacheBind(name, action, this.onCollectValidate)
})
const fieldOption = {
name,
trigger: DEFAULT_TRIGGER,
valuePropName: 'value',
validate: [],
...usersFieldOption,
}
// make sure that the value will be collect
if (trigger && validateTriggers.indexOf(trigger) === -1) {
inputProps[trigger] = this.getCacheBind(name, trigger, this.onCollect)
}
const {
rules,
trigger,
validateTrigger = trigger,
validate,
} = fieldOption
const meta = {
...fieldMeta,
...fieldOption,
validate: validateRules,
}
this.fieldsStore.setFieldMeta(name, meta)
if (fieldMetaProp) {
inputProps[fieldMetaProp] = meta
}
const fieldMeta = this.fieldsStore.getFieldMeta(name)
if ('initialValue' in fieldOption) {
fieldMeta.initialValue = fieldOption.initialValue
}
if (fieldDataProp) {
inputProps[fieldDataProp] = this.fieldsStore.getField(name)
}
const inputProps = {
...this.fieldsStore.getFieldValuePropValue(fieldOption),
ref: name,
}
const saveRef = this.getCacheBind(name, `${name}__ref`, this.saveRef)
this.$nextTick(() => {
if (this.instances[name] !== this.$refs[name]) {
this.$refs[name].destroyed = () => {
this.$refs[name].destroyed()
// after destroy, delete data
this.clearedFieldMetaCache[name] = {
field: this.fieldsStore.getField(name),
meta: this.fieldsStore.getFieldMeta(name),
}
this.fieldsStore.clearField(name)
delete this.instances[name]
delete this.cachedBind[name]
}
}
saveRef(name, `${name}__ref`, this.$refs[name])
})
if (fieldNameProp) {
inputProps[fieldNameProp] = name
}
return inputProps
},
const validateRules = normalizeValidateRules(validate, rules, validateTrigger)
const validateTriggers = getValidateTriggers(validateRules)
validateTriggers.forEach((action) => {
if (inputProps[action]) return
inputProps[action] = this.getCacheBind(name, action, this.onCollectValidate)
})
getFieldInstance (name) {
return this.instances[name]
},
// make sure that the value will be collect
if (trigger && validateTriggers.indexOf(trigger) === -1) {
inputProps[trigger] = this.getCacheBind(name, trigger, this.onCollect)
}
getRules (fieldMeta, action) {
const actionRules = fieldMeta.validate.filter((item) => {
return !action || item.trigger.indexOf(action) >= 0
}).map((item) => item.rules)
return flattenArray(actionRules)
},
const meta = {
...fieldMeta,
...fieldOption,
validate: validateRules,
}
this.fieldsStore.setFieldMeta(name, meta)
if (fieldMetaProp) {
inputProps[fieldMetaProp] = meta
}
setFields (maybeNestedFields, callback) {
const fields = this.fieldsStore.flattenRegisteredFields(maybeNestedFields)
this.fieldsStore.setFields(fields)
if (onFieldsChange) {
const changedFields = Object.keys(fields)
.reduce((acc, name) => set(acc, name, this.fieldsStore.getField(name)), {})
onFieldsChange(this.props, changedFields, this.fieldsStore.getNestedAllFields())
}
this.forceUpdate(callback)
},
if (fieldDataProp) {
inputProps[fieldDataProp] = this.fieldsStore.getField(name)
}
resetFields (ns) {
const newFields = this.fieldsStore.resetFields(ns)
if (Object.keys(newFields).length > 0) {
this.setFields(newFields)
}
if (ns) {
const names = Array.isArray(ns) ? ns : [ns]
names.forEach(name => delete this.clearedFieldMetaCache[name])
} else {
this.clearedFieldMetaCache = {}
}
},
return inputProps
},
getFieldInstance (name) {
return this.instances[name]
},
getRules (fieldMeta, action) {
const actionRules = fieldMeta.validate.filter((item) => {
return !action || item.trigger.indexOf(action) >= 0
}).map((item) => item.rules)
return flattenArray(actionRules)
},
setFields (maybeNestedFields, callback) {
const fields = this.fieldsStore.flattenRegisteredFields(maybeNestedFields)
this.fieldsStore.setFields(fields)
if (onFieldsChange) {
const changedFields = Object.keys(fields)
.reduce((acc, name) => set(acc, name, this.fieldsStore.getField(name)), {})
onFieldsChange(this.props, changedFields, this.fieldsStore.getNestedAllFields())
}
this.forceUpdate(callback)
},
setFieldsValue (changedValues, callback) {
const { fieldsMeta } = this.fieldsStore
const values = this.fieldsStore.flattenRegisteredFields(changedValues)
const newFields = Object.keys(values).reduce((acc, name) => {
const isRegistered = fieldsMeta[name]
if (process.env.NODE_ENV !== 'production') {
warning(
isRegistered,
'Cannot use `setFieldsValue` until ' +
'you use `getFieldDecorator` or `getFieldProps` to register it.'
)
resetFields (ns) {
const newFields = this.fieldsStore.resetFields(ns)
if (Object.keys(newFields).length > 0) {
this.setFields(newFields)
}
if (isRegistered) {
const value = values[name]
acc[name] = {
value,
}
if (ns) {
const names = Array.isArray(ns) ? ns : [ns]
names.forEach(name => delete this.clearedFieldMetaCache[name])
} else {
this.clearedFieldMetaCache = {}
}
return acc
}, {})
this.setFields(newFields, callback)
if (onValuesChange) {
const allValues = this.fieldsStore.getAllValues()
onValuesChange(this.props, changedValues, allValues)
}
},
},
saveRef (name, _, component) {
if (!component) {
// after destroy, delete data
this.clearedFieldMetaCache[name] = {
field: this.fieldsStore.getField(name),
meta: this.fieldsStore.getFieldMeta(name),
setFieldsValue (changedValues, callback) {
const { fieldsMeta } = this.fieldsStore
const values = this.fieldsStore.flattenRegisteredFields(changedValues)
const newFields = Object.keys(values).reduce((acc, name) => {
const isRegistered = fieldsMeta[name]
if (process.env.NODE_ENV !== 'production') {
warning(
isRegistered,
'Cannot use `setFieldsValue` until ' +
'you use `getFieldDecorator` or `getFieldProps` to register it.'
)
}
if (isRegistered) {
const value = values[name]
acc[name] = {
value,
}
}
return acc
}, {})
this.setFields(newFields, callback)
if (onValuesChange) {
const allValues = this.fieldsStore.getAllValues()
onValuesChange(this.props, changedValues, allValues)
}
this.fieldsStore.clearField(name)
delete this.instances[name]
delete this.cachedBind[name]
return
}
this.recoverClearedField(name)
const fieldMeta = this.fieldsStore.getFieldMeta(name)
if (fieldMeta) {
const ref = fieldMeta.ref
if (ref) {
if (typeof ref === 'string') {
throw new Error(`can not set ref string for ${name}`)
},
saveRef (name, _, component) {
this.recoverClearedField(name)
const fieldMeta = this.fieldsStore.getFieldMeta(name)
if (fieldMeta) {
const ref = fieldMeta.ref
if (ref) {
if (typeof ref === 'string') {
throw new Error(`can not set ref string for ${name}`)
}
ref(component)
}
ref(component)
}
}
this.instances[name] = component
},
this.instances[name] = component
},
validateFieldsInternal (fields, {
fieldNames,
action,
options = {},
}, callback) {
const allRules = {}
const allValues = {}
const allFields = {}
const alreadyErrors = {}
fields.forEach((field) => {
const name = field.name
if (options.force !== true && field.dirty === false) {
if (field.errors) {
set(alreadyErrors, name, { errors: field.errors })
validateFieldsInternal (fields, {
fieldNames,
action,
options = {},
}, callback) {
const allRules = {}
const allValues = {}
const allFields = {}
const alreadyErrors = {}
fields.forEach((field) => {
const name = field.name
if (options.force !== true && field.dirty === false) {
if (field.errors) {
set(alreadyErrors, name, { errors: field.errors })
}
return
}
const fieldMeta = this.fieldsStore.getFieldMeta(name)
const newField = {
...field,
}
newField.errors = undefined
newField.validating = true
newField.dirty = true
allRules[name] = this.getRules(fieldMeta, action)
allValues[name] = newField.value
allFields[name] = newField
})
this.setFields(allFields)
// in case normalize
Object.keys(allValues).forEach((f) => {
allValues[f] = this.fieldsStore.getFieldValue(f)
})
if (callback && isEmptyObject(allFields)) {
callback(isEmptyObject(alreadyErrors) ? null : alreadyErrors,
this.fieldsStore.getFieldsValue(fieldNames))
return
}
const fieldMeta = this.fieldsStore.getFieldMeta(name)
const newField = {
...field,
const validator = new AsyncValidator(allRules)
if (validateMessages) {
validator.messages(validateMessages)
}
newField.errors = undefined
newField.validating = true
newField.dirty = true
allRules[name] = this.getRules(fieldMeta, action)
allValues[name] = newField.value
allFields[name] = newField
})
this.setFields(allFields)
// in case normalize
Object.keys(allValues).forEach((f) => {
allValues[f] = this.fieldsStore.getFieldValue(f)
})
if (callback && isEmptyObject(allFields)) {
callback(isEmptyObject(alreadyErrors) ? null : alreadyErrors,
this.fieldsStore.getFieldsValue(fieldNames))
return
}
const validator = new AsyncValidator(allRules)
if (validateMessages) {
validator.messages(validateMessages)
}
validator.validate(allValues, options, (errors) => {
const errorsGroup = {
...alreadyErrors,
}
if (errors && errors.length) {
errors.forEach((e) => {
const fieldName = e.field
const field = get(errorsGroup, fieldName)
if (typeof field !== 'object' || Array.isArray(field)) {
set(errorsGroup, fieldName, { errors: [] })
validator.validate(allValues, options, (errors) => {
const errorsGroup = {
...alreadyErrors,
}
if (errors && errors.length) {
errors.forEach((e) => {
const fieldName = e.field
const field = get(errorsGroup, fieldName)
if (typeof field !== 'object' || Array.isArray(field)) {
set(errorsGroup, fieldName, { errors: [] })
}
const fieldErrors = get(errorsGroup, fieldName.concat('.errors'))
fieldErrors.push(e)
})
}
const expired = []
const nowAllFields = {}
Object.keys(allRules).forEach((name) => {
const fieldErrors = get(errorsGroup, name)
const nowField = this.fieldsStore.getField(name)
// avoid concurrency problems
if (nowField.value !== allValues[name]) {
expired.push({
name,
})
} else {
nowField.errors = fieldErrors && fieldErrors.errors
nowField.value = allValues[name]
nowField.validating = false
nowField.dirty = false
nowAllFields[name] = nowField
}
const fieldErrors = get(errorsGroup, fieldName.concat('.errors'))
fieldErrors.push(e)
})
}
const expired = []
const nowAllFields = {}
Object.keys(allRules).forEach((name) => {
const fieldErrors = get(errorsGroup, name)
const nowField = this.fieldsStore.getField(name)
// avoid concurrency problems
if (nowField.value !== allValues[name]) {
expired.push({
name,
})
} else {
nowField.errors = fieldErrors && fieldErrors.errors
nowField.value = allValues[name]
nowField.validating = false
nowField.dirty = false
nowAllFields[name] = nowField
this.setFields(nowAllFields)
if (callback) {
if (expired.length) {
expired.forEach(({ name }) => {
const fieldErrors = [{
message: `${name} need to revalidate`,
field: name,
}]
set(errorsGroup, name, {
expired: true,
errors: fieldErrors,
})
})
}
callback(isEmptyObject(errorsGroup) ? null : errorsGroup,
this.fieldsStore.getFieldsValue(fieldNames))
}
})
this.setFields(nowAllFields)
if (callback) {
if (expired.length) {
expired.forEach(({ name }) => {
const fieldErrors = [{
message: `${name} need to revalidate`,
field: name,
}]
set(errorsGroup, name, {
expired: true,
errors: fieldErrors,
})
})
},
validateFields (ns, opt, cb) {
const { names, callback, options } = getParams(ns, opt, cb)
const fieldNames = names
? this.fieldsStore.getValidFieldsFullName(names)
: this.fieldsStore.getValidFieldsName()
const fields = fieldNames
.filter(name => {
const fieldMeta = this.fieldsStore.getFieldMeta(name)
return hasRules(fieldMeta.validate)
}).map((name) => {
const field = this.fieldsStore.getField(name)
field.value = this.fieldsStore.getFieldValue(name)
return field
})
if (!fields.length) {
if (callback) {
callback(null, this.fieldsStore.getFieldsValue(fieldNames))
}
callback(isEmptyObject(errorsGroup) ? null : errorsGroup,
this.fieldsStore.getFieldsValue(fieldNames))
return
}
})
},
validateFields (ns, opt, cb) {
const { names, callback, options } = getParams(ns, opt, cb)
const fieldNames = names
? this.fieldsStore.getValidFieldsFullName(names)
: this.fieldsStore.getValidFieldsName()
const fields = fieldNames
.filter(name => {
const fieldMeta = this.fieldsStore.getFieldMeta(name)
return hasRules(fieldMeta.validate)
}).map((name) => {
const field = this.fieldsStore.getField(name)
field.value = this.fieldsStore.getFieldValue(name)
return field
})
if (!fields.length) {
if (callback) {
callback(null, this.fieldsStore.getFieldsValue(fieldNames))
if (!('firstFields' in options)) {
options.firstFields = fieldNames.filter((name) => {
const fieldMeta = this.fieldsStore.getFieldMeta(name)
return !!fieldMeta.validateFirst
})
}
return
}
if (!('firstFields' in options)) {
options.firstFields = fieldNames.filter((name) => {
const fieldMeta = this.fieldsStore.getFieldMeta(name)
return !!fieldMeta.validateFirst
})
}
this.validateFieldsInternal(fields, {
fieldNames,
options,
}, callback)
},
this.validateFieldsInternal(fields, {
fieldNames,
options,
}, callback)
},
isSubmitting () {
if (process.env.NODE_ENV !== 'production' && process.env.NODE_ENV !== 'test') {
warning(
false,
'`isSubmitting` is deprecated. ' +
'Actually, it\'s more convenient to handle submitting status by yourself.'
)
}
return this.state.submitting
},
isSubmitting () {
if (process.env.NODE_ENV !== 'production' && process.env.NODE_ENV !== 'test') {
warning(
false,
'`isSubmitting` is deprecated. ' +
'Actually, it\'s more convenient to handle submitting status by yourself.'
)
}
return this.submitting
},
submit (callback) {
if (process.env.NODE_ENV !== 'production' && process.env.NODE_ENV !== 'test') {
warning(
false,
'`submit` is deprecated.' +
'Actually, it\'s more convenient to handle submitting status by yourself.'
)
}
const fn = () => {
submit (callback) {
if (process.env.NODE_ENV !== 'production' && process.env.NODE_ENV !== 'test') {
warning(
false,
'`submit` is deprecated.' +
'Actually, it\'s more convenient to handle submitting status by yourself.'
)
}
const fn = () => {
this.setState({
submitting: false,
})
}
this.setState({
submitting: false,
submitting: true,
})
}
this.setState({
submitting: true,
})
callback(fn)
callback(fn)
},
},
render () {
const { wrappedComponentRef, ...restProps } = this.props
const { $props, $listeners } = this
const formProps = {
[formPropName]: this.getForm(),
}
const wrappedComponentProps = {
props: mapProps.call(this, {
...formProps,
...$props,
}),
on: $listeners,
}
if (withRef) {
if (process.env.NODE_ENV !== 'production' && process.env.NODE_ENV !== 'test') {
warning(
false,
'`withRef` is deprecated, please use `wrappedComponentRef` instead. ' +
'See: https://github.com/react-component/form#note-use-wrappedcomponentref-instead-of-withref-after-rc-form140'
)
}
formProps.ref = 'wrappedComponent'
} else if (wrappedComponentRef) {
formProps.ref = wrappedComponentRef
wrappedComponentProps.ref = 'wrappedComponent'
}
const props = mapProps.call(this, {
...formProps,
...restProps,
})
return <WrappedComponent {...props}/>
return <WrappedComponent {...wrappedComponentProps}/>
},
})
}
return argumentContainer(Form, WrappedComponent)
}

71
components/vc-form/src/createDOMForm.jsx

@ -49,50 +49,53 @@ function getScrollableContainer (n) {
}
const mixin = {
getForm () {
return {
...formMixin.getForm.call(this),
validateFieldsAndScroll: this.validateFieldsAndScroll,
}
},
methods: {
getForm () {
return {
...formMixin.getForm.call(this),
validateFieldsAndScroll: this.validateFieldsAndScroll,
}
},
validateFieldsAndScroll (ns, opt, cb) {
const { names, callback, options } = getParams(ns, opt, cb)
validateFieldsAndScroll (ns, opt, cb) {
const { names, callback, options } = getParams(ns, opt, cb)
const newCb = (error, values) => {
if (error) {
const validNames = this.fieldsStore.getValidFieldsName()
let firstNode
let firstTop
for (const name of validNames) {
if (has(error, name)) {
const instance = this.getFieldInstance(name)
if (instance) {
const node = instance.$el
const top = node.getBoundingClientRect().top
if (firstTop === undefined || firstTop > top) {
firstTop = top
firstNode = node
const newCb = (error, values) => {
if (error) {
const validNames = this.fieldsStore.getValidFieldsName()
let firstNode
let firstTop
for (const name of validNames) {
if (has(error, name)) {
const instance = this.getFieldInstance(name)
if (instance) {
const node = instance.$el
const top = node.getBoundingClientRect().top
if (firstTop === undefined || firstTop > top) {
firstTop = top
firstNode = node
}
}
}
}
if (firstNode) {
const c = options.container || getScrollableContainer(firstNode)
scrollIntoView(firstNode, c, {
onlyScrollIfNeeded: true,
...options.scroll,
})
}
}
if (firstNode) {
const c = options.container || getScrollableContainer(firstNode)
scrollIntoView(firstNode, c, {
onlyScrollIfNeeded: true,
...options.scroll,
})
}
}
if (typeof callback === 'function') {
callback(error, values)
if (typeof callback === 'function') {
callback(error, values)
}
}
}
return this.validateFields(names, options, newCb)
return this.validateFields(names, options, newCb)
},
},
}
function createDOMForm (option) {

44
components/vc-form/src/createForm.jsx

@ -1,27 +1,29 @@
import createBaseForm from './createBaseForm'
export const mixin = {
getForm () {
return {
getFieldsValue: this.fieldsStore.getFieldsValue,
getFieldValue: this.fieldsStore.getFieldValue,
getFieldInstance: this.getFieldInstance,
setFieldsValue: this.setFieldsValue,
setFields: this.setFields,
setFieldsInitialValue: this.fieldsStore.setFieldsInitialValue,
getFieldDecorator: this.getFieldDecorator,
getFieldProps: this.getFieldProps,
getFieldsError: this.fieldsStore.getFieldsError,
getFieldError: this.fieldsStore.getFieldError,
isFieldValidating: this.fieldsStore.isFieldValidating,
isFieldsValidating: this.fieldsStore.isFieldsValidating,
isFieldsTouched: this.fieldsStore.isFieldsTouched,
isFieldTouched: this.fieldsStore.isFieldTouched,
isSubmitting: this.isSubmitting,
submit: this.submit,
validateFields: this.validateFields,
resetFields: this.resetFields,
}
methods: {
getForm () {
return {
getFieldsValue: this.fieldsStore.getFieldsValue,
getFieldValue: this.fieldsStore.getFieldValue,
getFieldInstance: this.getFieldInstance,
setFieldsValue: this.setFieldsValue,
setFields: this.setFields,
setFieldsInitialValue: this.fieldsStore.setFieldsInitialValue,
getFieldDecorator: this.getFieldDecorator,
getFieldProps: this.getFieldProps,
getFieldsError: this.fieldsStore.getFieldsError,
getFieldError: this.fieldsStore.getFieldError,
isFieldValidating: this.fieldsStore.isFieldValidating,
isFieldsValidating: this.fieldsStore.isFieldsValidating,
isFieldsTouched: this.fieldsStore.isFieldsTouched,
isFieldTouched: this.fieldsStore.isFieldTouched,
isSubmitting: this.isSubmitting,
submit: this.submit,
validateFields: this.validateFields,
resetFields: this.resetFields,
}
},
},
}

9
components/vc-form/src/utils.js

@ -1,14 +1,13 @@
import hoistStatics from 'hoist-non-react-statics'
function getDisplayName (WrappedComponent) {
return WrappedComponent.displayName || WrappedComponent.name || 'WrappedComponent'
return WrappedComponent.name || 'WrappedComponent'
}
export function argumentContainer (Container, WrappedComponent) {
/* eslint no-param-reassign:0 */
Container.displayName = `Form(${getDisplayName(WrappedComponent)})`
Container.name = `Form_${getDisplayName(WrappedComponent)}`
Container.WrappedComponent = WrappedComponent
return hoistStatics(Container, WrappedComponent)
Container.methods = { ...Container.methods, ...WrappedComponent.methods }
return Container
}
export function identity (obj) {

325
package.json

@ -1,164 +1,165 @@
{
"name": "vue-antd-ui",
"version": "0.4.3",
"title": "Ant Design Vue",
"description": "An enterprise-class UI design language and Vue-based implementation",
"keywords": [
"ant",
"design",
"antd",
"vue",
"vueComponent",
"component",
"components",
"ui",
"framework",
"frontend"
],
"main": "dist/antd.min.js",
"files": [
"dist",
"lib",
"es"
],
"scripts": {
"start": "NODE_ENV=development ./node_modules/.bin/webpack-dev-server --open --hot",
"test": "karma start test/karma.conf.js --single-run",
"site": "node scripts/run.js site-dist",
"copy": "node scripts/run.js copy-html",
"compile": "node antd-tools/cli/run.js compile",
"pub": "node antd-tools/cli/run.js pub",
"prepublish": "node antd-tools/cli/run.js guard",
"dist": "node antd-tools/cli/run.js dist",
"lint": "eslint -c ./.eslintrc --fix --ext .jsx,.js,.vue ./components",
"lint:style": "stylelint \"./examples/**/*.less\" --fix --syntax less",
"commitmsg": "validate-commit-msg",
"cm": "git-cz"
},
"repository": {
"type": "git",
"url": "git+https://github.com/vueComponent/ant-design.git"
},
"license": "MIT",
"bugs": {
"url": "https://github.com/vueComponent/ant-design/issues"
},
"homepage": "https://github.com/vueComponent/ant-design",
"pre-commit": [
"lint:style",
"lint"
],
"devDependencies": {
"@octokit/rest": "^15.2.6",
"autoprefixer": "^8.1.0",
"babel-cli": "^6.26.0",
"babel-core": "^6.26.0",
"babel-eslint": "^8.0.1",
"babel-helper-vue-jsx-merge-props": "^2.0.3",
"babel-loader": "^7.1.2",
"babel-plugin-add-module-exports": "^0.2.1",
"babel-plugin-import": "^1.1.1",
"babel-plugin-istanbul": "^4.1.1",
"babel-plugin-syntax-dynamic-import": "^6.18.0",
"babel-plugin-syntax-jsx": "^6.18.0",
"babel-plugin-transform-decorators": "^6.24.1",
"babel-plugin-transform-decorators-legacy": "^1.3.4",
"babel-plugin-transform-es3-member-expression-literals": "^6.22.0",
"babel-plugin-transform-es3-property-literals": "^6.22.0",
"babel-plugin-transform-object-assign": "^6.22.0",
"babel-plugin-transform-object-rest-spread": "^6.26.0",
"babel-plugin-transform-runtime": "~6.23.0",
"babel-plugin-transform-vue-jsx": "^3.7.0",
"babel-polyfill": "^6.26.0",
"babel-preset-env": "^1.6.1",
"case-sensitive-paths-webpack-plugin": "^2.1.2",
"chai": "^4.1.2",
"chalk": "^2.3.2",
"cheerio": "^1.0.0-rc.2",
"colorful": "^2.1.0",
"commander": "^2.15.0",
"commitizen": "^2.9.6",
"css-loader": "^0.28.7",
"deep-assign": "^2.0.0",
"eslint": "^4.7.2",
"eslint-plugin-vue": "^3.13.0",
"eslint-plugin-html": "^3.2.2",
"eslint-plugin-vue-libs": "^1.2.1",
"extract-text-webpack-plugin": "^3.0.2",
"fetch-jsonp": "^1.1.3",
"gulp": "^3.9.1",
"gulp-babel": "^7.0.0",
"gulp-strip-code": "^0.1.4",
"highlight.js": "^9.12.0",
"html-webpack-plugin": "^2.30.1",
"husky": "^0.14.3",
"istanbul-instrumenter-loader": "^3.0.0",
"jsonp": "^0.2.1",
"karma": "^1.4.1",
"karma-coverage": "^1.1.1",
"karma-coverage-istanbul-reporter": "^1.3.0",
"karma-mocha": "^1.3.0",
"karma-phantomjs-launcher": "^1.0.2",
"karma-phantomjs-shim": "^1.4.0",
"karma-sinon-chai": "^1.3.1",
"karma-sourcemap-loader": "^0.3.7",
"karma-spec-reporter": "0.0.31",
"karma-webpack": "^2.0.2",
"less": "^2.7.2",
"less-loader": "^4.0.5",
"less-plugin-npm-import": "^2.1.0",
"markdown-it": "^8.4.0",
"markdown-it-anchor": "^4.0.0",
"marked": "^0.3.7",
"merge2": "^1.2.1",
"minimist": "^1.2.0",
"mkdirp": "^0.5.1",
"mocha": "^3.2.0",
"postcss": "^6.0.20",
"postcss-loader": "^2.1.2",
"pre-commit": "^1.2.2",
"querystring": "^0.2.0",
"reqwest": "^2.0.5",
"rimraf": "^2.6.2",
"rucksack-css": "^1.0.2",
"selenium-server": "^3.0.1",
"semver": "^5.3.0",
"sinon": "^4.0.2",
"sinon-chai": "^2.8.0",
"style-loader": "^0.18.2",
"stylelint": "^8.1.1",
"stylelint-config-standard": "^17.0.0",
"through2": "^2.0.3",
"validate-commit-msg": "^2.14.0",
"vue": "^2.5.15",
"vue-antd-md-loader": "^1.0.3",
"vue-clipboard2": "0.0.8",
"vue-loader": "^13.0.5",
"vue-router": "^3.0.1",
"vue-template-compiler": "^2.5.15",
"webpack": "^3.6.0",
"webpack-chunk-hash": "^0.5.0",
"webpack-dev-server": "^2.8.2",
"webpack-merge": "^4.1.1"
},
"dependencies": {
"add-dom-event-listener": "^1.0.2",
"array-tree-filter": "^2.1.0",
"babel-runtime": "6.x",
"babel-helper-vue-jsx-merge-props": "^2.0.3",
"classnames": "^2.2.5",
"component-classes": "^1.2.6",
"css-animation": "^1.4.1",
"dom-align": "^1.6.7",
"dom-closest": "^0.2.0",
"dom-scroll-into-view": "^1.2.1",
"enquire.js": "^2.1.6",
"is-negative-zero": "^2.0.0",
"lodash": "^4.17.5",
"moment": "^2.21.0",
"omit.js": "^1.0.0",
"shallow-equal": "^1.0.0",
"shallowequal": "^1.0.2",
"warning": "^3.0.0"
}
"name": "vue-antd-ui",
"version": "0.4.3",
"title": "Ant Design Vue",
"description": "An enterprise-class UI design language and Vue-based implementation",
"keywords": [
"ant",
"design",
"antd",
"vue",
"vueComponent",
"component",
"components",
"ui",
"framework",
"frontend"
],
"main": "dist/antd.min.js",
"files": [
"dist",
"lib",
"es"
],
"scripts": {
"start": "NODE_ENV=development ./node_modules/.bin/webpack-dev-server --open --hot",
"test": "karma start test/karma.conf.js --single-run",
"site": "node scripts/run.js site-dist",
"copy": "node scripts/run.js copy-html",
"compile": "node antd-tools/cli/run.js compile",
"pub": "node antd-tools/cli/run.js pub",
"prepublish": "node antd-tools/cli/run.js guard",
"dist": "node antd-tools/cli/run.js dist",
"lint": "eslint -c ./.eslintrc --fix --ext .jsx,.js,.vue ./components",
"lint:style": "stylelint \"./examples/**/*.less\" --fix --syntax less",
"commitmsg": "validate-commit-msg",
"cm": "git-cz"
},
"repository": {
"type": "git",
"url": "git+https://github.com/vueComponent/ant-design.git"
},
"license": "MIT",
"bugs": {
"url": "https://github.com/vueComponent/ant-design/issues"
},
"homepage": "https://github.com/vueComponent/ant-design",
"pre-commit": [
"lint:style",
"lint"
],
"devDependencies": {
"@octokit/rest": "^15.2.6",
"autoprefixer": "^8.1.0",
"babel-cli": "^6.26.0",
"babel-core": "^6.26.0",
"babel-eslint": "^8.0.1",
"babel-helper-vue-jsx-merge-props": "^2.0.3",
"babel-loader": "^7.1.2",
"babel-plugin-add-module-exports": "^0.2.1",
"babel-plugin-import": "^1.1.1",
"babel-plugin-istanbul": "^4.1.1",
"babel-plugin-syntax-dynamic-import": "^6.18.0",
"babel-plugin-syntax-jsx": "^6.18.0",
"babel-plugin-transform-decorators": "^6.24.1",
"babel-plugin-transform-decorators-legacy": "^1.3.4",
"babel-plugin-transform-es3-member-expression-literals": "^6.22.0",
"babel-plugin-transform-es3-property-literals": "^6.22.0",
"babel-plugin-transform-object-assign": "^6.22.0",
"babel-plugin-transform-object-rest-spread": "^6.26.0",
"babel-plugin-transform-runtime": "~6.23.0",
"babel-plugin-transform-vue-jsx": "^3.7.0",
"babel-polyfill": "^6.26.0",
"babel-preset-env": "^1.6.1",
"case-sensitive-paths-webpack-plugin": "^2.1.2",
"chai": "^4.1.2",
"chalk": "^2.3.2",
"cheerio": "^1.0.0-rc.2",
"colorful": "^2.1.0",
"commander": "^2.15.0",
"commitizen": "^2.9.6",
"css-loader": "^0.28.7",
"deep-assign": "^2.0.0",
"eslint": "^4.7.2",
"eslint-plugin-vue": "^3.13.0",
"eslint-plugin-html": "^3.2.2",
"eslint-plugin-vue-libs": "^1.2.1",
"extract-text-webpack-plugin": "^3.0.2",
"fetch-jsonp": "^1.1.3",
"gulp": "^3.9.1",
"gulp-babel": "^7.0.0",
"gulp-strip-code": "^0.1.4",
"highlight.js": "^9.12.0",
"html-webpack-plugin": "^2.30.1",
"husky": "^0.14.3",
"istanbul-instrumenter-loader": "^3.0.0",
"jsonp": "^0.2.1",
"karma": "^1.4.1",
"karma-coverage": "^1.1.1",
"karma-coverage-istanbul-reporter": "^1.3.0",
"karma-mocha": "^1.3.0",
"karma-phantomjs-launcher": "^1.0.2",
"karma-phantomjs-shim": "^1.4.0",
"karma-sinon-chai": "^1.3.1",
"karma-sourcemap-loader": "^0.3.7",
"karma-spec-reporter": "0.0.31",
"karma-webpack": "^2.0.2",
"less": "^2.7.2",
"less-loader": "^4.0.5",
"less-plugin-npm-import": "^2.1.0",
"markdown-it": "^8.4.0",
"markdown-it-anchor": "^4.0.0",
"marked": "^0.3.7",
"merge2": "^1.2.1",
"minimist": "^1.2.0",
"mkdirp": "^0.5.1",
"mocha": "^3.2.0",
"postcss": "^6.0.20",
"postcss-loader": "^2.1.2",
"pre-commit": "^1.2.2",
"querystring": "^0.2.0",
"reqwest": "^2.0.5",
"rimraf": "^2.6.2",
"rucksack-css": "^1.0.2",
"selenium-server": "^3.0.1",
"semver": "^5.3.0",
"sinon": "^4.0.2",
"sinon-chai": "^2.8.0",
"style-loader": "^0.18.2",
"stylelint": "^8.1.1",
"stylelint-config-standard": "^17.0.0",
"through2": "^2.0.3",
"validate-commit-msg": "^2.14.0",
"vue": "^2.5.15",
"vue-antd-md-loader": "^1.0.3",
"vue-clipboard2": "0.0.8",
"vue-loader": "^13.0.5",
"vue-router": "^3.0.1",
"vue-template-compiler": "^2.5.15",
"webpack": "^3.6.0",
"webpack-chunk-hash": "^0.5.0",
"webpack-dev-server": "^2.8.2",
"webpack-merge": "^4.1.1"
},
"dependencies": {
"add-dom-event-listener": "^1.0.2",
"array-tree-filter": "^2.1.0",
"async-validator": "^1.8.2",
"babel-helper-vue-jsx-merge-props": "^2.0.3",
"babel-runtime": "6.x",
"classnames": "^2.2.5",
"component-classes": "^1.2.6",
"css-animation": "^1.4.1",
"dom-align": "^1.6.7",
"dom-closest": "^0.2.0",
"dom-scroll-into-view": "^1.2.1",
"enquire.js": "^2.1.6",
"is-negative-zero": "^2.0.0",
"lodash": "^4.17.5",
"moment": "^2.21.0",
"omit.js": "^1.0.0",
"shallow-equal": "^1.0.0",
"shallowequal": "^1.0.2",
"warning": "^3.0.0"
}
}

2
site/routes.js

@ -4,7 +4,7 @@ import Iframe from './components/iframe.vue'
const AsyncTestComp = () => {
const d = window.location.hash.replace('#', '')
return {
component: import(`../components/menu/demo/${d}`),
component: import(`../components/vc-form/demo/${d}`),
}
}

Loading…
Cancel
Save