feat: update vc-drawer vc-form
parent
d805107543
commit
754d897393
|
@ -1,9 +1,9 @@
|
|||
import classNames from 'classnames'
|
||||
import warning from 'warning'
|
||||
import VcDrawer from '../vc-drawer/src'
|
||||
import PropTypes from '../_util/vue-types'
|
||||
import BaseMixin from '../_util/BaseMixin'
|
||||
import Icon from '../icon'
|
||||
import { getComponentFromProp, getOptionProps } from '../_util/props-util'
|
||||
import { getComponentFromProp, getOptionProps, getClass } from '../_util/props-util'
|
||||
|
||||
const Drawer = {
|
||||
name: 'ADrawer',
|
||||
|
@ -26,6 +26,10 @@ const Drawer = {
|
|||
},
|
||||
mixins: [BaseMixin],
|
||||
data () {
|
||||
warning(
|
||||
this.wrapClassName === undefined,
|
||||
'wrapClassName is deprecated, please use className instead.',
|
||||
)
|
||||
this.destoryClose = false
|
||||
this.preVisible = this.$props.visible
|
||||
return {
|
||||
|
@ -195,16 +199,17 @@ const Drawer = {
|
|||
open: visible,
|
||||
showMask: props.mask,
|
||||
placement,
|
||||
wrapClassName: classNames({
|
||||
[wrapClassName]: !!wrapClassName,
|
||||
[haveMask]: !!haveMask,
|
||||
}),
|
||||
},
|
||||
on: {
|
||||
maskClick: this.onMaskClick,
|
||||
...this.$listeners,
|
||||
},
|
||||
style: this.getRcDrawerStyle(),
|
||||
class: {
|
||||
[wrapClassName]: !!wrapClassName,
|
||||
...getClass(this),
|
||||
[haveMask]: !!haveMask,
|
||||
},
|
||||
}
|
||||
return (
|
||||
<VcDrawer
|
||||
|
|
|
@ -112,6 +112,8 @@ export const ValidationRule = {
|
|||
// normalize?: (value: any, prevValue: any, allValues: any) => any;
|
||||
// /** Whether stop validate on first rule of error for this field. */
|
||||
// validateFirst?: boolean;
|
||||
// /** 是否一直保留子节点的信息 */
|
||||
// preserve?: boolean;
|
||||
// };
|
||||
|
||||
const Form = {
|
||||
|
|
|
@ -23,6 +23,7 @@ Add or remove form items dynamically.
|
|||
`names[${k}]`,
|
||||
{
|
||||
validateTrigger: ['change', 'blur'],
|
||||
preserve: true,
|
||||
rules: [{
|
||||
required: true,
|
||||
whitespace: true,
|
||||
|
|
|
@ -25,7 +25,7 @@ export default {
|
|||
},
|
||||
getLevelMove (e) {
|
||||
const target = e.target
|
||||
if (target.className === 'drawer1') {
|
||||
if (target.className.indexOf('drawer1') >= 0) {
|
||||
return [200, 100]
|
||||
}
|
||||
return 100
|
||||
|
@ -47,7 +47,7 @@ export default {
|
|||
handler={false}
|
||||
open={this.open}
|
||||
onMaskClick={this.onClick}
|
||||
wrapperClassName='drawer1'
|
||||
class='drawer1'
|
||||
placement='right'
|
||||
>
|
||||
<div>
|
||||
|
@ -56,7 +56,7 @@ export default {
|
|||
handler={false}
|
||||
open={this.openChild}
|
||||
onMaskClick={this.onChildClick}
|
||||
wrapperClassName='drawer2'
|
||||
class='drawer2'
|
||||
level='.drawer1'
|
||||
placement='right'
|
||||
levelMove={100}
|
||||
|
|
|
@ -35,7 +35,7 @@ export default {
|
|||
return (
|
||||
<div >
|
||||
{this.childShow && (
|
||||
<Drawer placement={this.placement} width={this.width} hieght={this.height}>
|
||||
<Drawer placement={this.placement} width={this.width} height={this.height}>
|
||||
<Menu
|
||||
defaultSelectedKeys={['1']}
|
||||
defaultOpenKeys={['sub1']}
|
||||
|
|
|
@ -2,7 +2,7 @@ import classnames from 'classnames'
|
|||
import Vue from 'vue'
|
||||
import ref from 'vue-ref'
|
||||
import BaseMixin from '../../_util/BaseMixin'
|
||||
import { initDefaultProps, getEvents } from '../../_util/props-util'
|
||||
import { initDefaultProps, getEvents, getClass } from '../../_util/props-util'
|
||||
import { cloneElement } from '../../_util/vnode'
|
||||
import ContainerRender from '../../_util/ContainerRender'
|
||||
import getScrollBarSize from '../../_util/getScrollBarSize'
|
||||
|
@ -10,7 +10,7 @@ import drawerProps from './drawerProps'
|
|||
import {
|
||||
dataToArray,
|
||||
transitionEnd,
|
||||
trnasitionStr,
|
||||
transitionStr,
|
||||
addEventListener,
|
||||
removeEventListener,
|
||||
transformArguments,
|
||||
|
@ -40,7 +40,7 @@ const Drawer = {
|
|||
showMask: true,
|
||||
handler: true,
|
||||
maskStyle: {},
|
||||
wrapClassName: '',
|
||||
wrapperClassName: '',
|
||||
}),
|
||||
data () {
|
||||
this.levelDom = []
|
||||
|
@ -51,8 +51,9 @@ const Drawer = {
|
|||
this.sFirstEnter = this.firstEnter
|
||||
this.timeout = null
|
||||
this.children = null
|
||||
this.drawerId = Number((Date.now() + Math.random()).toString()
|
||||
.replace('.', Math.round(Math.random() * 9))).toString(16)
|
||||
this.drawerId = Number(
|
||||
(Date.now() + Math.random()).toString().replace('.', Math.round(Math.random() * 9)),
|
||||
).toString(16)
|
||||
const open = this.open !== undefined ? this.open : !!this.defaultOpen
|
||||
currentDrawer[this.drawerId] = open
|
||||
this.orignalOpen = this.open
|
||||
|
@ -170,7 +171,7 @@ const Drawer = {
|
|||
onWrapperTransitionEnd (e) {
|
||||
if (e.target === this.contentWrapper) {
|
||||
this.dom.style.transition = ''
|
||||
if (!this.sOpen && this.getCrrentDrawerSome()) {
|
||||
if (!this.sOpen && this.getCurrentDrawerSome()) {
|
||||
document.body.style.overflowX = ''
|
||||
if (this.maskDom) {
|
||||
this.maskDom.style.left = ''
|
||||
|
@ -185,7 +186,7 @@ const Drawer = {
|
|||
this.container = this.defaultGetContainer()
|
||||
}
|
||||
},
|
||||
getCrrentDrawerSome () {
|
||||
getCurrentDrawerSome () {
|
||||
return !Object.keys(currentDrawer).some(key => currentDrawer[key])
|
||||
},
|
||||
getSelfContainer () {
|
||||
|
@ -215,8 +216,11 @@ const Drawer = {
|
|||
if (level === 'all') {
|
||||
const children = Array.prototype.slice.call(this.parent.children)
|
||||
children.forEach(child => {
|
||||
if (child.nodeName !== 'SCRIPT' && child.nodeName !== 'STYLE' &&
|
||||
child.nodeName !== 'LINK' && child !== this.container) {
|
||||
if (child.nodeName !== 'SCRIPT' &&
|
||||
child.nodeName !== 'STYLE' &&
|
||||
child.nodeName !== 'LINK' &&
|
||||
child !== this.container
|
||||
) {
|
||||
this.levelDom.push(child)
|
||||
}
|
||||
})
|
||||
|
@ -251,9 +255,12 @@ const Drawer = {
|
|||
if (getContainer === 'body') {
|
||||
const eventArray = ['touchstart']
|
||||
const domArray = [document.body, this.maskDom, this.handlerdom, this.contentDom]
|
||||
const right = document.body.scrollHeight > (window.innerHeight || document.documentElement.clientHeight) &&
|
||||
const right =
|
||||
document.body.scrollHeight >
|
||||
(window.innerHeight || document.documentElement.clientHeight) &&
|
||||
window.innerWidth > document.body.offsetWidth
|
||||
? getScrollBarSize(1) : 0
|
||||
? getScrollBarSize(1)
|
||||
: 0
|
||||
let widthTransition = `width ${duration} ${ease}`
|
||||
const trannsformTransition = `transform ${duration} ${ease}`
|
||||
if (open && document.body.style.overflow !== 'hidden') {
|
||||
|
@ -295,12 +302,12 @@ const Drawer = {
|
|||
this.passive
|
||||
)
|
||||
})
|
||||
} else if (this.getCrrentDrawerSome()) {
|
||||
} else if (this.getCurrentDrawerSome()) {
|
||||
document.body.style.overflow = ''
|
||||
if ((this.isOpenChange || openTransition) && right) {
|
||||
document.body.style.position = ''
|
||||
document.body.style.width = ''
|
||||
if (trnasitionStr) {
|
||||
if (transitionStr) {
|
||||
document.body.style.overflowX = 'hidden'
|
||||
}
|
||||
this.dom.style.transition = 'none'
|
||||
|
@ -367,21 +374,19 @@ const Drawer = {
|
|||
maskStyle,
|
||||
width,
|
||||
height,
|
||||
wrapClassName,
|
||||
} = this.$props
|
||||
const children = this.$slots.default
|
||||
const wrapperClassname = classnames(prefixCls, {
|
||||
[`${prefixCls}-${placement}`]: true,
|
||||
[`${prefixCls}-open`]: open,
|
||||
[wrapClassName]: !!wrapClassName,
|
||||
...getClass(this),
|
||||
})
|
||||
const isOpenChange = this.isOpenChange
|
||||
const isHorizontal = placement === 'left' || placement === 'right'
|
||||
const placementName = `translate${isHorizontal ? 'X' : 'Y'}`
|
||||
// 百分比与像素动画不同步,第一次打用后全用像素动画。
|
||||
// const defaultValue = !this.contentDom || !level ? '100%' : `${value}px`;
|
||||
const placementPos =
|
||||
placement === 'left' || placement === 'top' ? '-100%' : '100%'
|
||||
const placementPos = placement === 'left' || placement === 'top' ? '-100%' : '100%'
|
||||
const transform = open ? '' : `${placementName}(${placementPos})`
|
||||
if (isOpenChange === undefined || isOpenChange) {
|
||||
const contentValue = this.contentDom ? this.contentDom.getBoundingClientRect()[
|
||||
|
@ -390,7 +395,7 @@ const Drawer = {
|
|||
const value = (isHorizontal ? width : height) || contentValue
|
||||
this.setLevelDomTransform(open, false, placementName, value)
|
||||
}
|
||||
let handlerCildren
|
||||
let handlerChildren
|
||||
if (handler !== false) {
|
||||
const handlerDefalut = (
|
||||
<div class='drawer-handle'>
|
||||
|
@ -400,7 +405,7 @@ const Drawer = {
|
|||
const { handler: handlerSlot } = this.$slots
|
||||
const handlerSlotVnode = handlerSlot || handlerDefalut
|
||||
const { click: handleIconClick } = getEvents(handlerSlotVnode)
|
||||
handlerCildren = cloneElement(handlerSlotVnode, {
|
||||
handlerChildren = cloneElement(handlerSlotVnode, {
|
||||
on: {
|
||||
click: (e) => {
|
||||
handleIconClick && handleIconClick()
|
||||
|
@ -475,7 +480,7 @@ const Drawer = {
|
|||
>
|
||||
{children}
|
||||
</div>
|
||||
{handlerCildren}
|
||||
{handlerChildren}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
@ -484,7 +489,7 @@ const Drawer = {
|
|||
return this.open !== undefined ? this.open : this.sOpen
|
||||
},
|
||||
getTouchParentScroll (root, currentTarget, differX, differY) {
|
||||
if (!currentTarget) {
|
||||
if (!currentTarget || currentTarget === document) {
|
||||
return false
|
||||
}
|
||||
// root 为 drawer-content 设定了 overflow, 判断为 root 的 parent 时结束滚动;
|
||||
|
@ -506,20 +511,27 @@ const Drawer = {
|
|||
*/
|
||||
const t = currentTarget.scrollTop
|
||||
const l = currentTarget.scrollLeft
|
||||
currentTarget.scrollTo(currentTarget.scrollLeft + 1, currentTarget.scrollTop + 1)
|
||||
if (currentTarget.scrollTo) {
|
||||
currentTarget.scrollTo(currentTarget.scrollLeft + 1, currentTarget.scrollTop + 1)
|
||||
}
|
||||
const currentT = currentTarget.scrollTop
|
||||
const currentL = currentTarget.scrollLeft
|
||||
currentTarget.scrollTo(currentTarget.scrollLeft - 1, currentTarget.scrollTop - 1)
|
||||
|
||||
if (currentTarget.scrollTo) {
|
||||
currentTarget.scrollTo(currentTarget.scrollLeft - 1, currentTarget.scrollTop - 1)
|
||||
}
|
||||
if (
|
||||
isY && (!scrollY || !(currentT - t) ||
|
||||
(scrollY && (currentTarget.scrollTop >= scrollY && differY < 0 ||
|
||||
currentTarget.scrollTop <= 0 && differY > 0))
|
||||
) ||
|
||||
isX && (!scrollX || !(currentL - l) ||
|
||||
(scrollX && (currentTarget.scrollLeft >= scrollX && differX < 0 ||
|
||||
currentTarget.scrollLeft <= 0 && differX > 0))
|
||||
)
|
||||
(isY &&
|
||||
(!scrollY ||
|
||||
!(currentT - t) ||
|
||||
(scrollY &&
|
||||
((currentTarget.scrollTop >= scrollY && differY < 0) ||
|
||||
(currentTarget.scrollTop <= 0 && differY > 0))))) ||
|
||||
(isX &&
|
||||
(!scrollX ||
|
||||
!(currentL - l) ||
|
||||
(scrollX &&
|
||||
((currentTarget.scrollLeft >= scrollX && differX < 0) ||
|
||||
(currentTarget.scrollLeft <= 0 && differX > 0)))))
|
||||
) {
|
||||
return this.getTouchParentScroll(root, currentTarget.parentNode, differX, differY)
|
||||
}
|
||||
|
@ -544,8 +556,8 @@ const Drawer = {
|
|||
if (
|
||||
currentTarget === this.maskDom ||
|
||||
currentTarget === this.handlerdom ||
|
||||
currentTarget === this.contentDom &&
|
||||
this.getTouchParentScroll(currentTarget, e.target, differX, differY)
|
||||
(currentTarget === this.contentDom &&
|
||||
this.getTouchParentScroll(currentTarget, e.target, differX, differY))
|
||||
) {
|
||||
e.preventDefault()
|
||||
}
|
||||
|
@ -588,7 +600,7 @@ const Drawer = {
|
|||
</div>
|
||||
)
|
||||
}
|
||||
if (!this.container || !open && !this.sFirstEnter) {
|
||||
if (!this.container || (!open && !this.sFirstEnter)) {
|
||||
return null
|
||||
}
|
||||
return (
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import PropTypes from '../../_util/vue-types'
|
||||
|
||||
export default {
|
||||
wrapClassName: PropTypes.string,
|
||||
wrapperClassName: PropTypes.string,
|
||||
width: PropTypes.any,
|
||||
height: PropTypes.any,
|
||||
defaultOpen: PropTypes.bool,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// base in 1.7.6
|
||||
// base in 1.7.7
|
||||
// export this package's api
|
||||
import Drawer from './Drawer'
|
||||
|
||||
|
|
|
@ -4,20 +4,20 @@ export function dataToArray (vars) {
|
|||
}
|
||||
return [vars]
|
||||
}
|
||||
const trnasitionEndObject = {
|
||||
const transitionEndObject = {
|
||||
transition: 'transitionend',
|
||||
WebkitTransition: 'webkitTransitionEnd',
|
||||
MozTransition: 'transitionend',
|
||||
OTransition: 'oTransitionEnd otransitionend',
|
||||
}
|
||||
export const trnasitionStr = Object.keys(trnasitionEndObject).filter(key => {
|
||||
export const transitionStr = Object.keys(transitionEndObject).filter(key => {
|
||||
if (typeof document === 'undefined') {
|
||||
return false
|
||||
}
|
||||
const html = document.getElementsByTagName('html')[0]
|
||||
return key in (html ? html.style : {})
|
||||
})[0]
|
||||
export const transitionEnd = trnasitionEndObject[trnasitionStr]
|
||||
export const transitionEnd = transitionEndObject[transitionStr]
|
||||
|
||||
export function addEventListener (target, eventType, callback, options) {
|
||||
if (target.addEventListener) {
|
||||
|
@ -51,6 +51,6 @@ export function transformArguments (arg, cb) {
|
|||
return [result]
|
||||
}
|
||||
|
||||
export const isNumeric = (value) => {
|
||||
export const isNumeric = value => {
|
||||
return !isNaN(parseFloat(value)) && isFinite(value);// eslint-disable-line
|
||||
}
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
import { createForm } from '../index'
|
||||
const Form = {
|
||||
|
||||
methods: {
|
||||
handleSubmit (e) {
|
||||
e.preventDefault()
|
||||
const { validateFields } = this.form
|
||||
validateFields()
|
||||
.then(console.log)
|
||||
.catch(console.error)
|
||||
},
|
||||
},
|
||||
|
||||
render () {
|
||||
const { getFieldDecorator } = this.form
|
||||
return (
|
||||
<form onSubmit={this.handleSubmit}>
|
||||
{getFieldDecorator('name', {
|
||||
rules: [{
|
||||
required: true,
|
||||
}],
|
||||
})(<input/>)}
|
||||
<button type='submit'>submit</button>
|
||||
</form>
|
||||
)
|
||||
},
|
||||
}
|
||||
|
||||
export default createForm()(Form)
|
|
@ -34,6 +34,7 @@ function createBaseForm (option = {}, mixins = []) {
|
|||
fieldMetaProp,
|
||||
fieldDataProp,
|
||||
formPropName = 'form',
|
||||
name: formName,
|
||||
props = {},
|
||||
templateContext,
|
||||
} = option
|
||||
|
@ -267,7 +268,7 @@ function createBaseForm (option = {}, mixins = []) {
|
|||
const inputListeners = {}
|
||||
const inputAttrs = {}
|
||||
if (fieldNameProp) {
|
||||
inputProps[fieldNameProp] = name
|
||||
inputProps[fieldNameProp] = formName ? `${formName}_${name}` : name
|
||||
}
|
||||
|
||||
const validateRules = normalizeValidateRules(validate, rules, validateTrigger)
|
||||
|
@ -375,12 +376,15 @@ function createBaseForm (option = {}, mixins = []) {
|
|||
|
||||
saveRef (name, _, component) {
|
||||
if (!component) {
|
||||
const fieldMeta = this.fieldsStore.getFieldMeta(name)
|
||||
if (!fieldMeta.preserve) {
|
||||
// after destroy, delete data
|
||||
this.clearedFieldMetaCache[name] = {
|
||||
field: this.fieldsStore.getField(name),
|
||||
meta: this.fieldsStore.getFieldMeta(name),
|
||||
this.clearedFieldMetaCache[name] = {
|
||||
field: this.fieldsStore.getField(name),
|
||||
meta: fieldMeta,
|
||||
}
|
||||
this.clearField(name)
|
||||
}
|
||||
this.clearField(name)
|
||||
delete this.domFields[name]
|
||||
return
|
||||
}
|
||||
|
@ -401,9 +405,10 @@ function createBaseForm (option = {}, mixins = []) {
|
|||
|
||||
cleanUpUselessFields () {
|
||||
const fieldList = this.fieldsStore.getAllFieldsName()
|
||||
const removedList = fieldList.filter(field => (
|
||||
!this.renderFields[field] && !this.domFields[field]
|
||||
))
|
||||
const removedList = fieldList.filter(field => {
|
||||
const fieldMeta = this.fieldsStore.getFieldMeta(field)
|
||||
return (!this.renderFields[field] && !this.domFields[field] && !fieldMeta.preserve)
|
||||
})
|
||||
if (removedList.length) {
|
||||
removedList.forEach(this.clearField)
|
||||
}
|
||||
|
@ -536,35 +541,52 @@ function createBaseForm (option = {}, mixins = []) {
|
|||
},
|
||||
|
||||
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))
|
||||
const pending = new Promise((resolve, reject) => {
|
||||
const { names, options } = getParams(ns, opt, cb)
|
||||
let { callback } = getParams(ns, opt, cb)
|
||||
if (!callback || typeof callback === 'function') {
|
||||
const oldCb = callback
|
||||
callback = (errors, values) => {
|
||||
if (oldCb) {
|
||||
oldCb(errors, values)
|
||||
} else if (errors) {
|
||||
reject({ errors, values })
|
||||
} else {
|
||||
resolve(values)
|
||||
}
|
||||
}
|
||||
}
|
||||
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)
|
||||
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))
|
||||
}
|
||||
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)
|
||||
})
|
||||
pending.catch((e) => e)
|
||||
return pending
|
||||
},
|
||||
|
||||
isSubmitting () {
|
||||
|
|
|
@ -159,7 +159,8 @@ class FieldsStore {
|
|||
}
|
||||
|
||||
getNotCollectedFields () {
|
||||
return this.getValidFieldsName()
|
||||
const fieldsName = this.getValidFieldsName()
|
||||
return fieldsName
|
||||
.filter(name => !this.fields[name])
|
||||
.map(name => ({
|
||||
name,
|
||||
|
|
Loading…
Reference in New Issue