search表单

This commit is contained in:
Gary Fu
2024-01-06 18:11:40 +08:00
parent a32d6b2eac
commit 62f7ad4b9c
5 changed files with 297 additions and 237 deletions

View File

@@ -97,6 +97,10 @@ html, body, #app, .index-container {
padding-top: 20px;
}
.common-form.el-form--inline .el-input{
--el-input-width: 220px;
}
.form-edit-width-70 {
width:70%
}

View File

@@ -29,6 +29,7 @@
* @property {string} labelKey label字段名
* @property {number} debounceTime 防抖时间
* @property {string} autocompleteWidth 宽度
* @property {string} inputWidth input宽度
* @property {CommonSelectPageOption} selectPageConfig 分页
* @property {Number} colSize 显示几列
* @property {string} loadingText 加载提示loading
@@ -36,7 +37,7 @@
* @property {Object} inputAttrs 输入框配置项
*/
import { computed, nextTick, onMounted, ref, watch } from 'vue'
import { debounce } from 'lodash'
import { debounce, isObject } from 'lodash'
import { onClickOutside, onKeyStroke, useVModel } from '@vueuse/core'
import chunk from 'lodash/chunk'
@@ -80,6 +81,10 @@ const props = defineProps({
type: String,
default: '500px'
},
inputWidth: {
type: String,
default: '220px'
},
autocompleteConfig: {
type: Object,
required: true
@@ -122,7 +127,7 @@ const props = defineProps({
}
})
const emit = defineEmits(['update:modelValue', 'onSelectData', 'update:defaultLabel'])
const emit = defineEmits(['update:modelValue', 'change', 'update:defaultLabel'])
// 关键字搜索
const keywords = ref(props.defaultLabel)
// 上次搜索记录
@@ -214,15 +219,32 @@ watch(() => popoverVisible.value, (val) => {
}
})
watch(() => props.modelValue, (value) => {
console.info('=====================value', value)
if (!props.useIdModel) {
setAutocompleteLabel(value && isObject(value) ? value[labelProp.value] : '')
}
vModel.value = value
})
watch(() => props.defaultLabel, (label) => {
setAutocompleteLabel(label)
})
//* ********************数据选择*********************
const vModel = useVModel(props, 'modelValue', emit)
const vAutocompleteLabel = useVModel(props, 'defaultLabel', emit)
const vDefaultLabel = useVModel(props, 'defaultLabel', emit)
const setAutocompleteLabel = label => {
keywords.value = label
vDefaultLabel.value = label
lastAutocompleteLabel.value = label
}
const onSelectData = (row) => {
popoverVisible.value = false
if (!vModel.value && !row) {
console.info('==================', row)
return
}
let label = ''
@@ -231,11 +253,9 @@ const onSelectData = (row) => {
label = row[labelProp.value]
value = props.useIdModel ? row[idProp.value] : row
}
keywords.value = label
vAutocompleteLabel.value = label
lastAutocompleteLabel.value = label
setAutocompleteLabel(label)
vModel.value = value
emit('onSelectData', row)
emit('change', row)
}
// =======================按键处理===================
@@ -316,7 +336,6 @@ const selectPagePaginationChange = (tab, pageNumber) => {
</script>
<template>
<div>
<el-popover
ref="autocompletePopover"
:visible="popoverVisible"
@@ -332,6 +351,7 @@ const selectPagePaginationChange = (tab, pageNumber) => {
:placeholder="placeholder||title"
:disabled="disabled"
:readonly="readonly"
:style="{width: inputWidth}"
v-bind="inputAttrs"
@input="onInputKeywords(true)"
@click="onInputKeywords(false)"
@@ -423,7 +443,6 @@ const selectPagePaginationChange = (tab, pageNumber) => {
</common-table>
</template>
</el-popover>
</div>
</template>
<style scoped>

View File

@@ -31,6 +31,10 @@ const props = defineProps({
type: Object,
default: null
},
validateOnRuleChange: {
type: Boolean,
default: false
},
showButtons: {
type: Boolean,
default: true
@@ -99,10 +103,9 @@ const emit = defineEmits(['submitForm', 'update:model'])
const formModel = useVModel(props, 'model', emit)
watch(() => props.options, (options) => {
console.info('=================options', options)
options.forEach(option => {
if (formModel.value && option.value) {
formModel.value[option.prop] = option.value
if (formModel.value) {
formModel.value[option.prop] = option.value || undefined
}
})
rules.value = initRules()
@@ -121,10 +124,12 @@ defineExpose({
<template>
<el-form
ref="form"
class="common-form"
:model="formModel"
:rules="rules"
:label-width="labelWidth"
v-bind="$attrs"
:validate-on-rule-change="validateOnRuleChange"
>
<common-form-control
v-for="(option,index) in options"

View File

@@ -1,10 +1,23 @@
<script setup>
import { ref } from 'vue'
import { computed, ref } from 'vue'
import { useCityAutocompleteConfig, useCitySelectPageConfig } from '@/services/city/CityService'
import { $i18nMsg } from '@/messages'
const defaultCity = ref({})
setTimeout(() => {
defaultCity.value = {
code: 'SHA',
nameCn: '上海',
nameEn: 'Shanghai'
}
}, 1000)
/**
* @type {[CommonFormOption]}
*/
const formOptions = ref([{
const formOptions = computed(() => {
return [{
label: '用户名',
prop: 'userName',
value: '',
@@ -17,7 +30,7 @@ const formOptions = ref([{
message: '用户名在2-6位之间'
}
]
}, {
}, {
label: '密码',
prop: 'userPassword',
value: '',
@@ -27,14 +40,14 @@ const formOptions = ref([{
attrs: {
showPassword: true
}
}, {
}, {
label: '出生日期',
type: 'date-picker',
prop: 'birthday',
value: '',
placeholder: '选择出生日期',
required: true
}, {
}, {
label: '兴趣爱好',
type: 'checkbox-group',
prop: 'hobby',
@@ -54,7 +67,7 @@ const formOptions = ref([{
value: 'sleep'
}
]
}, {
}, {
label: '职业',
type: 'select',
prop: 'career',
@@ -74,7 +87,7 @@ const formOptions = ref([{
value: 'teacher'
}
]
}, {
}, {
label: '性别',
type: 'radio-group',
prop: 'gender',
@@ -94,32 +107,48 @@ const formOptions = ref([{
value: 'unknown'
}
]
}, {
}, {
label: '图标',
prop: 'icon',
value: '',
type: 'common-icon-select',
required: true
}, {
}, {
label: '城市',
prop: 'city',
value: 'SHA',
value: defaultCity.value?.code,
type: 'common-autocomplete',
required: true,
placeholder: '请选择城市',
change: (city) => {
defaultCity.value = city
},
attrs: {
defaultLabel: '上海市',
defaultLabel: $i18nMsg(defaultCity.value?.nameCn, defaultCity.value?.nameEn),
autocompleteConfig: useCityAutocompleteConfig(),
selectPageConfig: useCitySelectPageConfig()
}
}, {
}, {
label: '城市1',
prop: 'city1',
value: defaultCity,
type: 'common-autocomplete',
required: true,
placeholder: '请选择城市1',
attrs: {
useIdModel: false,
autocompleteConfig: useCityAutocompleteConfig(),
selectPageConfig: useCitySelectPageConfig()
}
}, {
label: '地址',
prop: 'address',
value: '',
attrs: {
type: 'textarea'
}
}])
}]
})
const userDto = ref({
userName: '',
userPassword: ''

View File

@@ -82,20 +82,22 @@ const searchFormOptions = computed(() => {
{
label: '用户名',
prop: 'nameCn'
},
{
label: '关键字',
prop: 'keywords'
},
{
label: '地址',
prop: 'address'
}, {
label: $i18nMsg('性别', 'Gender'),
type: 'select',
prop: 'gender',
children: [{
type: 'option',
value: '',
label: '请选择'
}, {
type: 'option',
value: 'male',
label: $i18nMsg('男', 'Male')
}, {
type: 'option',
value: 'female',
label: $i18nMsg('女', 'Female')
}]
@@ -106,9 +108,9 @@ const doSearch = form => {
console.info('=================searchParam', searchParam.value)
}
/** *************用户编辑**************/
const currentUser = ref({})
const currentUser = ref(null)
const showEdit = ref(false)
const userFormOptions = ref(useUserFormOptions())
const userFormOptions = computed(() => useUserFormOptions())
const toEditUser = user => {
currentUser.value = { ...user }
showEdit.value = true
@@ -171,6 +173,7 @@ const submitForm = () => {
title="用户编辑"
>
<common-form
v-if="currentUser"
ref="formRef"
class="form-edit-width-100"
:model="currentUser"