1
0
mirror of synced 2025-12-09 07:08:22 +08:00

修改数值类型值大于或小于限制时,上下箭头禁用逻辑

This commit is contained in:
xuliangzhan
2022-05-29 16:29:02 +08:00
parent 04083ef71e
commit 67c2107f0d
20 changed files with 338 additions and 166 deletions

View File

@@ -135,7 +135,7 @@
</vxe-form-item>
<vxe-form-item title="标题貌似有点长呢" field="sex" span="24" :item-render="{}" title-overflow>
<template #default="params">
<vxe-select v-model="params.data.sex" placeholder="请选择性别" clearable @change="$refs.xForm.updateStatus(params)">
<vxe-select v-model="params.data.sex" placeholder="请选择性别" clearable>
<vxe-option value="1" label="女"></vxe-option>
<vxe-option value="2" label="男"></vxe-option>
</vxe-select>
@@ -143,7 +143,7 @@
</vxe-form-item>
<vxe-form-item title="标题貌似有点长呢" field="age" span="24" :item-render="{autofocus:'input'}" title-overflow="title">
<template #default="params">
<vxe-input v-model="params.data.age" type="integer" placeholder="请输入年龄" clearable @change="$refs.xForm.updateStatus(params)"></vxe-input>
<vxe-input v-model="params.data.age" type="integer" placeholder="请输入年龄" clearable></vxe-input>
</template>
</vxe-form-item>
<vxe-form-item title="标题貌似有点长呢" field="date" span="24" :item-render="{}" title-overflow="ellipsis">

View File

@@ -58,7 +58,7 @@
"gulp-sourcemaps": "^2.6.5",
"gulp-typescript": "^5.0.1",
"gulp-uglify": "^3.0.2",
"sass": "^1.45.1",
"sass": "^1.52.1",
"sass-loader": "^10.0.5",
"typescript": "~4.3.5",
"vue": "^3.2.31",

View File

