1.背景:
介绍:
vue结合element–ui的后台管理系统,会有很多的数据表格,结合数据表格的会有很多搜索选项。我们的搜索栏区域每一个数据表格搜索条件都不一样,并且在多人开发的情况下样式也不相同,布局样式还不能统一。
考虑到这一个问题,我们来封装一个搜索组件,统一配置,提升开发效率,并且减少一定量的代码量。
2.问题分析
项目使用的是elementui框架,搜索栏这种表单提交,首先要使用el–form组件来封装,而复杂点就是表单项可能有很多种,例如input输入框、select选择框、日期时间选择框、日期时间范围选择框、cascader级联选择框等,每一项的字段名prop、名称label、绑定的属性方法都不尽相同。所以不能通过普通的绑定个别属性的方式来处理,而slot插槽的方式也无法简化,最终决定通过传递一个配置项数组的形式来解析生成相应的结构。
3.组件实现:
目前实现的方式由两部分组成,一部分是form表单组件,接受父组件传递的配置项数组,一部分是封装一些常用的表单项组件,通过v–if来控制,form表单组件里引入该表单项组件,循环遍历,根据传递的表单项类型来匹配显示具体的表单项。
示例代码1
<el-form
class="search-block"
ref="searchFormRef"
:model="formModel"
:inline="props.inline"
>
<el-row>
<el-form-item
v-for="(item, key) in props.searchForm"
:key="key"
:label="item.label"
:prop="key"
:class="item.class"
>
<template
v-if="item.component === 'el-date-picker' && item.customContent"
>
<el-date-picker
v-bind="item.attrs"
v-model="formModel[key]"
:style="item.style || 'width:258px'"
clearable
:editable="false"
:type="item.type || ''"
:prefix-icon="item.customPrefix ? customPrefix : ''"
>
</el-date-picker>
</template>
</el-form-item>
</el-row>
</el-form>
示例代码2
<el-form
class="search-block"
ref="searchFormRef"
:model="formModel"
:inline="props.inline"
>
<el-row>
<component
:is="item.component"
v-bind="item.attrs"
v-on="item.event"
v-model="formModel[key]"
:id="item.id"
clearable
v-if="!item.customContent"
:style="item.style || 'width:158px'"
:prefix-icon="item.customPrefix ? customPrefix : ''"
>
<template #default v-if="item.component === 'el-select'">
<el-option
v-for="option in item.options"
:key="option.key"
:value="option.key"
:label="option.value"
>
</el-option>
</template>
</component>
</el-form-item>
</el-row>
</el-form>
4.参数配置:
4.1组件内参数示例:
<script setup>
const props = defineProps({
title: { type: String, default: '搜索' },
searchForm: { type: Object }, // 传入的数据
inline: {
type: Boolean,
default: true
},
searchBtnShow: { // 是否显示【搜索】【清空】按钮
type: Boolean,
default: true
},
emitSearch: [Object, String] // 解决跳转页码后选择器内容为空
})
</script>
4.2组件外传入参数配置示例
// 搜索栏数据
const searchForm = reactive({
projectName: {
label: '项目名称',
component: 'el-input',
attrs: {
},
options: [],
style: {
},
event: {}
},
indicatorId: {
label: '关联病理指标',
component: 'el-select',
attrs: {
},
options: [],
style: {
},
event: {}
},
beginTime: {
label: '创建时间',
component: 'el-date-picker',
attrs: {
rangeSeparator: '至',
valueFormat: 'YYYY-MM-DD'
},
customPrefix: true,
customContent: true,
id: 'start-time',
type: 'daterange',
event: {},
child: {
}
}
})
5.使用示例
- 组件引入
<template>
<search :searchForm="searchForm" title="" />
</template>
<script setup>
import search from '@/components/search'
// 搜索栏数据
const searchForm = reactive({
projectName: {
label: '项目名称',
component: 'el-input',
attrs: {
},
options: [],
style: {
},
event: {}
},
indicatorId: {
label: '关联病理指标',
component: 'el-select',
attrs: {
},
options: [],
style: {
},
event: {}
},
beginTime: {
label: '创建时间',
component: 'el-date-picker',
attrs: {
rangeSeparator: '至',
valueFormat: 'YYYY-MM-DD'
},
customPrefix: true,
customContent: true,
id: 'start-time',
type: 'daterange',
event: {},
child: {
}
}
})
</script>
6.完成代码
1.search.vue
<template>
<div class="search-module">
<div class="title-heading" v-if="props.title">
<span>{{ props.title }}</span>
</div>
<!-- 搜索 -->
<el-form
class="search-block"
ref="searchFormRef"
:model="formModel"
:inline="props.inline"
>
<el-row>
<el-form-item
v-for="(item, key) in props.searchForm"
:key="key"
:label="item.label"
:prop="key"
:class="item.class"
>
<template
v-if="item.component === 'el-date-picker' && item.customContent"
>
<el-date-picker
v-bind="item.attrs"
v-model="formModel[key]"
:style="item.style || 'width:258px'"
clearable
:editable="false"
:type="item.type || ''"
:prefix-icon="item.customPrefix ? customPrefix : ''"
>
</el-date-picker>
</template>
<component
:is="item.component"
v-bind="item.attrs"
v-on="item.event"
v-model="formModel[key]"
:id="item.id"
clearable
v-if="!item.customContent"
:style="item.style || 'width:158px'"
:prefix-icon="item.customPrefix ? customPrefix : ''"
>
<template #default v-if="item.component === 'el-select'">
<el-option
v-for="option in item.options"
:key="option.key"
:value="option.key"
:label="option.value"
>
</el-option>
</template>
</component>
</el-form-item>
<div class="search-btn" v-if="searchBtnShow">
<el-button type="primary" class="btn-default-blue" @click="searchSubmit('searchFormRef')"
>搜索</el-button
>
<el-button type="primary" class="btn-default-blue" @click="resetSubmit('searchFormRef')"
>清空</el-button
>
</div>
</el-row>
</el-form>
</div>
</template>
<script setup>
const props = defineProps({
title: { type: String, default: '搜索' },
searchForm: { type: Object },
inline: {
type: Boolean,
default: true
},
searchBtnShow: { // 是否显示【搜索】【清空】按钮
type: Boolean,
default: true
},
emitSearch: [Object, String] // 解决跳转页码后选择器内容为空
})
const formModel = ref({})
onBeforeMount(() => {
const keys = Object.keys(props.searchForm)
const obj = {}
keys.forEach(key => {
obj[key] = props.searchForm[key].defaultValue || ''
})
formModel.value = Object.assign({}, formModel.value, obj)
})
const searchFormRef = ref(null)
const emit = defineEmits(['refreshData', 'update:emitSearch'])
// 日期自定义样式
const customPrefix = shallowRef({
render () {
return h('p', { class: 'icon-rili-01 font_family icon-size' })
}
})
const searchSubmit = () => {
formModel.value.params = {}
if (formModel.value?.beginTime) {
const date = {
beginTime: formModel.value.beginTime[0],
endTime: formModel.value.beginTime[1]
}
formModel.value.params['beginTime'] = date.beginTime
formModel.value.params['endTime'] = date.endTime
} else if (!formModel.value.beginTime) {
formModel.value.params['beginTime'] = ''
formModel.value.params['endTime'] = ''
}
let assignForm = {...formModel.value}
delete assignForm.beginTime
emit('update:emitSearch', assignForm)
emit('refreshData', assignForm, true)
/* emit('update:emitSearch', Object.assign({}, formModel.value))
emit('refreshData', Object.assign({}, formModel.value)) */
}
const resetSubmit = () => {
searchFormRef.value.clearValidate()
searchFormRef.value.resetFields()
emit('update:emitSearch', null)
emit('refreshData', null)
}
defineExpose({
resetSubmit
})
</script>
<style lang="scss" scoped>
.search-module {
display: flex;
// height: 90px;
// padding: 0 20px;
flex-direction: column;
// border-bottom: 1px solid #ccc;
.title-heading {
font-size: 20px;
color: #333333;
font-weight: 500;
height: 50%;
line-height: 3.5;
// ::before {
vertical-align: middle;
// }
}
:deep(.el-form-item) {
margin-bottom: unset;
margin-right: 40px;
height: 55px;
.el-range-separator {
line-height: 1.5;
}
}
.date-del-margin {
margin-right: 0px;
}
:deep(.el-form-item__label) {
line-height: 55px;
}
/* .date-dash {
:deep(.el-form-item__label) {
padding: 0 4px;
}
} */
.search-block {
display: flex;
margin: auto 0;
> div {
margin-right: 40px;
/* display: inherit;
align-items: baseline; */
}
:deep(.el-input__inner) {
height: 30px;
}
.search-time {
:deep(.el-input) {
width: 158px;
}
}
:deep(.el-input__prefix) {
right: 5px;
// left: unset;
}
.search-btn {
// height: 100%;
line-height: 55px;
button {
min-height: unset;
height: 26px;
min-width: 62px;
padding: 0px;
}
}
}
}
</style>
2.index.vue
<template>
<search :searchForm="searchForm" title="" />
</template>
<script setup>
import search from '@/components/search'
// 搜索栏数据
const searchForm = reactive({
projectName: {
label: '项目名称',
component: 'el-input',
attrs: {
},
options: [],
style: {
},
event: {}
},
indicatorId: {
label: '关联病理指标',
component: 'el-select',
attrs: {
},
options: [],
style: {
},
event: {}
},
beginTime: {
label: '创建时间',
component: 'el-date-picker',
attrs: {
rangeSeparator: '至',
valueFormat: 'YYYY-MM-DD'
},
customPrefix: true,
customContent: true,
id: 'start-time',
type: 'daterange',
event: {},
child: {
}
}
})
</script>
总结
vue结合elemen-ui的搜索组件封装就写完了,希望小伙伴们喜欢!!!
原文地址:https://blog.csdn.net/qq_27244301/article/details/128674571
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_49388.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!