ElementUI級(jí)聯(lián)選擇器實(shí)現(xiàn)同一父級(jí)下最多只能選中一個(gè)子級(jí)
這個(gè)需求有點(diǎn)多選與單選結(jié)合的意思,同一父級(jí)下的子節(jié)點(diǎn)單選,又可以選擇多個(gè)不同父級(jí)下的節(jié)點(diǎn)。這里以兩級(jí)為例,實(shí)現(xiàn)一個(gè)在多選模式下,同一父級(jí)下最多只能選中一個(gè)子級(jí)的級(jí)聯(lián)選擇器。
1、隱藏父級(jí)節(jié)點(diǎn)處的CheckBox
多選模式下可以通過勾選父級(jí)一鍵選中所有的子級(jí),而每個(gè)父級(jí)下可能有多個(gè)子級(jí),也可能只有一個(gè),起初我想的是根據(jù)本次選擇選中的個(gè)數(shù)分類討論,但討論起來比較繁瑣,所以最后決定直接把父級(jí)的checkbox隱藏掉,不讓用戶直接勾選父級(jí),減少了很多不必要的麻煩。
.hide { .el-cascader-menu:first-of-type { .el-cascader-node { .el-checkbox { display: none; } } } }
這里需要注意的一點(diǎn)是hide類名必須使用級(jí)聯(lián)選擇器中的popper-class來添加自定義浮層類名的。
2、對(duì)選中的項(xiàng)進(jìn)行篩選限制,先找到本次新增的項(xiàng),和新增前的值進(jìn)行對(duì)比,看是否存在與本次新增的項(xiàng)同屬于一個(gè)父級(jí)的,如果存在則刪除之前已經(jīng)存在的那一項(xiàng),留下本次新增的。
這里的解決花費(fèi)了我很多時(shí)間,因?yàn)橐婚_始想著直接操作級(jí)聯(lián)選擇器綁定值,刪除掉不要的那一項(xiàng)就可以了,但問題出現(xiàn)了。綁定的值確實(shí)達(dá)到了我想要的效果(即刪除之前已經(jīng)存在的那一項(xiàng),留下本次新增的),但級(jí)聯(lián)面板中右側(cè)的部分(即子節(jié)點(diǎn)部分),會(huì)自動(dòng)刷新跳轉(zhuǎn)到第一個(gè)父級(jí)下的子級(jí)面板,用戶體驗(yàn)差,嘗試解決,沒解決掉。。。
最后,選擇從另外一個(gè)角度來實(shí)現(xiàn),如果存在與本次新增的項(xiàng)同屬于一個(gè)父級(jí)的,則直接通過js觸發(fā)點(diǎn)擊事件,取消勾選之前已經(jīng)存在的那一項(xiàng)。
有了思路以后就可以一步一步來實(shí)現(xiàn)了。
首先找到本次新增的這一項(xiàng),由于組件庫文檔中級(jí)聯(lián)選擇器這一塊并沒有提供相關(guān)的辦法獲取到最新選擇的一項(xiàng),只能拿到已選擇的所有值,并且級(jí)聯(lián)選擇器新增的項(xiàng)并不是直接push到綁定值的末尾,而是按選項(xiàng)值在頁面上展示的順序添加的,所以只能手動(dòng)去對(duì)比查找,需要定義一個(gè)preValue數(shù)組來存儲(chǔ)上一次的值。
let newIndex; let i = 0, j = 0; while (i < val.length && j < this.preValue.length) { if (val[i][0] === this.preValue[j][0] && val[i][1] === this.preValue[j][1]) { i++; j++; } else { //添加在中間的情況 newIndex = i; break; } } //添加在末尾的情況 if (j === this.preValue.length) { newIndex = i; }
找到新增項(xiàng)后,再去對(duì)比在此之前是否添加過于新增項(xiàng)同一父級(jí)下的其他子級(jí)。
let delIndex = val.findIndex((item, index) => index !== newIndex && item[0] === val[newIndex][0]);
如果存在的話,接下來就需要去觸發(fā)相應(yīng)的點(diǎn)擊事件取消這一項(xiàng)的勾選。
我們先來觀察一下html結(jié)構(gòu),右側(cè)面板下的各個(gè)li標(biāo)簽的id值其實(shí)就是右側(cè)面板id值加上:'-'+index,因此我們只需要拿到右側(cè)面板id值就能知道對(duì)應(yīng)選項(xiàng)的id值,再觸發(fā)li標(biāo)簽的孩子標(biāo)簽中的checkbox的點(diǎn)擊事件就可以了。
右側(cè)面板id通過級(jí)聯(lián)選擇器的引用可以拿到,另外需要求得取消勾選選項(xiàng)的index,通過與級(jí)聯(lián)選擇器選項(xiàng)值對(duì)比得到。
let cancelIndex; for (let i = 0; i < this.options.length; i++) { if (this.options[i].value === val[delIndex][0]) { for (let j = 0; j < this.options[i].children.length; j++) { if (this.options[i].children[j].value === val[delIndex][1]) { cancelIndex = j; break; } } break; } }
獲取id值。
this.$nextTick(() => { let panelId = this.$refs.cascade.panel.$refs.menu[1].$el.id; //其中menu[1]表示右側(cè)的面板 menu[0]即為左側(cè)的面板 let liId = document.getElementById(panelId + '-' + cancelIndex); liId.children[0].click(); })
到這里就基本完成了這個(gè)需求,其實(shí)不難,但因?yàn)橐婚_始自己的思路(直接刪值)實(shí)現(xiàn)起來出現(xiàn)了問題,想著去解決花費(fèi)了很多時(shí)間,也沒解決掉,最后和同事討論換一種思路很快就實(shí)現(xiàn)了,所以思路變通是非常重要的~
3、完整代碼
<template> <div class='test'> <el-cascader class='cascader' :options='options' :props='props' clearable :popper-class="'hide'" @change='handleChange' ref='cascade' ></el-cascader> </div> </template> <script> export default { name: 'Cascader', data() { return { props: { multiple: true, expandTrigger: 'click' }, options: [{ value: 1, label: '杭州', children: [{ value: 3, label: '西湖' }, { value: 4, label: '錢塘' }, { value: 7, label: '上城' }] }, { value: 2, label: '成都', children: [{ value: 5, label: '青羊' }, { value: 6, label: '武侯' }] }], preValue:[] } }, methods:{ handleChange(val){ if (this.preValue.length > 0 && val.length > this.preValue.length) { let newIndex; let i = 0, j = 0; while (i < val.length && j < this.preValue.length) { if (val[i][0] === this.preValue[j][0] && val[i][1] === this.preValue[j][1]) { i++; j++; } else { //添加在中間的情況 newIndex = i; break; } } //添加在末尾的情況 if (j === this.preValue.length) { newIndex = i; } let delIndex = val.findIndex((item, index) => index !== newIndex && item[0] === val[newIndex][0]); if (delIndex >= 0) { // 取消選擇的節(jié)點(diǎn) let cancelIndex; for (let i = 0; i < this.options.length; i++) { if (this.options[i].value === val[delIndex][0]) { for (let j = 0; j < this.options[i].children.length; j++) { if (this.options[i].children[j].value === val[delIndex][1]) { cancelIndex = j; break; } } break; } } this.$nextTick(() => { let panelId = this.$refs.cascade.panel.$refs.menu[1].$el.id; //其中menu[1]表示右側(cè)的面板 menu[0]即為左側(cè)的面板 let liId = document.getElementById(panelId + '-' + cancelIndex); liId.children[0].click(); }) val[delIndex] = ''; val = val.filter(item => item !== ''); } } this.preValue = val; } } }; </script> <style lang='less'> .test { text-align: center; margin-top: 200px; .title { display: block; margin-bottom: 20px; } .cascader { .el-input__inner { width: 362px; } .el-cascader__tags { display: flex; flex-wrap: nowrap; overflow-y: overlay; margin-left: 2px; } .el-cascader__tags::-webkit-scrollbar { width: 0; height: 3px; } /*定義滾動(dòng)條軌道 內(nèi)陰影+圓角*/ .el-cascader__tags::-webkit-scrollbar-track { background-color: rgba(186, 203, 227, 0.3); } /*定義滑塊 內(nèi)陰影+圓角*/ .el-cascader__tags::-webkit-scrollbar-thumb { background-color: #B3C2D7; } } } .hide { .el-cascader-menu:first-of-type { .el-cascader-node { .el-checkbox { display: none; } } } } </style>
到此這篇關(guān)于ElementUI級(jí)聯(lián)選擇器實(shí)現(xiàn)同一父級(jí)下最多只能選中一個(gè)子級(jí)的文章就介紹到這了,更多相關(guān)ElementUI級(jí)聯(lián)選擇器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Vue2.0實(shí)現(xiàn)自適應(yīng)分辨率
這篇文章主要為大家詳細(xì)介紹了Vue2.0實(shí)現(xiàn)自適應(yīng)分辨率,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-11-11vue實(shí)現(xiàn)實(shí)時(shí)上傳文件進(jìn)度條
這篇文章主要為大家詳細(xì)介紹了vue實(shí)現(xiàn)實(shí)時(shí)上傳文件進(jìn)度條,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03對(duì)vue中v-on綁定自定事件的實(shí)例講解
今天小編就為大家分享一篇對(duì)vue中v-on綁定自定事件的實(shí)例講解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-09-09vue實(shí)現(xiàn)組件跟隨鼠標(biāo)位置彈出效果(示例代碼)
這篇文章主要介紹了vue中實(shí)現(xiàn)組件跟隨鼠標(biāo)位置彈出效果,本文通過圖文示例代碼相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-02-02Vue使用v-viewer實(shí)現(xiàn)圖片預(yù)覽
這篇文章主要為大家詳細(xì)介紹了Vue使用v-viewer實(shí)現(xiàn)圖片預(yù)覽,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-10-10解決vue2中使用axios http請(qǐng)求出現(xiàn)的問題
下面小編就為大家分享一篇解決vue2中使用axios http請(qǐng)求出現(xiàn)的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-03-03