222 lines
5.4 KiB
Vue
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>
|