@@ -4,7 +4,7 @@ import { getFuncText } from '../../tools/utils'
import GlobalConfig from '../../v-x-e-table/src/conf'
import { useSize } from '../../hooks/size'
import { VxeCheckboxConstructor, VxeCheckboxGroupConstructor, VxeCheckboxEmits, VxeCheckboxGroupPrivateMethods, CheckboxMethods, VxeCheckboxPropTypes } from '../../../types/all'
import { VxeCheckboxConstructor, VxeCheckboxGroupConstructor, VxeCheckboxEmits, VxeCheckboxGroupPrivateMethods, CheckboxMethods, VxeCheckboxPropTypes, VxeFormConstructor, VxeFormPrivateMethods, VxeFormDefines } from '../../../types/all'
export default defineComponent({
name: 'VxeCheckbox',
@@ -25,6 +25,8 @@ export default defineComponent({
] as VxeCheckboxEmits,
setup (props, context) {
const { slots, emit } = context
const $xeform = inject<VxeFormConstructor & VxeFormPrivateMethods | null>('$xeform', null)
const $xeformiteminfo = inject<VxeFormDefines.ProvideItemInfo | null>('$xeformiteminfo', null)
const xID = XEUtils.uniqueId()
@@ -60,6 +62,10 @@ export default defineComponent({
} else {
emit('update:modelValue', value)
checkboxMethods.dispatchEvent('change', params, evnt)
// 自动更新校验状态
if ($xeform && $xeformiteminfo) {
$xeform.triggerItemEvent(evnt, $xeformiteminfo.itemConfig.field, value)
}
}
}
}

View File

@@ -1,9 +1,9 @@
import { defineComponent, h, provide, PropType } from 'vue'
import { defineComponent, h, provide, PropType, inject } from 'vue'
import GlobalConfig from '../../v-x-e-table/src/conf'
import XEUtils from 'xe-utils'
import { useSize } from '../../hooks/size'
import { VxeCheckboxGroupConstructor, VxeCheckboxGroupEmits, VxeCheckboxGroupPrivateMethods, CheckboxGroupPrivateMethods, CheckboxGroupMethods, VxeCheckboxGroupPropTypes } from '../../../types/all'
import { VxeCheckboxGroupConstructor, VxeCheckboxGroupEmits, VxeCheckboxGroupPrivateMethods, CheckboxGroupPrivateMethods, CheckboxGroupMethods, VxeCheckboxGroupPropTypes, VxeFormConstructor, VxeFormPrivateMethods, VxeFormDefines } from '../../../types/all'
export default defineComponent({
name: 'VxeCheckboxGroup',
@@ -18,6 +18,8 @@ export default defineComponent({
] as VxeCheckboxGroupEmits,
setup (props, context) {
const { slots, emit } = context
const $xeform = inject<VxeFormConstructor & VxeFormPrivateMethods | null>('$xeform', null)
const $xeformiteminfo = inject<VxeFormDefines.ProvideItemInfo | null>('$xeformiteminfo', null)
const xID = XEUtils.uniqueId()
@@ -49,6 +51,10 @@ export default defineComponent({
}
emit('update:modelValue', checklist)
$xecheckboxgroup.dispatchEvent('change', Object.assign({ checklist }, params), evnt)
// 自动更新校验状态
if ($xeform && $xeformiteminfo) {
$xeform.triggerItemEvent(evnt, $xeformiteminfo.itemConfig.field, checklist)
}
}
}

View File

@@ -0,0 +1,156 @@
import { defineComponent, h, inject, provide, PropType, createCommentVNode } from 'vue'
import XEUtils from 'xe-utils'
import GlobalConfig from '../../v-x-e-table/src/conf'
import { VXETable } from '../../v-x-e-table'
import { getFuncText, isEnableConf } from '../../tools/utils'
import { renderTitle } from './render'
import { VxeFormConstructor, VxeFormDefines, VxeFormPrivateMethods } from '../../../types/all'
const VxeFormConfigItem = defineComponent({
name: 'VxeFormConfigItem',
props: {
itemConfig2: Object,
itemConfig: Object as PropType<VxeFormDefines.ItemInfo>
},
setup (props) {
const $xeform = inject('$xeform', {} as VxeFormConstructor & VxeFormPrivateMethods)
const xeformiteminfo = { itemConfig: props.itemConfig }
provide('$xeformiteminfo', xeformiteminfo)
provide('$xeformgather', null)
const renderVN = () => {
const { reactData } = $xeform
const { data, rules, span: allSpan, align: allAlign, titleAlign: allTitleAlign, titleWidth: allTitleWidth, titleColon: allTitleColon, titleAsterisk: allTitleAsterisk, titleOverflow: allTitleOverflow } = $xeform.props
const { computeValidOpts } = $xeform.getComputeMaps()
const item = props.itemConfig as VxeFormDefines.ItemInfo
const { collapseAll } = reactData
const validOpts = computeValidOpts.value
const { slots, title, visible, folding, visibleMethod, field, collapseNode, itemRender, showError, errRule, className, titleOverflow, children } = item
const compConf = isEnableConf(itemRender) ? VXETable.renderer.get(itemRender.name) : null
const defaultSlot = slots ? slots.default : null
const titleSlot = slots ? slots.title : null
const span = item.span || allSpan
const align = item.align || allAlign
const titleAlign = item.titleAlign || allTitleAlign
const titleWidth = item.titleWidth || allTitleWidth
const titleColon = item.titleColon === null ? allTitleColon : item.titleColon
const titleAsterisk = item.titleAsterisk === null ? allTitleAsterisk : item.titleAsterisk
const itemOverflow = (XEUtils.isUndefined(titleOverflow) || XEUtils.isNull(titleOverflow)) ? allTitleOverflow : titleOverflow
const showEllipsis = itemOverflow === 'ellipsis'
const showTitle = itemOverflow === 'title'
const showTooltip = itemOverflow === true || itemOverflow === 'tooltip'
const hasEllipsis = showTitle || showTooltip || showEllipsis
let itemVisibleMethod = visibleMethod
const params = { data, field, property: field, item, $form: $xeform }
if (visible === false) {
return createCommentVNode()
}
let isRequired = false
if (rules) {
const itemRules = rules[field]
if (itemRules) {
isRequired = itemRules.some((rule) => rule.required)
}
}
// 如果为项集合
const isGather = children && children.length > 0
if (isGather) {
const childVNs = children.map((childItem, index) => {
return h(VxeFormConfigItem, {
key: index,
itemConfig: childItem
})
})
return childVNs.length ? h('div', {
class: ['vxe-form--gather vxe-row', item.id, span ? `vxe-col--${span} is--span` : '', className ? (XEUtils.isFunction(className) ? className(params) : className) : '']
}, childVNs) : createCommentVNode()
}
if (!itemVisibleMethod && compConf && compConf.itemVisibleMethod) {
itemVisibleMethod = compConf.itemVisibleMethod
}
let contentVNs: any[] = []
if (defaultSlot) {
contentVNs = $xeform.callSlot(defaultSlot, params)
} else if (compConf && compConf.renderItemContent) {
contentVNs = compConf.renderItemContent(itemRender, params)
} else if (field) {
contentVNs = [`${XEUtils.get(data, field)}`]
}
if (collapseNode) {
contentVNs.push(
h('div', {
class: 'vxe-form--item-trigger-node',
onClick: $xeform.toggleCollapseEvent
}, [
h('span', {
class: 'vxe-form--item-trigger-text'
}, collapseAll ? GlobalConfig.i18n('vxe.form.unfolding') : GlobalConfig.i18n('vxe.form.folding')),
h('i', {
class: ['vxe-form--item-trigger-icon', collapseAll ? GlobalConfig.icon.FORM_FOLDING : GlobalConfig.icon.FORM_UNFOLDING]
})
])
)
}
if (errRule && validOpts.showMessage) {
contentVNs.push(
h('div', {
class: 'vxe-form--item-valid',
style: errRule.maxWidth ? {
width: `${errRule.maxWidth}px`
} : null
}, errRule.content)
)
}
const ons = showTooltip ? {
onMouseenter (evnt: MouseEvent) {
$xeform.triggerTitleTipEvent(evnt, params)
},
onMouseleave: $xeform.handleTitleTipLeaveEvent
} : {}
return h('div', {
class: ['vxe-form--item', item.id, span ? `vxe-col--${span} is--span` : '', className ? (XEUtils.isFunction(className) ? className(params) : className) : '', {
'is--title': title,
'is--colon': titleColon,
'is--asterisk': titleAsterisk,
'is--required': isRequired,
'is--hidden': folding && collapseAll,
'is--active': !itemVisibleMethod || itemVisibleMethod(params),
'is--error': showError
}],
itemConfig: item,
key: item.id
}, [
h('div', {
class: 'vxe-form--item-inner'
}, [
title || titleSlot ? h('div', {
class: ['vxe-form--item-title', titleAlign ? `align--${titleAlign}` : null, {
'is--ellipsis': hasEllipsis
}],
style: titleWidth ? {
width: isNaN(titleWidth as number) ? titleWidth : `${titleWidth}px`
} : null,
title: showTitle ? getFuncText(title) : null,
...ons
}, renderTitle($xeform, item)) : null,
h('div', {
class: ['vxe-form--item-content', align ? `align--${align}` : null]
}, contentVNs)
])
])
}
const $xeformconfigitem = {
renderVN
}
return $xeformconfigitem
},
render () {
return this.renderVN()
}
})
export default VxeFormConfigItem

View File

@@ -15,9 +15,12 @@ export default defineComponent({
const defaultSlot = slots.default
const formItem = reactive(createItem($xeform, props))
const xeformitem: XEFormItemProvide = { formItem }
const xeformiteminfo = { itemConfig: formItem }
formItem.children = []
provide('$xeformiteminfo', xeformiteminfo)
provide('$xeformgather', xeformitem)
provide('$xeformitem', null)
watchItem(props, formItem)
@@ -44,7 +47,6 @@ export default defineComponent({
}
const $xeformgather = {
itemConfig: formItem,
renderVN
}

View File

@@ -1,4 +1,4 @@
import { defineComponent, h, onUnmounted, inject, ref, Ref, onMounted, PropType } from 'vue'
import { defineComponent, h, onUnmounted, inject, ref, Ref, provide, onMounted, PropType } from 'vue'
import XEUtils from 'xe-utils'
import GlobalConfig from '../../v-x-e-table/src/conf'
import { VXETable } from '../../v-x-e-table'
@@ -43,8 +43,14 @@ export default defineComponent({
const $xeform = inject('$xeform', {} as VxeFormConstructor & VxeFormPrivateMethods)
const formGather = inject('$xeformgather', null as XEFormItemProvide | null)
const formItem = createItem($xeform, props)
const xeformitem: XEFormItemProvide = { formItem }
const xeformiteminfo = { itemConfig: formItem }
formItem.slots = slots
provide('$xeformiteminfo', xeformiteminfo)
provide('$xeformitem', xeformitem)
provide('$xeformgather', null)
watchItem(props, formItem)
onMounted(() => {
@@ -163,7 +169,6 @@ export default defineComponent({
}
const $xeformitem = {
itemConfig: formItem,
renderVN
}

View File

@@ -6,8 +6,8 @@ import { getFuncText, isEnableConf, eqEmptyValue } from '../../tools/utils'
import { errLog } from '../../tools/log'
import { scrollToView } from '../../tools/dom'
import { createItem, handleFieldOrItem } from './util'
import { renderTitle } from './render'
import { useSize } from '../../hooks/size'
import VxeFormConfigItem from './form-config-item'
import { VxeFormConstructor, VxeFormPropTypes, VxeFormEmits, FormReactData, FormMethods, FormPrivateRef, VxeFormPrivateMethods, VxeFormDefines, VxeFormItemPropTypes, VxeTooltipInstance, FormInternalData, VxeFormPrivateComputed } from '../../../types/all'
@@ -331,7 +331,7 @@ export default defineComponent({
}
} else {
const isArrType = type === 'array'
const hasEmpty = isArrType ? (!XEUtils.isArray(itemValue) || !itemValue.length) : eqEmptyValue(itemValue)
const hasEmpty = isArrType || XEUtils.isArray(itemValue) ? (!XEUtils.isArray(itemValue) || !itemValue.length) : eqEmptyValue(itemValue)
if (required ? (hasEmpty || validErrorRuleValue(rule, itemValue)) : (!hasEmpty && validErrorRuleValue(rule, itemValue))) {
errorRules.push(new Rule(rule))
}
@@ -491,142 +491,31 @@ export default defineComponent({
}
}
/**
* 更新项状态
* 如果组件值 v-model 发生 change 时,调用改函数用于更新某一项编辑状态
* 如果单元格配置了校验规则,则会进行校验
*/
const updateStatus = (scope: any, itemValue?: any) => {
const { property } = scope
if (property) {
validItemRules('change', property, itemValue)
const triggerItemEvent = (evnt: Event, field: string, itemValue?: any) => {
if (field) {
return validItemRules(evnt ? evnt.type : 'all', field, itemValue)
.then(() => {
clearValidate(property)
clearValidate(field)
})
.catch(({ rule }) => {
const item = getItemByField(property)
const item = getItemByField(field)
if (item) {
item.showError = true
item.errRule = rule
}
})
}
return nextTick()
}
const renderItems = (itemList: VxeFormDefines.ItemInfo[]): VNode[] => {
const { data, rules, titleOverflow: allTitleOverflow } = props
const { collapseAll } = reactData
const validOpts = computeValidOpts.value
return itemList.map((item) => {
const { slots, title, visible, folding, visibleMethod, field, collapseNode, itemRender, showError, errRule, className, titleOverflow, children } = item
const compConf = isEnableConf(itemRender) ? VXETable.renderer.get(itemRender.name) : null
const defaultSlot = slots ? slots.default : null
const titleSlot = slots ? slots.title : null
const span = item.span || props.span
const align = item.align || props.align
const titleAlign = item.titleAlign || props.titleAlign
const titleWidth = item.titleWidth || props.titleWidth
const titleColon = item.titleColon === null ? props.titleColon : item.titleColon
const titleAsterisk = item.titleAsterisk === null ? props.titleAsterisk : item.titleAsterisk
const itemOverflow = (XEUtils.isUndefined(titleOverflow) || XEUtils.isNull(titleOverflow)) ? allTitleOverflow : titleOverflow
const showEllipsis = itemOverflow === 'ellipsis'
const showTitle = itemOverflow === 'title'
const showTooltip = itemOverflow === true || itemOverflow === 'tooltip'
const hasEllipsis = showTitle || showTooltip || showEllipsis
let itemVisibleMethod = visibleMethod
const params = { data, field, property: field, item, $form: $xeform }
if (visible === false) {
return createCommentVNode()
}
let isRequired = false
if (rules) {
const itemRules = rules[field]
if (itemRules) {
isRequired = itemRules.some((rule) => rule.required)
}
}
// 如果为项集合
const isGather = children && children.length > 0
if (isGather) {
const childVNs = renderItems(item.children)
return childVNs.length ? h('div', {
class: ['vxe-form--gather vxe-row', item.id, span ? `vxe-col--${span} is--span` : '', className ? (XEUtils.isFunction(className) ? className(params) : className) : '']
}, childVNs) : createCommentVNode()
}
if (!itemVisibleMethod && compConf && compConf.itemVisibleMethod) {
itemVisibleMethod = compConf.itemVisibleMethod
}
let contentVNs: any[] = []
if (defaultSlot) {
contentVNs = callSlot(defaultSlot, params)
} else if (compConf && compConf.renderItemContent) {
contentVNs = compConf.renderItemContent(itemRender, params)
} else if (field) {
contentVNs = [`${XEUtils.get(data, field)}`]
}
if (collapseNode) {
contentVNs.push(
h('div', {
class: 'vxe-form--item-trigger-node',
onClick: toggleCollapseEvent
}, [
h('span', {
class: 'vxe-form--item-trigger-text'
}, collapseAll ? GlobalConfig.i18n('vxe.form.unfolding') : GlobalConfig.i18n('vxe.form.folding')),
h('i', {
class: ['vxe-form--item-trigger-icon', collapseAll ? GlobalConfig.icon.FORM_FOLDING : GlobalConfig.icon.FORM_UNFOLDING]
})
])
)
}
if (errRule && validOpts.showMessage) {
contentVNs.push(
h('div', {
class: 'vxe-form--item-valid',
style: errRule.maxWidth ? {
width: `${errRule.maxWidth}px`
} : null
}, errRule.content)
)
}
const ons = showTooltip ? {
onMouseenter (evnt: MouseEvent) {
triggerTitleTipEvent(evnt, params)
},
onMouseleave: handleTitleTipLeaveEvent
} : {}
return h('div', {
class: ['vxe-form--item', item.id, span ? `vxe-col--${span} is--span` : '', className ? (XEUtils.isFunction(className) ? className(params) : className) : '', {
'is--title': title,
'is--colon': titleColon,
'is--asterisk': titleAsterisk,
'is--required': isRequired,
'is--hidden': folding && collapseAll,
'is--active': !itemVisibleMethod || itemVisibleMethod(params),
'is--error': showError
}],
itemConfig: item,
key: item.id
}, [
h('div', {
class: 'vxe-form--item-inner'
}, [
title || titleSlot ? h('div', {
class: ['vxe-form--item-title', titleAlign ? `align--${titleAlign}` : null, {
'is--ellipsis': hasEllipsis
}],
style: titleWidth ? {
width: isNaN(titleWidth as number) ? titleWidth : `${titleWidth}px`
} : null,
title: showTitle ? getFuncText(title) : null,
...ons
}, renderTitle($xeform, item)) : null,
h('div', {
class: ['vxe-form--item-content', align ? `align--${align}` : null]
}, contentVNs)
])
])
})
/**
* 更新项状态
* 如果组件值 v-model 发生 change 时,调用改函数用于更新某一项编辑状态
* 如果单元格配置了校验规则,则会进行校验
*/
const updateStatus = (scope: any, itemValue?: any) => {
const { field } = scope
return triggerItemEvent(new Event('change'), field, itemValue)
}
formMethods = {
@@ -646,6 +535,7 @@ export default defineComponent({
const formPrivateMethods: VxeFormPrivateMethods = {
callSlot,
triggerItemEvent,
toggleCollapseEvent,
triggerTitleTipEvent,
handleTitleTipLeaveEvent
@@ -694,7 +584,13 @@ export default defineComponent({
}, [
h('div', {
class: 'vxe-form--wrapper vxe-row'
}, customLayout ? (defaultSlot ? defaultSlot({}) : []) : renderItems(formItems)),
}, customLayout ? (defaultSlot ? defaultSlot({}) : []) : formItems.map((item, index) => {
return h(VxeFormConfigItem, {
key: index,
itemConfig2: item,
itemConfig: item
})
})),
h('div', {
class: 'vxe-form-slots',
ref: 'hideItem'
@@ -723,6 +619,7 @@ export default defineComponent({
provide('$xeform', $xeform)
provide('$xeformgather', null)
provide('$xeformitem', null)
provide('$xeformiteminfo', null)
return $xeform
},

View File

@@ -1,4 +1,4 @@
import { defineComponent, h, Teleport, ref, Ref, computed, reactive, nextTick, watch, onUnmounted, PropType } from 'vue'
import { defineComponent, h, Teleport, ref, Ref, computed, reactive, inject, nextTick, watch, onUnmounted, PropType } from 'vue'
import XEUtils from 'xe-utils'
import GlobalConfig from '../../v-x-e-table/src/conf'
import { useSize } from '../../hooks/size'
@@ -8,7 +8,7 @@ import { GlobalEvent, hasEventKey, EVENT_KEYS } from '../../tools/event'
import { toStringTimeDate, getDateQuarter } from './date'
import { handleNumber, toFloatValueFixed } from './number'
import { VNodeStyle, VxeInputConstructor, VxeInputEmits, InputReactData, InputMethods, VxeInputPropTypes, InputPrivateRef } from '../../../types/all'
import { VNodeStyle, VxeInputConstructor, VxeInputEmits, InputReactData, InputMethods, VxeInputPropTypes, InputPrivateRef, VxeFormConstructor, VxeFormPrivateMethods, VxeFormDefines } from '../../../types/all'
interface DateYearItem {
date: Date;
@@ -130,6 +130,8 @@ export default defineComponent({
] as VxeInputEmits,
setup (props, context) {
const { slots, emit } = context
const $xeform = inject<VxeFormConstructor & VxeFormPrivateMethods | null>('$xeform', null)
const $xeformiteminfo = inject<VxeFormDefines.ProvideItemInfo | null>('$xeformiteminfo', null)
const xID = XEUtils.uniqueId()
@@ -610,6 +612,40 @@ export default defineComponent({
return immediate || !(type === 'text' || type === 'number' || type === 'integer' || type === 'float')
})
const computeNumValue = computed(() => {
const { type } = props
const { inputValue } = reactData
const isNumType = computeIsNumType.value
if (isNumType) {
return type === 'integer' ? XEUtils.toInteger(handleNumber(inputValue)) : XEUtils.toNumber(handleNumber(inputValue))
}
return 0
})
const computeIsDisabledSubtractNumber = computed(() => {
const { min } = props
const { inputValue } = reactData
const isNumType = computeIsNumType.value
const numValue = computeNumValue.value
// 当有值时再进行判断
if ((inputValue || inputValue === 0) && isNumType && min !== null) {
return numValue <= XEUtils.toNumber(min)
}
return false
})
const computeIsDisabledAddNumber = computed(() => {
const { max } = props
const { inputValue } = reactData
const isNumType = computeIsNumType.value
const numValue = computeNumValue.value
// 当有值时再进行判断
if ((inputValue || inputValue === 0) && isNumType && max !== null) {
return numValue >= XEUtils.toNumber(max)
}
return false
})
const getNumberValue = (val: any) => {
const { type, exponential } = props
const inpMaxlength = computeInpMaxlength.value
@@ -632,6 +668,10 @@ export default defineComponent({
inputMethods.dispatchEvent('input', { value }, evnt)
if (XEUtils.toValueString(props.modelValue) !== value) {
inputMethods.dispatchEvent('change', { value }, evnt)
// 自动更新校验状态
if ($xeform && $xeformiteminfo) {
$xeform.triggerItemEvent(evnt, $xeformiteminfo.itemConfig.field, value)
}
}
}
@@ -959,8 +999,9 @@ export default defineComponent({
const numberNextEvent = (evnt: Event) => {
const { readonly, disabled } = props
const isDisabledSubtractNumber = computeIsDisabledSubtractNumber.value
clearTimeout(downbumTimeout)
if (!disabled && !readonly) {
if (!disabled && !readonly && !isDisabledSubtractNumber) {
numberChange(false, evnt)
}
inputMethods.dispatchEvent('next-number', {}, evnt)
@@ -975,8 +1016,9 @@ export default defineComponent({
const numberPrevEvent = (evnt: Event) => {
const { readonly, disabled } = props
const isDisabledAddNumber = computeIsDisabledAddNumber.value
clearTimeout(downbumTimeout)
if (!disabled && !readonly) {
if (!disabled && !readonly && !isDisabledAddNumber) {
numberChange(true, evnt)
}
inputMethods.dispatchEvent('prev-number', {}, evnt)
@@ -2059,11 +2101,15 @@ export default defineComponent({
}
const renderNumberIcon = () => {
const isDisabledAddNumber = computeIsDisabledAddNumber.value
const isDisabledSubtractNumber = computeIsDisabledSubtractNumber.value
return h('span', {
class: 'vxe-input--number-suffix'
}, [
h('span', {
class: 'vxe-input--number-prev is--prev',
class: ['vxe-input--number-prev is--prev', {
'is--disabled': isDisabledAddNumber
}],
onMousedown: numberMousedownEvent,
onMouseup: numberStopDown,
onMouseleave: numberStopDown
@@ -2073,7 +2119,9 @@ export default defineComponent({
})
]),
h('span', {
class: 'vxe-input--number-next is--next',
class: ['vxe-input--number-next is--next', {
'is--disabled': isDisabledSubtractNumber
}],
onMousedown: numberMousedownEvent,
onMouseup: numberStopDown,
onMouseleave: numberStopDown

View File

@@ -4,7 +4,7 @@ import { getFuncText } from '../../tools/utils'
import GlobalConfig from '../../v-x-e-table/src/conf'
import { useSize } from '../../hooks/size'
import { VxeRadioButtonPropTypes, VxeRadioGroupConstructor, VxeRadioButtonConstructor, VxeRadioButtonEmits, VxeRadioGroupPrivateMethods, RadioButtonMethods } from '../../../types/all'
import { VxeRadioButtonPropTypes, VxeRadioGroupConstructor, VxeRadioButtonConstructor, VxeRadioButtonEmits, VxeRadioGroupPrivateMethods, RadioButtonMethods, VxeFormConstructor, VxeFormPrivateMethods, VxeFormDefines } from '../../../types/all'
export default defineComponent({
name: 'VxeRadioButton',
@@ -23,6 +23,8 @@ export default defineComponent({
] as VxeRadioButtonEmits,
setup (props, context) {
const { slots, emit } = context
const $xeform = inject<VxeFormConstructor & VxeFormPrivateMethods | null>('$xeform', null)
const $xeformiteminfo = inject<VxeFormDefines.ProvideItemInfo | null>('$xeformiteminfo', null)
const xID = XEUtils.uniqueId()
@@ -69,6 +71,10 @@ export default defineComponent({
} else {
emit('update:modelValue', label)
radioButtonMethods.dispatchEvent('change', { label }, evnt)
// 自动更新校验状态
if ($xeform && $xeformiteminfo) {
$xeform.triggerItemEvent(evnt, $xeformiteminfo.itemConfig.field, label)
}
}
}

View File

@@ -1,9 +1,9 @@
import { defineComponent, h, provide, PropType } from 'vue'
import { defineComponent, h, provide, PropType, inject } from 'vue'
import XEUtils from 'xe-utils'
import GlobalConfig from '../../v-x-e-table/src/conf'
import { useSize } from '../../hooks/size'
import { VxeRadioGroupPropTypes, VxeRadioGroupConstructor, VxeRadioGroupEmits, VxeRadioGroupPrivateMethods, RadioGroupPrivateMethods, RadioGroupMethods } from '../../../types/all'
import { VxeRadioGroupPropTypes, VxeRadioGroupConstructor, VxeRadioGroupEmits, VxeRadioGroupPrivateMethods, RadioGroupPrivateMethods, RadioGroupMethods, VxeFormConstructor, VxeFormPrivateMethods, VxeFormDefines } from '../../../types/all'
export default defineComponent({
name: 'VxeRadioGroup',
@@ -19,6 +19,8 @@ export default defineComponent({
] as VxeRadioGroupEmits,
setup (props, context) {
const { slots, emit } = context
const $xeform = inject<VxeFormConstructor & VxeFormPrivateMethods | null>('$xeform', null)
const $xeformiteminfo = inject<VxeFormDefines.ProvideItemInfo | null>('$xeformiteminfo', null)
const xID = XEUtils.uniqueId()
@@ -34,9 +36,13 @@ export default defineComponent({
useSize(props)
const radioGroupPrivateMethods: RadioGroupPrivateMethods = {
handleChecked (params) {
handleChecked (params, evnt) {
emit('update:modelValue', params.label)
radioGroupMethods.dispatchEvent('change', params)
// 自动更新校验状态
if ($xeform && $xeformiteminfo) {
$xeform.triggerItemEvent(evnt, $xeformiteminfo.itemConfig.field, params.label)
}
}
}

View File

@@ -4,7 +4,7 @@ import { getFuncText } from '../../tools/utils'
import GlobalConfig from '../../v-x-e-table/src/conf'
import { useSize } from '../../hooks/size'
import { VxeRadioPropTypes, VxeRadioConstructor, VxeRadioEmits, VxeRadioGroupConstructor, VxeRadioGroupPrivateMethods, RadioMethods } from '../../../types/all'
import { VxeRadioPropTypes, VxeRadioConstructor, VxeRadioEmits, VxeRadioGroupConstructor, VxeRadioGroupPrivateMethods, RadioMethods, VxeFormConstructor, VxeFormPrivateMethods, VxeFormDefines } from '../../../types/all'
export default defineComponent({
name: 'VxeRadio',
@@ -24,6 +24,8 @@ export default defineComponent({
] as VxeRadioEmits,
setup (props, context) {
const { slots, emit } = context
const $xeform = inject<VxeFormConstructor & VxeFormPrivateMethods | null>('$xeform', null)
const $xeformiteminfo = inject<VxeFormDefines.ProvideItemInfo | null>('$xeformiteminfo', null)
const xID = XEUtils.uniqueId()
@@ -62,6 +64,10 @@ export default defineComponent({
} else {
emit('update:modelValue', label)
radioMethods.dispatchEvent('change', { label }, evnt)
// 自动更新校验状态
if ($xeform && $xeformiteminfo) {
$xeform.triggerItemEvent(evnt, $xeformiteminfo.itemConfig.field, label)
}
}
}

View File

@@ -1,4 +1,4 @@
import { defineComponent, h, Teleport, PropType, ref, Ref, VNode, resolveComponent, ComponentOptions, computed, provide, onUnmounted, reactive, nextTick, watch, onMounted } from 'vue'
import { defineComponent, h, Teleport, PropType, ref, Ref, inject, VNode, resolveComponent, ComponentOptions, computed, provide, onUnmounted, reactive, nextTick, watch, onMounted } from 'vue'
import XEUtils from 'xe-utils'
import GlobalConfig from '../../v-x-e-table/src/conf'
import { useSize } from '../../hooks/size'
@@ -6,7 +6,7 @@ import { getEventTargetNode, getAbsolutePos } from '../../tools/dom'
import { getLastZIndex, nextZIndex, getFuncText, formatText } from '../../tools/utils'
import { GlobalEvent, hasEventKey, EVENT_KEYS } from '../../tools/event'
import { VxeSelectPropTypes, VxeSelectConstructor, SelectReactData, VxeSelectEmits, SelectMethods, SelectPrivateRef, VxeSelectMethods, VxeInputConstructor, VxeOptgroupProps, VxeOptionProps } from '../../../types/all'
import { VxeSelectPropTypes, VxeSelectConstructor, SelectReactData, VxeSelectEmits, SelectMethods, SelectPrivateRef, VxeSelectMethods, VxeInputConstructor, VxeOptgroupProps, VxeOptionProps, VxeFormDefines, VxeFormConstructor, VxeFormPrivateMethods } from '../../../types/all'
function isOptionVisible (option: any) {
return option.visible !== false
@@ -49,6 +49,8 @@ export default defineComponent({
] as VxeSelectEmits,
setup (props, context) {
const { slots, emit } = context
const $xeform = inject<VxeFormConstructor & VxeFormPrivateMethods | null>('$xeform', null)
const $xeformiteminfo = inject<VxeFormDefines.ProvideItemInfo | null>('$xeformiteminfo', null)
const xID = XEUtils.uniqueId()
@@ -370,6 +372,10 @@ export default defineComponent({
if (selectValue !== props.modelValue) {
emit('update:modelValue', selectValue)
selectMethods.dispatchEvent('change', { value: selectValue }, evnt)
// 自动更新校验状态
if ($xeform && $xeformiteminfo) {
$xeform.triggerItemEvent(evnt, $xeformiteminfo.itemConfig.field, selectValue)
}
}
}

View File

@@ -1,10 +1,10 @@
import { defineComponent, h, ref, Ref, computed, reactive, nextTick, createCommentVNode, PropType } from 'vue'
import { defineComponent, h, ref, Ref, computed, reactive, nextTick, createCommentVNode, PropType, inject } from 'vue'
import XEUtils from 'xe-utils'
import GlobalConfig from '../../v-x-e-table/src/conf'
import { useSize } from '../../hooks/size'
import { getFuncText } from '../../tools/utils'
import { VxeSwitchPropTypes, VxeSwitchConstructor, VxeSwitchEmits, SwitchReactData, SwitchMethods } from '../../../types/all'
import { VxeSwitchPropTypes, VxeSwitchConstructor, VxeSwitchEmits, SwitchReactData, SwitchMethods, VxeFormConstructor, VxeFormPrivateMethods, VxeFormDefines } from '../../../types/all'
export default defineComponent({
name: 'VxeSwitch',
@@ -27,6 +27,8 @@ export default defineComponent({
] as VxeSwitchEmits,
setup (props, context) {
const { emit } = context
const $xeform = inject<VxeFormConstructor & VxeFormPrivateMethods | null>('$xeform', null)
const $xeformiteminfo = inject<VxeFormDefines.ProvideItemInfo | null>('$xeformiteminfo', null)
const xID = XEUtils.uniqueId()
@@ -70,6 +72,10 @@ export default defineComponent({
reactData.hasAnimat = true
emit('update:modelValue', value)
switchMethods.dispatchEvent('change', { value }, evnt)
// 自动更新校验状态
if ($xeform && $xeformiteminfo) {
$xeform.triggerItemEvent(evnt, $xeformiteminfo.itemConfig.field, value)
}
_atimeout = setTimeout(() => {
reactData.hasAnimat = false
}, 400)

View File

@@ -1,10 +1,10 @@
import { defineComponent, h, ref, Ref, computed, nextTick, watch, PropType, reactive } from 'vue'
import { defineComponent, h, ref, Ref, computed, nextTick, watch, PropType, reactive, inject } from 'vue'
import XEUtils from 'xe-utils'
import GlobalConfig from '../../v-x-e-table/src/conf'
import { getFuncText } from '../../tools/utils'
import { useSize } from '../../hooks/size'
import { VxeTextareaPropTypes, TextareaReactData, TextareaMethods, VxeTextareaConstructor, VxeTextareaEmits, TextareaPrivateRef } from '../../../types/all'
import { VxeTextareaPropTypes, TextareaReactData, TextareaMethods, VxeTextareaConstructor, VxeTextareaEmits, TextareaPrivateRef, VxeFormConstructor, VxeFormPrivateMethods, VxeFormDefines } from '../../../types/all'
let autoTxtElem: HTMLDivElement
@@ -40,6 +40,8 @@ export default defineComponent({
] as VxeTextareaEmits,
setup (props, context) {
const { emit } = context
const $xeform = inject<VxeFormConstructor & VxeFormPrivateMethods | null>('$xeform', null)
const $xeformiteminfo = inject<VxeFormDefines.ProvideItemInfo | null>('$xeformiteminfo', null)
const xID = XEUtils.uniqueId()
@@ -136,6 +138,10 @@ export default defineComponent({
emit('update:modelValue', value)
if (XEUtils.toValueString(props.modelValue) !== value) {
textareaMethods.dispatchEvent('change', { value }, evnt)
// 自动更新校验状态
if ($xeform && $xeformiteminfo) {
$xeform.triggerItemEvent(evnt, $xeformiteminfo.itemConfig.field, value)
}
}
}

View File

@@ -314,7 +314,7 @@ const validatorHook: VxeGlobalHooksHandles.HookOptions = {
}
} else {
const isArrType = type === 'array'
const hasEmpty = isArrType ? (!XEUtils.isArray(cellValue) || !cellValue.length) : eqEmptyValue(cellValue)
const hasEmpty = isArrType || XEUtils.isArray(cellValue) ? (!XEUtils.isArray(cellValue) || !cellValue.length) : eqEmptyValue(cellValue)
if (required ? (hasEmpty || validErrorRuleValue(rule, cellValue)) : (!hasEmpty && validErrorRuleValue(rule, cellValue))) {
validRuleErr = true
errorRules.push(new Rule(rule))

View File

@@ -325,10 +325,10 @@
&:before {
@extend %PseudoClass;
content: "+";
left: -0.05em;
bottom: 0;
line-height: 0.9em;
font-size: 1.4em;
left: -0.12em;
bottom: -0.1em;
line-height: 1em;
font-size: 1.6em;
}
}
@@ -355,11 +355,12 @@
@extend %DefaultWidthHeight;
&:before {
@extend %PseudoClass;
content: "\D7";
left: -0.05em;
bottom: 0;
line-height: 0.8em;
font-size: 1.4em;
content: "+";
left: -0.1em;
bottom: -0.16em;
line-height: 1em;
font-size: 1.8em;
transform: rotate(45deg);
}
}

View File

@@ -212,6 +212,10 @@ $iconWidth: 1.6em;
&:active {
color: $vxe-primary-color;
}
&.is--disabled {
cursor: no-drop;
color: $vxe-input-number-disabled-color;
}
}
}
}

View File

@@ -187,6 +187,7 @@ $vxe-button-round-border-radius-mini: 14px !default;
/*input*/
$vxe-input-background-color: #fff !default;
$vxe-input-panel-background-color: $vxe-input-background-color !default;
$vxe-input-number-disabled-color: #e4e7ed !default;
$vxe-input-date-festival-color: #999999 !default;
$vxe-input-date-festival-important-color: $vxe-primary-color !default;
$vxe-input-date-notice-background-color: #FF0000 !default;

14
types/form.d.ts vendored
View File

@@ -150,9 +150,14 @@ export interface FormMethods {
/**
* 更新项状态
* 当使用自定义渲染时可能会用到
* @param scope 插槽对象
* @param params 插槽对象
*/
updateStatus(scope: any, itemValue?: any): void
updateStatus(
params: {
field: VxeFormItemPropTypes.Field
},
itemValue?: any
): void
/**
* 获取表单项列表
*/
@@ -176,6 +181,7 @@ export interface VxeFormMethods extends FormMethods { }
export interface FormPrivateMethods {
callSlot<T>(slotFunc: ((params: T) => any[]) | string | null, params: T): VNode[]
triggerItemEvent(evnt: Event | { type: string }, field: string, itemValue?: any): Promise<any>
toggleCollapseEvent(evnt: Event): void
triggerTitleTipEvent(evnt: MouseEvent, params: {
item: VxeFormDefines.ItemInfo
@@ -264,6 +270,10 @@ export namespace VxeFormDefines {
property: string
}
export interface ProvideItemInfo {
itemConfig: ItemInfo
}
export interface ValidateErrorMapParams {
[field: string]: ValidateErrorParams[]
}