最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

ElementUI級聯(lián)選擇器實(shí)現(xiàn)同一父級下最多只能選中一個子級

 更新時間:2023年10月25日 11:59:33   作者:UNDEFINED:)  
本文主要介紹了ElementUI級聯(lián)選擇器實(shí)現(xiàn)同一父級下最多只能選中一個子級,同一父級下的子節(jié)點(diǎn)單選,又可以選擇多個不同父級下的節(jié)點(diǎn),具有一定參考價值,感興趣的可以了解一下

這個需求有點(diǎn)多選與單選結(jié)合的意思,同一父級下的子節(jié)點(diǎn)單選,又可以選擇多個不同父級下的節(jié)點(diǎn)。這里以兩級為例,實(shí)現(xiàn)一個在多選模式下,同一父級下最多只能選中一個子級的級聯(lián)選擇器。

1、隱藏父級節(jié)點(diǎn)處的CheckBox

多選模式下可以通過勾選父級一鍵選中所有的子級,而每個父級下可能有多個子級,也可能只有一個,起初我想的是根據(jù)本次選擇選中的個數(shù)分類討論,但討論起來比較繁瑣,所以最后決定直接把父級的checkbox隱藏掉,不讓用戶直接勾選父級,減少了很多不必要的麻煩。

.hide {
  .el-cascader-menu:first-of-type {
    .el-cascader-node {
      .el-checkbox {
        display: none;
      }
    }
  }
}

這里需要注意的一點(diǎn)是hide類名必須使用級聯(lián)選擇器中的popper-class來添加自定義浮層類名的。

 2、對選中的項(xiàng)進(jìn)行篩選限制,先找到本次新增的項(xiàng),和新增前的值進(jìn)行對比,看是否存在與本次新增的項(xiàng)同屬于一個父級的,如果存在則刪除之前已經(jīng)存在的那一項(xiàng),留下本次新增的。

這里的解決花費(fèi)了我很多時間,因?yàn)橐婚_始想著直接操作級聯(lián)選擇器綁定值,刪除掉不要的那一項(xiàng)就可以了,但問題出現(xiàn)了。綁定的值確實(shí)達(dá)到了我想要的效果(即刪除之前已經(jīng)存在的那一項(xiàng),留下本次新增的),但級聯(lián)面板中右側(cè)的部分(即子節(jié)點(diǎn)部分),會自動刷新跳轉(zhuǎn)到第一個父級下的子級面板,用戶體驗(yàn)差,嘗試解決,沒解決掉。。。

最后,選擇從另外一個角度來實(shí)現(xiàn),如果存在與本次新增的項(xiàng)同屬于一個父級的,則直接通過js觸發(fā)點(diǎn)擊事件,取消勾選之前已經(jīng)存在的那一項(xiàng)。

有了思路以后就可以一步一步來實(shí)現(xiàn)了。

首先找到本次新增的這一項(xiàng),由于組件庫文檔中級聯(lián)選擇器這一塊并沒有提供相關(guān)的辦法獲取到最新選擇的一項(xiàng),只能拿到已選擇的所有值,并且級聯(lián)選擇器新增的項(xiàng)并不是直接push到綁定值的末尾,而是按選項(xiàng)值在頁面上展示的順序添加的,所以只能手動去對比查找,需要定義一個preValue數(shù)組來存儲上一次的值。

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)后,再去對比在此之前是否添加過于新增項(xiàng)同一父級下的其他子級。

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è)面板下的各個li標(biāo)簽的id值其實(shí)就是右側(cè)面板id值加上:'-'+index,因此我們只需要拿到右側(cè)面板id值就能知道對應(yīng)選項(xiàng)的id值,再觸發(fā)li標(biāo)簽的孩子標(biāo)簽中的checkbox的點(diǎn)擊事件就可以了。

 右側(cè)面板id通過級聯(lián)選擇器的引用可以拿到,另外需要求得取消勾選選項(xiàng)的index,通過與級聯(lián)選擇器選項(xiàng)值對比得到。

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();
  })

