本组件依赖于iview的select,可以在全局安装了Iview的项目或者局部引入了Select的页面中自由使用。
目录
效果展示
从左到右分别是:未选状态、选中一个状态、全选状态
功能描述
- 下拉框分为三块:已选列表;全选/取消全选按钮;未选列表;
- 当选中未选列表的某项,该项自动从未选列表pop去已选列表;
- 当选中已选列表的某项,该项自动从已选列表pop去未选列表;
- 支持关键字搜索,输入框显示已选数目;
结构代码
<template>
<div class="c-search">
<Select
v-model="s_arr"
:disabled="isdisabled"
:placeholder="placeholder"
:max-tag-count="0"
multiple
filterable
label-in-value
@on-select="selectOption"
@on-open-change="openChange"
>
<Option
v-for="i in selectedList"
:value="i.value"
:key="i.value"
:title="i.label"
>{{ i.label }}</Option
>
<Option
value="all"
key="all"
v-if="trans_unselList.length > 0"
style="padding: 0px"
>
<p
@click="
selectAllFun(
s_arr.length !== unselList.length + selectedList.length
)
"
>
{{
s_arr.length !== unselList.length + selectedList.length
? "全选"
: "取消全选"
}}
</p>
</Option>
<Option
v-for="item in unselList"
:value="item.value"
:key="item.value"
:title="item.label"
>{{ item.label }}</Option
>
</Select>
</div>
</template>
data () {
return {
unselList: [], // 未选数组
selectedList: [], // 已选数组
s_arr: [], // v-model绑定选项数组
add_tag: true, // 新增选项标记
allList: [], // 全选v-model绑定选项数组
init_list: [] // 全选已选数组
}
}
- 根据s_arr长度是否为总长度确定是全选还是取消全选
逻辑代码
// 全选/取消全选
selectAllFun (isAll) {
const self = this
setTimeout(() => {
self.s_arr = []
if (isAll) { // 全选
self.selectedList = []
self.init_list.forEach(item => {
// 采用这种方式的拷贝,不会只是拷贝了对象的别名(只拷贝别名会导致不期望的被改动)
self.selectedList.push(item)
})
self.unselList = []
self.allList.forEach(item => {
self.s_arr.push(item)
})
} else { // 取消全选
self.selectedList = []
self.unselList = []
self.init_list.forEach(item => {
self.unselList.push(item)
})
self.s_arr = []
}
}, 0)
},
add_or_del (o) {
const self = this
try {
self.selectedList.forEach(function (item) {
if (item.value === o.value) {
self.add_tag = false
throw new Error('')
}
})
} catch (e) {
return ''
}
self.add_tag = true
return ''
},
selectOption (o) {
const self = this
if (o.value !== 'all') {
setTimeout(() => {
self.add_or_del(o)
if (self.add_tag) {
try {
self.unselList.forEach(function (item, index) {
if (item.value === o.value) {
self.unselList.splice(index, 1)
throw new Error('')
}
})
} catch (e) {
// console.log(e)
}
self.selectedList.push(o)
} else {
try {
self.selectedList.forEach(function (item, index) {
if (item.value === o.value) {
self.selectedList.splice(index, 1)
throw new Error('')
}
})
} catch (e) {
// console.log(e)
}
self.unselList.push(o)
}
}, 100)
}
},
openChange (isopen) {
if (!isopen) {
var res = this.backList_handle(this.selectedList)
this.$emit('func', res)
}
},
// 返回选项列表处理
backList_handle (list) {
if (isArray(list)) {
var res = []
list.forEach(item => {
res.push(item.value)
})
return res
}
},
allList_setValue () {
const self = this
self.unselList.forEach(temp => {
self.allList.push(temp.value)
self.init_list.push(temp)
})
},
// 拿到的选项处理
selList_handle (trans, unsel) {
const self = this
setTimeout(() => {
if (trans && trans.length > 0) {
const sel = []
const un_sel = []
unsel.forEach(function (item, index) {
if (item.value && trans.indexOf(item.value) !== -1) {
sel.push(item)
} else if (item.value && trans.indexOf(item.value) === -1) {
un_sel.push(item)
}
})
self.selectedList = sel
// s_arr保存的仅是value
self.selectedList.forEach(item => {
self.s_arr.push(item.value)
})
self.unselList = un_sel
const res = this.backList_handle(self.selectedList)
this.$emit('func', res)
} else if (trans && trans.length === 0) {
self.selectedList = []
self.unselList = []
self.init_list.forEach(item => {
self.unselList.push(item)
})
self.s_arr = []
const res = this.backList_handle(self.selectedList)
this.$emit('func', res)
}
}, 0)
}
-
selectAllFun:处理全选和取消全选事件,参数isAll判断当前处理的是全选还是取消全选事件
-
add_or_del:判断当前是添加选项还是删除选项并对应设置标签add_tag
-
selectOption:选择事件,根据add_tag进行对应的删除和添加的处理
-
openChange:下拉框展开收起事件,在收起的时候将拿到的选项组合传给父组件
-
allList_setValue:在首次拿到未选数组时,保存到allList和init_list中(定义见data)
-
selList_handle:处理初始化时从父组件那拿到的已选项
组件应用
<Csearch
placeholder="水果"
:trans_unselList="FruitGroup_List"
:trans_selList="res_FruitGroup_List"
@func="getFruitGroup_List"
/>
import Csearch from '../c-search/index.vue'
components: {
Csearch
},
- import引入 ——> 组件注册 ——> 使用
- 父 ——> 子传参:
-
placeholder:父组件传递的输入提示文字
-
trans_unselList:父组件传递的未选列表
-
isdisabled:父组件传递的该选择器禁用状态
-
trans_selList:父组件传递的已选列表
-
事件钩子
// 拿到选择的水果
getFruitGroup_List (list) {
this.sel_FruitGroup_List = list
...do something
}
- getFruitGroup_List:拿到选择的水果
github