基于iview封装的定制化select下拉菜单
前天PM那边给了个UE图,上面有这么个需求:
-
iview没有内置的这种类型的组件,因此,自己着手封了一个(一言不合就封它!)
-
而且select在该需求的基础上增加了一些功能:
1. 是否需要默认状态下自动显示全选 2. select宽度自定义 3. 支持父组件v-if下的显示隐藏该select子组件
完成效果如下:
代码如下:
<template>
<!-- 定制下拉菜单组件 & 开放搜索、多选功能 -->
<div class="search-select-tepl">
<span v-if="dataList.showTitle ? true : false">{{ dataList.title ? dataList.title : '请选择' }}:</span>
<Select @on-open-change="handleProduct()"
:placeholder="dataList.placeholder ? dataList.placeholder : '全部'"
clearable
size="small"
:style="'width:'+ width + 'px;'">
<Input v-if="dataList.showSearch" style="width: 190px;"
size="small"
icon="ios-search"
:placeholder="dataList.searchPlaceHolder ? dataList.searchPlaceHolder : '请输入内容回车搜索'"
v-model="dataList.search"
@input="searchProduct">
</Input>
<Checkbox
class="check-all"
:indeterminate="dataList.indeterminate"
:value="dataList.checkAll"
@click.prevent.native="handleCheckAll()">{{ dataList.checkAllName ? dataList.checkAllName : '全选' }}</Checkbox>
<CheckboxGroup @on-change="handleCheck()" v-model="dataList.checkList">
<Checkbox class="check-option" v-for="(item, index) in dataList.datalist" :key="index" :label="item.value">{{ item.label }}</Checkbox>
</CheckboxGroup>
</Select>
</div>
</template>
<script>
export default {
name: "searchSelectTepl",
props: ['list'],
data() {
return {
dataList: Object.assign({}, this.list)
}
},
watch: {
'dataList': {
handler(val, oldValue) {
for(let item in val) {
if (this.dataList.checkList.length === this.dataList.datalist.length) {
this.dataList.placeholder = "全部";
} else if (this.dataList.checkList.length == 0) {
this.dataList.placeholder = "请选择";
} else if (this.dataList.checkList.length > 0) {
this.dataList.placeholder = "已选" + this.dataList.checkList.length + "项";
}
}
},
deep:true
},
},
computed: {
// width
width() {
if (this.dataList.width) {
return this.dataList.width;
} else {
return 120;
}
},
},
created() {
this.dataList.datalistInfo = this.dataList.datalist;
// 匹配父组件 v-if时 默认全部
if ((!this.dataList.checkList.length) && this.dataList.showCheckAll) {
this.handleCheckSelect();
}
},
methods: {
// 初始化下拉菜单数据
handleCheckSelect() {
this.dataList.checkList = [];
this.dataList.datalist.map(item => {
this.dataList.checkList.push(item.value);
})
},
// select 展开 & 收起事件
handleProduct() {
if (this.dataList.showCheckAll) {
if (!this.dataList.checkList.length) {
this.handleCheckSelect();
this.dataList.indeterminate = false;
this.dataList.checkAll = true;
}
}
// 菜单关闭执行回调
this.$emit('sendCheckList', this.dataList);
},
// 产品线下拉菜单 & 搜索
searchProduct() {
this.dataList.datalist = this.dataList.datalistInfo;
if (this.dataList.search && this.dataList.search!= '') {
let tempProductLineList = [];
this.dataList.datalist.forEach(item => {
if (item.label.match(this.dataList.search)) {
tempProductLineList.push(item);
}
})
this.dataList.datalist = tempProductLineList;
}
},
// 全选check
handleCheckAll() {
if (this.dataList.indeterminate) {
this.dataList.checkAll = false;
} else {
this.dataList.checkAll = !this.dataList.checkAll;
}
this.dataList.indeterminate = false;
if (this.dataList.checkAll) {
this.handleCheckSelect();
} else {
this.dataList.checkList = [];
}
this.$emit('sendCheckList', this.dataList);
},
// check某一项
handleCheck() {
let data = this.dataList.checkList;
if (data.length === this.dataList.datalist.length) {
this.dataList.indeterminate = false;
this.dataList.checkAll = true;
} else if (data.length > 0) {
this.dataList.indeterminate = true;
this.dataList.checkAll = false;
} else {
this.dataList.indeterminate = false;
this.dataList.checkAll = false;
}
this.$emit('sendCheckList', this.dataList);
},
// 同步数据
setDataList(val) {
this.dataList = val;
}
}
}
</script>
<style lang="less">
.search-select-tepl {
position: relative;
/* 定制下拉菜单样式 */
.ivu-select-dropdown {
width: 210px;
}
.check-all {
margin: 5px 5px 0 5px;
}
/* 多选checkGroup */
.ivu-checkbox-group {
max-height: 140px;
overflow: auto;
padding: 5px 5px;
.check-option {
float: left;
width: 100%;
line-height: 20px;
}
}
.ivu-select-dropdown {
padding: 5px;
}
}
</style>
1. dataList模板说明、字段含义:
sendCheckList()
函数表示checked之后,checkList数据(选择的数据),需要父组件中函数接收这个数据。例如在父组件中:
- 下面dataList对象中各个属性表示该组件各项配置。例如:
showCheckAll:
,表示默认状态下全选。
// 使用模板 属性
// sendCheckList() this.$emit('sendCheckList', this.dataList); // 同步父组件checkList数据
dataList: {
key: 'runTime', // 标识
title: '执行周期', // 标题 默认为'请选择'
showTitle: true, // 是否显示标题 默认为true
placeholder: '全部', // 默认状态
search: '', // 搜索
width: 140, // select宽 默认为120px
showSearch: true, // 是否显示搜索
searchPlaceHolder: '请输入执行周期进行搜索', // search placeholder 默认为'请输入内容回车搜索'
indeterminate: false, // 是否处于半选状态
checkAllName: '全选', 默认为'全选'
checkAll: true, // 是否默认全选
showCheckAll: '', // 是否需要自动匹配全选
checkList: [], // checked list
datalistInfo: [], // 临时存储
datalist: [ // 下拉菜单项
{
value: '1',
label: '苹果'
}
]
}
2. 父组件传递子组件dataList格式,就是上方属性datalist
格式