到這里就基本完成了這個需求,其實(shí)不難,但因?yàn)橐婚_始自己的思路(直接刪值)實(shí)現(xiàn)起來出現(xiàn)了問題,想著去解決花費(fèi)了很多時間,也沒解決掉,最后和同事討論換一種思路很快就實(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;
    }

    /*定義滾動條軌道 內(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級聯(lián)選擇器實(shí)現(xiàn)同一父級下最多只能選中一個子級的文章就介紹到這了,更多相關(guān)ElementUI級聯(lián)選擇器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • vue中的事件修飾符介紹和示例

    vue中的事件修飾符介紹和示例

    在Vue中,修飾符處理了許多DOM事件的細(xì)節(jié),讓我們不再需要花大量的時間去處理這些煩惱的事情,而能有更多的精力專注于程序的邏輯處理,需要的朋友可以參考下
    2023-04-04
  • Vue3.0 響應(yīng)式系統(tǒng)源碼逐行分析講解

    Vue3.0 響應(yīng)式系統(tǒng)源碼逐行分析講解

    這篇文章主要介紹了Vue3.0 響應(yīng)式系統(tǒng)源碼逐行分析講解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-10-10
  • 封裝 axios+promise通用請求函數(shù)操作

    封裝 axios+promise通用請求函數(shù)操作

    這篇文章主要介紹了封裝 axios+promise通用請求函數(shù)操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-08-08
  • 使用vue-antd動態(tài)切換主題

    使用vue-antd動態(tài)切換主題

    這篇文章主要介紹了使用vue-antd動態(tài)切換主題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-10-10
  • Vue 父子組件實(shí)現(xiàn)數(shù)據(jù)雙向綁定效果的兩種方式(案例代碼)

    Vue 父子組件實(shí)現(xiàn)數(shù)據(jù)雙向綁定效果的兩種方式(案例代碼)

    本文給大家分享Vue 父子組件實(shí)現(xiàn)數(shù)據(jù)雙向綁定效果的兩種方式,方式一是通過監(jiān)聽事件實(shí)現(xiàn)方式二是通過 v-model 實(shí)現(xiàn),每種方式結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2022-11-11
  • Vue中加載天地圖的離線地圖基本步驟

    Vue中加載天地圖的離線地圖基本步驟

    這篇文章主要給大家介紹了關(guān)于Vue中加載天地圖的離線地圖的基本步驟,Vue天地圖離線地圖是指基于Vue框架開發(fā)的應(yīng)用程序,使用天地圖離線地圖服務(wù)提供商提供的地圖數(shù)據(jù),可以在沒有網(wǎng)絡(luò)的情況下使用地圖功能,需要的朋友可以參考下
    2023-10-10
  • Vue3配置bem樣式架構(gòu)的代碼詳解

    Vue3配置bem樣式架構(gòu)的代碼詳解

    BEM是一種前端命名方法論,主要是針對CSS,意思是塊(Block)、元素(Element)、修飾符(Modifier)的簡寫,這種命名方法讓CSS便于統(tǒng)一團(tuán)隊開發(fā)規(guī)范和方便維護(hù),本文給大家介紹了Vue3配置bem樣式架構(gòu),需要的朋友可以參考下
    2024-10-10
  • vue中使用element日歷組件的示例代碼

    vue中使用element日歷組件的示例代碼

    這篇文章主要介紹了vue中如何使用element的日歷組件,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-09-09
  • vue與ant-tree結(jié)合偽造懶加載并可以查詢

    vue與ant-tree結(jié)合偽造懶加載并可以查詢

    這篇文章主要為大家介紹了vue與ant-tree結(jié)合偽造懶加載并可以查詢實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-07-07
  • ssm+vue前后端分離框架整合實(shí)現(xiàn)(附源碼)

    ssm+vue前后端分離框架整合實(shí)現(xiàn)(附源碼)

    這篇文章主要介紹了ssm+vue前后端分離框架整合實(shí)現(xiàn)(附源碼),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07

最新評論

集安市| 汝南县| 上栗县| 永川市| 固原市| 西青区| 海晏县| 澎湖县| 阿拉善左旗| 景德镇市| 胶州市| 大庆市| 黎平县| 宜川县| 永福县| 南江县| 奉化市| 随州市| 海安县| 博野县| 苍溪县| 西华县| 涿州市| 陵水| 新巴尔虎右旗| 达日县| 安康市| 当涂县| 花莲市| 厦门市| 思南县| 兴隆县| 齐河县| 田林县| 临武县| 嘉荫县| 乐昌市| 武山县| 吐鲁番市| 惠州市| 娄烦县|