Files
foton-laws-system-front/src/components/CustomFormComponents/SearchSelect.vue
T
2021-06-25 17:57:33 +08:00

222 lines
5.4 KiB
Vue

<!-- 可搜索多选框 -->
<template>
<!-- <div>-->
<el-col :span="span">
<el-form-item
:label="config.attrName"
:prop="config.attrField"
label-width="150px"
class="add-form-item"
>
<el-dropdown
trigger="click"
class="search-select"
size="medium"
>
<el-input
type="text"
readonly
:placeholder="placeholder"
v-model="selectedLabel"
suffix-icon="el-icon-arrow-down"
@click.native="visibleToggle"
:class="{ 'search-visible': visible }"
></el-input>
<el-input
type="hidden"
v-model="selectedValue"
class="el-input-hidden"
></el-input>
<el-dropdown-menu
slot="dropdown"
class="search-select-el-dropdown-menu"
>
<div class="search-input">
<el-input
v-model="searchKey"
placeholder="要搜索的内容"
class="input-color"
clearable />
</div>
<div class="search-options">
<el-dropdown-item
v-for="option in filterOptions"
:name="option.value || option.id"
:title="option.label || option.name"
:key="option.value"
:disabled="disabled"
@click.native="ondropClick(option)"
>
{{ option.label || option.name }}
</el-dropdown-item>
</div>
</el-dropdown-menu>
</el-dropdown>
</el-form-item>
</el-col>
<!-- </div>-->
</template>
<script>
export default {
name: 'searchSelect',
data () {
return {
// 显示的label
selectedLabel: '',
// 选择的value
selectedValue: '',
visible: false,
// 原始选项数据
filterOptions: [],
// 选项匹配词
searchKey: ''
}
},
methods: {
/**
* @description: 切换显示状态
* @author: chenxiaoxi
* @date: 2018/12/25 10:38:54
*/
visibleToggle () {
if (!this.disabled) {
this.visible = !this.visible
}
},
/**
* @description: 选项过滤
* @author: chenxiaoxi
* @date: 2018/12/25 10:44:38
*/
handleFilterOptions () {
// 匹配项来源
if (this.searchKey === '') {
this.filterOptions = this.options
} else {
let result = []
// 用原始数据进行匹配
if (this.options !== '' && this.options !== null) {
this.options.map((opt) => {
if (opt.label !== null && opt.label.indexOf(this.searchKey) !== -1) {
result.push(opt)
}
})
}
this.filterOptions = result
}
},
/**
* @description: 对v-model绑定的值进行匹配
* @author: chenxiaoxi
* @date: 2018/12/25 15:23:46
*/
handleValue () {
if (this.value && this.value !== '') {
if (this.options !== '' && this.options !== null) {
this.options.map((opt) => {
if (opt.value === this.value || opt.id === this.value) {
this.selectedLabel = opt.label || opt.name
this.selectedValue = opt.value || opt.id
}
})
}
} else {
this.selectedLabel = ''
this.selectedValue = ''
}
},
// 点击下拉选项事件
ondropClick (option) {
this.visible = false // 隐藏下拉菜单
this.selectedValue = option.value
this.selectedLabel = option.label
this.$emit('input', option.value) // 赋值给父组件
this.$emit('on-change', option.value) // 赋值给父组件
}
},
components: {},
props: {
value: {
type: [String, Number]
},
options: {
required: true
},
placeholder: {
type: String,
default: '请选择'
},
disabled: {
type: Boolean,
default: false
},
clearable: {
type: Boolean,
default: true
},
// 栅格比例
span: {
type: Number,
default: 24
}
},
computed: {},
watch: {
selectedLabel: {
deep: true,
handler (val, oldVal) {
// 当外层输入框内容清空时, 将selectedValue置为空
if (val === '') {
this.selectedValue = ''
}
}
},
// 监听显示状态
visible (val) {
if (val) {
// 当显示的时候,给选项框外绑定事件
window.addEventListener('click', function (e) {
// 点击的是搜索框外
if ($(e.target).parents('.search-select').length === 0) {
this.visible = false
}
}.bind(this))
} else {
this.searchKey = ''
}
},
// 监听关键词的变化,代替keyup事件
searchKey (val) {
this.handleFilterOptions()
},
// 监听最终选取的值
selectedValue (val) {
if (val === '' || this.selectedLabel === '') {
this.$emit('input', val)
this.$emit('on-change', val)
}
},
// 监听v-model变化
value (val) {
this.handleValue()
},
// 监听options变化
options (val, oldVal) {
this.filterOptions = JSON.parse(JSON.stringify(this.options))
this.handleValue()
}
},
mounted () {
this.filterOptions = JSON.parse(JSON.stringify(this.options))
this.handleValue()
}
}
</script>
<style lang="less">
@import '~@/assets/styles/mixins';
@import '~@/assets/styles/style';
</style>