开发过程中总会遇到一些奇奇怪怪的设计,比如以下这个。
说明:使用element-ui框架,
它有以下组件:el-checkbox与el-select
目标:在el-select的option前面添加checkbox,达到下拉并能多选的目的
具体实现:
<el-select v-model="submitForm.role" collapse-tags clearable multiple @change="changeSelect" @visible-change="visibleSelect">
<el-checkbox v-model="checkAll" @change="handleCheckAllChange" style="padding:0.3vw 0.52vw;width:100%">全部</el-checkbox>
<el-option v-for="item in roleOptions" :label="item.name" :key="item.id" :value="item.id"></option>
</el-select>
data () {
charOptions: [
{ id: 1, name: '角色A'},
{ id: 2, name: '角色B'},
{ id: 3, name: '角色C'},
{ id: 4, name: '角色DEFGHIJKLMN'}
],
checkAll: true, // 全选
roleOptions: [], // 角色选项列表
submitForm: {
role: '全部'
}
}
方法:
/** 全选 */
handleCheckAllChange () {
this.submitForm.role = []
if (this.checkAll) {
this.roleOptions.map(item => {
this.submitForm.role.push(item.id)
})
const lis = document.getElementsByClassName('el-select-dropdown__item')
for (let i = 0; i < lis.length; i++) {
const element = lis[i]
// 必须使用nextTick 否则拿不到最新的修改后的dom选中状态,也就没法判断
this.$nextTick(() => {
element.firstChild.checked = true
})
}
} else {
this.submitForm.role = []
const lis = document.getElementsByClassName('el-select-dropdown__item')
for (let i = 0; i < lis.length; i++) {
const element = lis[i]
// 必须使用nextTick 否则拿不到最新的修改后的dom选中状态,也就没法判断
this.$nextTick(() => {
element.firstChild.checked = false
})
}
}
}
/** 下拉框展开 关闭事件 */
visibleSelect (e) {
// 获取所有的li
const lis = document.getElementsByClassName('el-select-dropdown__item')
// 打开所有的下拉框,添加input
if (e) {
for (let i = 0; i < lis.length; i++) {
const element = lis[i]
const input = document.createElement('input')
input.style.cssText = 'margin-right: 0.52vw'
input.type = 'checkbox'
// 根据是否有选中的类名来判断li是否被选中
if (element.classList.contains('selected')) {
// 对应复选框也设置被选中
input.checked = true
}
element.insertBefore(input, element.lastChild)
}
} else {
// 关闭下拉框 移除掉input -- 否则每次打开添加就是多个input
for (let i = 0; i< lis.length; i++) {
const element = lis[i]
element.removeChild(element.firstElementChild)
}
}
}
/** 下拉选项变换事件 */
changeSelect (val) {
if (val.length === this.roleOptions.length) {
this.checkAll = true
} else {
this.checkAll = false
}
const lis = document.getElementsByClassName('el-select-dropdown__item')
for (let i = 0; i < lis.length; i++) {
const element = lis[i]
// 必须使用nextTick 否则拿不到最新的修改后的dom选中状态 也就没法判断
this.$nextTick(() => {
// 判断当前的li是否被选中,选中的则设置复选框被选中
if (element.classList.contains('selected')) {
element.firstChild.checked = true
} else {
element.firstChild.checked = false
}
})
}
}