优化自定义控件表单验证

This commit is contained in:
Gary Fu
2024-01-06 19:28:58 +08:00
parent 62f7ad4b9c
commit 38f6ea96d6
5 changed files with 39 additions and 14 deletions

View File

@@ -35,11 +35,13 @@
* @property {string} loadingText 加载提示loading * @property {string} loadingText 加载提示loading
* @property {string} minHeight 高度自定义 * @property {string} minHeight 高度自定义
* @property {Object} inputAttrs 输入框配置项 * @property {Object} inputAttrs 输入框配置项
* @property {boolean} validateEvent 验证事件
*/ */
import { computed, nextTick, onMounted, ref, watch } from 'vue' import { computed, nextTick, onMounted, ref, watch } from 'vue'
import { debounce, isObject } from 'lodash' import { debounce, isObject } from 'lodash'
import { onClickOutside, onKeyStroke, useVModel } from '@vueuse/core' import { onClickOutside, onKeyStroke, useVModel } from '@vueuse/core'
import chunk from 'lodash/chunk' import chunk from 'lodash/chunk'
import { UPDATE_MODEL_EVENT, CHANGE_EVENT, useFormItem } from 'element-plus'
/** /**
* @type {CommonAutocompleteProps} * @type {CommonAutocompleteProps}
@@ -124,10 +126,14 @@ const props = defineProps({
minHeight: { minHeight: {
type: String, type: String,
default: '100px' default: '100px'
},
validateEvent: {
type: Boolean,
default: true
} }
}) })
const emit = defineEmits(['update:modelValue', 'change', 'update:defaultLabel']) const emit = defineEmits([UPDATE_MODEL_EVENT, CHANGE_EVENT, 'update:defaultLabel'])
// 关键字搜索 // 关键字搜索
const keywords = ref(props.defaultLabel) const keywords = ref(props.defaultLabel)
// 上次搜索记录 // 上次搜索记录
@@ -211,7 +217,6 @@ onMounted(() => {
watch(() => popoverVisible.value, (val) => { watch(() => popoverVisible.value, (val) => {
if (!val) { if (!val) {
nextTick(() => { nextTick(() => {
console.info('=======================', lastAutocompleteLabel.value, keywords.value)
if (lastAutocompleteLabel.value && keywords.value && keywords.value !== lastAutocompleteLabel.value) { if (lastAutocompleteLabel.value && keywords.value && keywords.value !== lastAutocompleteLabel.value) {
keywords.value = lastAutocompleteLabel.value keywords.value = lastAutocompleteLabel.value
} }
@@ -224,10 +229,15 @@ watch(() => props.modelValue, (value) => {
if (!props.useIdModel) { if (!props.useIdModel) {
setAutocompleteLabel(value && isObject(value) ? value[labelProp.value] : '') setAutocompleteLabel(value && isObject(value) ? value[labelProp.value] : '')
} }
vModel.value = value
}) })
watch(() => props.defaultLabel, (label) => { watch(() => {
if (!props.useIdModel) {
const value = props.modelValue
return value && isObject(value) ? value[labelProp.value] : ''
}
return props.defaultLabel
}, (label) => {
setAutocompleteLabel(label) setAutocompleteLabel(label)
}) })
@@ -242,20 +252,25 @@ const setAutocompleteLabel = label => {
lastAutocompleteLabel.value = label lastAutocompleteLabel.value = label
} }
const { formItem } = useFormItem()
const onSelectData = (row) => { const onSelectData = (row) => {
popoverVisible.value = false popoverVisible.value = false
if (!vModel.value && !row) { if (!vModel.value && !row) {
return return
} }
let label = '' let label = ''
let value = null let value
if (row) { if (row) {
label = row[labelProp.value] label = row[labelProp.value]
value = props.useIdModel ? row[idProp.value] : row value = props.useIdModel ? row[idProp.value] : row
} }
setAutocompleteLabel(label) setAutocompleteLabel(label)
vModel.value = value vModel.value = value
emit('change', row) emit(CHANGE_EVENT, row)
if (props.validateEvent) {
formItem?.validate(CHANGE_EVENT)
}
} }
// =======================按键处理=================== // =======================按键处理===================

View File

@@ -77,6 +77,7 @@ const initRules = () => {
if (option.required !== undefined) { if (option.required !== undefined) {
const label = option.label || $i18nBundle(option.labelKey) const label = option.label || $i18nBundle(option.labelKey)
_rules = [{ _rules = [{
trigger: option.trigger,
required: option.required, required: option.required,
message: $i18nBundle('common.msg.nonNull', [label]) message: $i18nBundle('common.msg.nonNull', [label])
}, ..._rules] }, ..._rules]

View File

@@ -2,6 +2,7 @@
import { computed, ref } from 'vue' import { computed, ref } from 'vue'
import { filterIconsByKeywords } from '@/services/icon/IconService' import { filterIconsByKeywords } from '@/services/icon/IconService'
import { useVModel } from '@vueuse/core' import { useVModel } from '@vueuse/core'
import { UPDATE_MODEL_EVENT, CHANGE_EVENT, useFormItem } from 'element-plus'
const props = defineProps({ const props = defineProps({
modelValue: { modelValue: {
@@ -37,6 +38,10 @@ const props = defineProps({
placeholder: { placeholder: {
type: String, type: String,
default: '' default: ''
},
validateEvent: {
type: Boolean,
default: true
} }
}) })
const iconSelectVisible = ref(false) const iconSelectVisible = ref(false)
@@ -49,13 +54,19 @@ const filterIcons = computed(() => {
return [] return []
}) })
const emit = defineEmits(['update:modelValue']) const emit = defineEmits([UPDATE_MODEL_EVENT, CHANGE_EVENT])
const vModel = useVModel(props, 'modelValue', emit) const vModel = useVModel(props, 'modelValue', emit)
const { formItem } = useFormItem()
const selectIcon = icon => { const selectIcon = icon => {
iconSelectVisible.value = false iconSelectVisible.value = false
vModel.value = icon vModel.value = icon
emit(CHANGE_EVENT, icon)
if (props.validateEvent) {
formItem?.validate(CHANGE_EVENT)
}
} }
</script> </script>
@@ -86,7 +97,7 @@ const selectIcon = icon => {
type="danger" type="danger"
:disabled="disabled||readonly" :disabled="disabled||readonly"
size="small" size="small"
@click="vModel = ''" @click="selectIcon()"
> >
{{ $t('common.label.clear') }} {{ $t('common.label.clear') }}
</el-button> </el-button>

View File

@@ -1,6 +1,7 @@
<script setup> <script setup>
import { useVModel } from '@vueuse/core' import { useVModel } from '@vueuse/core'
import { computed, ref } from 'vue' import { computed } from 'vue'
import { UPDATE_MODEL_EVENT } from 'element-plus'
const props = defineProps({ const props = defineProps({
modelValue: { modelValue: {
@@ -65,7 +66,7 @@ const props = defineProps({
} }
}) })
const emit = defineEmits(['update:modelValue']) const emit = defineEmits([UPDATE_MODEL_EVENT])
const showDialog = useVModel(props, 'modelValue', emit) // 自动响应v-model const showDialog = useVModel(props, 'modelValue', emit) // 自动响应v-model
const okButtonClick = $event => { const okButtonClick = $event => {

View File

@@ -149,10 +149,7 @@ const formOptions = computed(() => {
} }
}] }]
}) })
const userDto = ref({ const userDto = ref({})
userName: '',
userPassword: ''
})
const submitForm = (form) => { const submitForm = (form) => {
console.info(form) console.info(form)
form.validate((valid) => { form.validate((valid) => {