cnbmai-ui/src/components/SearchBar/SearchBar.vue

314 lines
9.6 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="searchBarBox divHeight" id='searchBarBox' :style="{ paddingRight: isFold ? '55px' : '0px' }">
<el-form
:inline="true"
ref="searchBarForm"
:model="formInline"
class="searchBar"
>
<span class="blue-block" v-if="removeBlue ? false : true"></span>
<template v-for="item in formConfig">
<el-form-item
v-if="item.type !== ''"
:key="item.param"
:label="item.label ? item.label : ''"
:required="item.required ? item.required : false"
>
<el-input
v-if="item.type === 'input'"
v-model="formInline[item.param]"
:size="item.size ? item.size : 'small'"
clearable
:disabled="item.disabled ? item.disabled : false"
:style="item.width ? 'width:' + item.width + 'px' : 'width:200px'"
:placeholder="item.placeholder ? item.placeholder : ''"
/>
<el-select
v-if="item.type === 'select'"
v-model="formInline[item.param]"
:size="item.size ? item.size : 'small'"
:filterable="item.filterable ? item.filterable : false"
:multiple="item.multiple ? item.multiple : false"
:clearable="item.clearable === false ? false : true"
:style="item.width ? 'width:' + item.width + 'px' : 'width:200px'"
:placeholder="item.label"
@change="
item.onchange
? $emit('select-changed', {
param: item.param,
value: formInline[item.param]
})
: null
"
>
<el-option
v-for="(sub, i) in item.selectOptions"
:key="i"
:label="item.labelField ? sub[item.labelField] : sub['name']"
:value="item.valueField ? sub[item.valueField] : sub['id']"
/>
</el-select>
<el-date-picker
v-if="item.type === 'datePicker'"
:key="item.param"
:size="item.size ? item.size : 'small'"
v-model="formInline[item.param]"
:type="item.dateType"
:format="item.format ? item.format : 'yyyy-MM-dd'"
:value-format="item.valueFormat ? item.valueFormat : null"
:default-time="item.defaultTime || null"
:range-separator="item.rangeSeparator || null"
:start-placeholder="item.startPlaceholder || null"
:end-placeholder="item.endPlaceholder || null"
:placeholder="item.placeholder"
:picker-options="item.pickerOptions ? item.pickerOptions : null"
:clearable="item.clearable === false ? false : true"
:style="item.width ? 'width:' + item.width + 'px' : (item.dateType === 'datetimerange' ? 'width:340px' : (item.dateType === 'daterange' ? 'width:220px' : 'width:140px'))"
/>
<el-autocomplete
v-if="item.type === 'autocomplete'"
v-model="formInline[item.param]"
:value-key="item.valueKey ? item.valueKey : 'value'"
:fetch-suggestions="item.querySearch"
:placeholder="item.placeholder"
:clearable="item.clearable === false ? false : true"
:style="item.width ? 'width:' + item.width + 'px' : 'width:200px'"
filterable
/>
<el-cascader
v-if="item.type === 'cascader'"
v-model="formInline[item.param]"
:options="item.selectOptions"
:props="item.cascaderProps"
:clearable="item.clearable === false ? false : true"
:show-all-levels="item.showAllLevels === false ? false : true"
:collapse-tags="item.collapseTags === true ? true : false"
:style="item.width ? 'width:' + item.width + 'px' : 'width:200px'"
@change="
item.onChange
? $emit('cascader-change', {
param: item.param,
value: formInline[item.param]
})
: null
"
></el-cascader>
<el-button
v-if="item.type === 'button'"
:type="item.color"
:size="item.size ? item.size : 'small'"
:plain="item.plain ? item.plain : false"
:round="item.round ? item.round : false"
@click="headBtnClick(item.name)"
>{{ item.btnName }}</el-button
>
<span v-if="item.type === 'separate'" class="separateStyle"></span>
<!-- 可用于显示其他按钮 -->
</el-form-item>
</template>
<el-form-item>
<slot></slot>
</el-form-item>
</el-form>
<span v-if="isFold" class="foldClass" @click='switchMode'>
{{ isExpand ? '收起' : '展开' }}
<i class="iconfont" :class="isExpand ? 'icon-upward' : 'icon-downward'"></i>
</span>
</div>
</template>
<script>
export default {
name: 'SearchBar',
props: {
formConfigs: {
type: Array,
default: () => {
return []
}
},
removeBlue: {
type: Boolean,
default: false
},
isFold: {// 多行模式(默认否)
type: Boolean,
default: false
}
},
data() {
const formInline = {}
const formConfig = this.formConfigs
let hasExtraOptions = false
for (const obj of formConfig) {
if (obj.type !== 'button') {
if (obj.defaultSelect === false || obj.defaultSelect === 0) {
formInline[obj.param] = obj.defaultSelect
} else {
formInline[obj.param] = obj.defaultSelect || '' // defaultSelect下拉框默认选中项
}
}
if (obj.extraOptions) {
hasExtraOptions = true
}
}
return {
formInline,
formConfig,
hasExtraOptions,
isExpand: false // 是否展开(默认否)
}
},
watch: {
formConfig: {
handler() {
for (const obj of this.formConfig) {
if (obj.defaultSelect) {
this.formInline[obj.param] = obj.defaultSelect
} else if (obj.defaultSelect === null) {
// 需要手动从外部清除选项缓存的情况确保在外部配置项中可直接设置null
this.formInline[obj.param] = ''
}
}
},
deep: true,
immediate: true
},
formInline: {
handler: function () {
this.$forceUpdate()
},
deep: true,
immediate: true
}
},
mounted() {
this.$nextTick(() => {
this.init()
})
},
methods: {
init() {
if (this.hasExtraOptions) {
// 如果有额外参数就处理,如果没有就算了
for (const obj of this.formConfig) {
if (obj.extraOptions) {
// 注: 对obj.extraOptions的选择是互斥的!
this.$watch(
`formInline.${obj.param}`,
function (newVal) {
let deleteCount = 0
if (obj.index + 1 < this.formConfig.length) {
// 如果obj不是最后一个配置
const nextConfig = this.formConfig[obj.index + 1]
if (nextConfig.parent && nextConfig.parent === obj.param)
deleteCount = 1
}
const currentConfig = Object.assign(
{},
obj.extraOptions[newVal]
)
this.formConfig.splice(
obj.index + 1,
deleteCount,
currentConfig
)
// 修改 formInline
this.$set(this.formInline, currentConfig.param, '')
},
{ immediate: true }
)
}
}
}
},
headBtnClick(btnName) {
this.formInline.btnName = btnName
this.$emit('headBtnClick', this.formInline)
},
resetForm() {
this.$refs.searchBarForm.resetFields()
const formInline = {}
const formConfig = this.formConfigs
for (const obj of formConfig) {
if (obj.type !== 'button') {
if (obj.defaultSelect === false || obj.defaultSelect === 0) {
formInline[obj.param] = obj.defaultSelect
} else {
formInline[obj.param] = obj.defaultSelect || '' // defaultSelect下拉框默认选中项
}
}
}
this.formInline = formInline
},
switchMode() {// 展开和收起切换
this.isExpand = !this.isExpand
const element = document.getElementById('searchBarBox')
if (this.isExpand) {
element.classList.remove('divHeight')
} else {
element.classList.add('divHeight')
}
}
}
}
</script>
<style>
.searchBarBox {
width: 100%;
position: relative;
margin-bottom: 8px;
}
.searchBarBox::after {
content: "";
display: block;
clear: both;
}
.divHeight {
height: 45px;
overflow: hidden;
}
.searchBar .blue-block {
display: inline-block;
float: left;
width: 4px;
height: 16px;
background-color: #0B58FF;
border-radius: 1px;
margin-right: 8px;
margin-top: 12px;
}
.searchBar .el-form-item {
margin-bottom: 10px;
}
.searchBar .el-date-editor .el-range__icon {
font-size: 16px;
color:#0B58FF;
}
.searchBar .el-input__prefix .el-icon-date {
font-size: 16px;
color:#0B58FF;
}
.searchBar .el-input__prefix .el-icon-time {
font-size: 16px;
color:#0B58FF;
}
.searchBar .separateStyle {
display: inline-block;
width: 1px;
height: 24px;
background: #E8E8E8;
vertical-align: middle;
}
.searchBarBox .foldClass {
position: absolute;
top: 14px;
right: 0;
cursor: pointer;
font-size: 12px;
color:#0B58FF;
}
.searchBarBox .foldClass .iconfont {
font-size: 14px;
}
</style>