Vue-搜索组件封装
组件代码:
<!--
* @Descripttion:搜索组件-->
<template>
<div class='YxkSearch'>
<el-form :model="form" :ref="$attrs.formRef" v-bind="$attrs">
<!-- 搜索项 -->
<template>
<el-form-item v-for="(item, index) in searchObj.list" :key="index" v-bind="formItemBind(item)">
<FormItem :form="form" :params="item" :selectOptions="selectOptions">
<template v-slot:[item.slots]="scope">
<slot :name="item.slots" :scope="{...scope, $index: index}"></slot>
</template>
</FormItem>
</el-form-item>
</template>
<!-- 搜索按钮 -->
<template>
<el-form-item v-for="item in searchObj.button" :key="item.text">
<FormButton :params="item">
<template v-slot:text="scope">{{scope.text}}</template>
</FormButton>
</el-form-item>
</template>
</el-form>
</div>
</template>
<script>
// 搜索项
const FormItem = {
props: {
form: {
type: Object
},
params: {
type: Object
},
selectOptions: {
type: Object
}
},
render(createElement) {
// 选择项
const options = (params, list) => {
// 属性
let item = JSON.parse(JSON.stringify(list))
let props = {
attrs: {
...item
},
domProps: {},
children: []
}
// 属性key值
if (params.keys) {
for (let key in params.keys) {
props.attrs[key] = item[params.keys[key]]
if (key == 'text') {
item.text = item[params.keys[key]]
}
}
}
this.selectOptions.list.map(list => {
if (params.ele == list.ele) props.ele = list.child // 选择项-元素
if (this.selectOptions.type.indexOf(params.ele) != -1) { // 选择项-文本
props.children = [{
ele: 'span',
domProps: {
innerHTML: item.text
}
}]
}
})
// 删除附属属性
if (item.id !== undefined) delete props.attrs.id
if (item.text) delete props.attrs.text
return createNode(props)
}
const createNode = params => {
// 元素ele
let ele = params.ele
// 属性
let props = {
attrs: {
...params.attrs
},
domProps: {
...params.domProps
},
on: {}
}
// v-model绑定
if (params.model && !params.slots) {
props.attrs.value = this.form[params.model]
props.on.input = e => {
this.$set(this.form, params.model, e)
}
}
// 子元素
let childNodes = []
if (params.children) {
childNodes = params.children.map(item => {
return createNode(item)
})
}
if (params.options) { // 子元素-选择项
childNodes = params.options.map(item => {
return options(params, item)
})
}
// 事件
if (params.on) {
Object.assign(props.on, params.on)
}
// 插槽
if (params.slots) {
childNodes.push(this.$scopedSlots[params.slots](params))
}
return createElement(ele, props, childNodes)
}
return createNode(this.params)
},
}
// 按钮
const FormButton = {
props: {
params: {
type: Object
}
},
render(createElement) {
const createNode = params => {
// ele 元素
let ele = params.ele || 'el-button'
// 属性
let attrs = JSON.parse(JSON.stringify(params))
if (attrs.text) delete attrs.text
if (attrs.click) delete attrs.click
let props = {
attrs: {
...attrs
},
on: {}
}
// 事件
if (params.click) {
props.on.click = params.click
}
// 子元素
let childNodes = []
childNodes.push(this.$scopedSlots.text(params))
return createElement(ele, props, childNodes)
}
return createNode(this.params)
},
}
export default {
name: 'YxkSearch',
componentName: 'YxkSearch',
props: {
searchObj: {
type: Object,
default: () => {
return {}
}
},
form: {
type: Object
}
},
components: {
FormItem,
FormButton
},
data() {
return {
selectOptions: {}
}
},
methods: {
// v-bind
formItemBind(obj) {
if (!this.searchObj.button) { // 默认搜索按钮
this.searchObj.button = [{
text: '搜索',
plain: true,
type: 'primary',
icon: 'el-icon-search',
click: () => this.searchSet()
}]
}
return this.deleteParams(obj, ['ele', 'model', 'attrs', 'on', 'domProps', 'options', 'keys', 'slots'])
},
// delete params
deleteParams(obj, arr) {
let params = JSON.parse(JSON.stringify(obj))
arr.forEach(item => {
delete params[item]
})
return params
},
// 默认搜索事件
searchSet() {
this.$emit('searchSet')
},
// 键盘回车事件
onKeyDown() {
if (this.searchObj.isKeyDown !== false) {
document.onkeydown = () => {
const key = window.event.keyCode;
if (key == 13) this.$emit('searchSet')
}
}
},
// 初始化
initialSet() {
this.selectOptions = {
list: [{ // 选择项
ele: 'el-radio-group',
child: 'el-radio'
}, {
ele: 'el-checkbox-group',
child: 'el-checkbox'
}, {
ele: 'el-select',
child: 'el-option'
}],
type: ['el-radio-group', 'el-checkbox-group'] // 特殊处理选择项
}
}
},
computed: {},
watch: {},
created() {
this.initialSet()
this.onKeyDown()
},
mounted() {}
}
</script>
<style lang='scss'>
.YxkSearch {
padding: 20px;
background: #fff;
.el-form {
display: flex;
flex-wrap: wrap;
align-items: flex-end;
.el-form-item {
margin: 0 22px 22px 0;
.el-checkbox-group {
display: flex;
width: 100%;
}
.el-input,
.el-select {
width: 100%;
}
}
}
}
</style>
示例:

参数说明:
YxkSearch
searchObj.list
searchObj.button
slot
事件 Events

浙公网安备 33010602011771号