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

vue多級(jí)復(fù)雜列表展開/折疊及全選/分組全選實(shí)現(xiàn)

 更新時(shí)間:2018年11月05日 10:21:33   作者:_TSY_  
這篇文章主要介紹了vue多級(jí)復(fù)雜列表展開/折疊及全選/分組全選實(shí)現(xiàn),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧

首先,來看下效果圖

在線體驗(yàn)地址:https://hxkj.vip/demo/multipleList/。溫馨提示,打開之后按F12,使用手機(jī)模式食用,口味更佳!

可以看出,這個(gè)列表有三種展現(xiàn)形式:

1.第一層級(jí)中包含直屬子項(xiàng)和第二層級(jí),其中第二層級(jí)里包含子項(xiàng)
2.第一層級(jí)中只包含第二層級(jí),第二層級(jí)里包含子項(xiàng)
3.第一層級(jí)中只包含直屬子項(xiàng)

接下來,再分析列表所實(shí)現(xiàn)的功能:

1.點(diǎn)擊父級(jí)可以展開與折疊該直屬子級(jí);
2.點(diǎn)擊父級(jí)級(jí)的勾選圖標(biāo)可以全選或取消該層級(jí)下列的所有子項(xiàng);
3.點(diǎn)擊子項(xiàng)達(dá)到該父級(jí)的全選狀態(tài)時(shí)時(shí),父級(jí)的勾選圖標(biāo)自動(dòng)勾選;反之,沒達(dá)到全選時(shí),父級(jí)的勾選圖標(biāo)自動(dòng)取消勾選;
4.所有相同層級(jí)之間勾選狀態(tài)的改變互不影響;

分析完了,緊接著就到了擼碼時(shí)刻了。

1.首先構(gòu)建我們所需要的數(shù)據(jù)結(jié)構(gòu)。

data() {
  return {
    headColor: ['#1c71fb', '#f7aa47', '#00c182', '#ff6769', '#917ee6', '#2cb2eb'],//待選顏色
    jobList: [{
      "id": "2511",
      "name": "嫩江第一中學(xué)",
      "member": [{
        "pid": "12058",
        "userName": "冷風(fēng)",
        "job": "安全主任",
        "name": "冷風(fēng)"
      }, {
        "pid": "12005",
        "userName": "周大龍",
        "job": "安全主任",
        "name": "大龍"
      }],
      "son": [{
        "id": "2513",
        "name": "校領(lǐng)導(dǎo)",
        "member": [{
          "pid": "12056",
          "userName": "凌凌",
          "job": "安全主任",
          "name": "凌凌"
        }, {
          "pid": "12039",
          "userName": "唐老師",
          "job": "安全主任",
          "name": "老師"
        }]
      }]
    }, {
      "id": "2510",
      "name": "黑龍江黑河市嫩江縣教育局",
      "son": [{
        "id": "2525",
        "name": "辦公室 ",
        "member": [{
          "pid": "12006",
          "userName": "張喵喵",
          "job": "安全主任",
          "name": "喵喵"
        }, {
          "pid": "12024",
          "userName": "張徳龍",
          "job": "老師",
          "name": "徳龍"
        }]
      }, {
        "id": "2524",
        "name": "局長(zhǎng)部",
        "member": [{
          "pid": "12015",
          "userName": "小組長(zhǎng)",
          "job": "安全主任",
          "name": "組長(zhǎng)"
        }, {
          "pid": "12025",
          "userName": "TSY",
          "job": "11",
          "name": "SY"
        }]
      }]
    }, {
      "id": "2545",
      "name": "城市之星2總部",
      "member": [{
        "pid": "12076",
        "userName": "文明",
        "job": "前端開發(fā)工程師",
        "name": "文明"
      }, {
        "pid": "12077",
        "userName": "不文明",
        "job": "高級(jí)架構(gòu)師",
        "name": "文明"
      }]
    }], //從后臺(tái)獲取的人員列表信息
    selectPeople: [],//存儲(chǔ)被選擇的人員
    isOpenItem: [],//控制每級(jí)面板的打開與折疊
    isSelectAll: [],//控制每級(jí)面板的選中狀態(tài)
  }
}

2.初始化數(shù)據(jù)

初始化數(shù)據(jù)的主要目的。

1.根據(jù)數(shù)據(jù)來給頭像設(shè)置隨機(jī)顏色
2.根據(jù)數(shù)據(jù)初始化一層級(jí)全選按鈕狀態(tài)
3.根據(jù)數(shù)據(jù)初始化折疊面板折疊狀態(tài)
4.根據(jù)數(shù)據(jù)設(shè)置第二層級(jí)的選中狀態(tài)

initData() {//數(shù)據(jù)初始化
  //設(shè)置頭像背景顏色
  let len = this.jobList.length;
  for (let i = 0; i < len; i++) {
    this.setHeadColor(this.jobList[i].member, this.headColor);
    //根據(jù)數(shù)據(jù)初始化全選按鈕狀態(tài)
    this.isSelectAll.push([]);
    this.$set(this.isSelectAll[i], 'group', false);
    this.$set(this.isSelectAll[i], 'child', []);
    //根據(jù)數(shù)據(jù)初始化折疊面板折疊狀態(tài)
    this.isOpenItem.push([]);
    this.$set(this.isOpenItem[i], 'group', false);
    this.$set(this.isOpenItem[i], 'child', []);
    //設(shè)置第二層級(jí)的狀態(tài)
    for (let j in this.jobList[i].son) {
      this.isSelectAll[i].child.push(false)
      this.isOpenItem[i].child.push(false)
      this.setHeadColor(this.jobList[i].son[j].member, this.headColor);
    }
  }
}

3.為父級(jí)綁定事件

全選框HTML。使用@click="checkAll(index)"綁定全選事件,用于改變?nèi)x框的全選狀態(tài)

<div class="checkGroup" @click="checkAll(index)" @click.stop>
    <i class="iconfont"
       :class="{'icon-gouxuan':isSelectAll[index] && isSelectAll[index].group,'icon-checkboxround0':isSelectAll[index] && !isSelectAll[index].group}"></i>
</div>

全選框JS。通過改變this.isSelectAll[index]中的group屬性,來動(dòng)態(tài)修改父級(jí)的選中狀態(tài)。因?yàn)樽蛹?jí)選項(xiàng)的數(shù)據(jù)this.selectPeople是由v-model綁定的,所有只需要對(duì)其進(jìn)行增加和刪除的操作,就可以改變子級(jí)每一項(xiàng)的選中狀態(tài)

checkAll(index) {//父級(jí)的全選操作
  this.$set(this.isSelectAll[index], 'group', !this.isSelectAll[index].group);//改變當(dāng)前按鈕的選中狀態(tài)
  if (!this.jobList[index].member && !this.jobList[index].son) {
    return
  }
  if (!this.isSelectAll[index].group) {// 從全選 =》 全不選
    for (let key in this.isSelectAll[index].child) { // 移除所有第二層級(jí)子項(xiàng)的選中狀態(tài)
      this.$set(this.isSelectAll[index].child, key, false);
    }
    for (let i = 0, len = this.selectPeople.length; i < len; i++) {
      if (!this.selectPeople[i]) { //刪除干凈了
        return
      }
      for (let k in this.jobList[index].son) {//循環(huán)刪除有部門的人員(對(duì)應(yīng)列表第三層級(jí))
        for (let j in this.jobList[index].son[k].member) {
          if (this.selectPeople[i] && this.selectPeople[i].pid == this.jobList[index].son[k].member[j].pid) {
            this.selectPeople.splice(i, 1);
            i--;
            break;
          }
        }
      }
      for (let j in this.jobList[index].member) {//循環(huán)刪除沒有部門的人員(對(duì)應(yīng)列表第二層級(jí))
        if (this.selectPeople[i] && this.selectPeople[i].pid == this.jobList[index].member[j].pid) {
          this.selectPeople.splice(i, 1);
          i--;
          break;
        }
      }
    }
  } else {// 從全不選 =》 全選
    for (let key in this.isSelectAll[index].child) { // 給所有第二層級(jí)子項(xiàng)添加選中狀態(tài)
      this.$set(this.isSelectAll[index].child, key, true);
    }
    for (let i in this.jobList[index].member) {//循環(huán)添加沒有部門的人員(對(duì)應(yīng)列表第二層級(jí))
      if (this.selectPeople.includes(this.jobList[index].member[i])) { //如果已經(jīng)存在,就不用再進(jìn)行添加
        continue;
      }
      this.selectPeople.push(this.jobList[index].member[i]);
    }
    for (let i in this.jobList[index].son) {//循環(huán)添加有部門的人員(對(duì)應(yīng)列表第三層級(jí))
      for (let j in this.jobList[index].son[i].member) {
        if (this.selectPeople.includes(this.jobList[index].son[i].member[j])) { //如果已經(jīng)存在,就不用再進(jìn)行添加
          continue;
        }
        this.selectPeople.push(this.jobList[index].son[i].member[j]);
      }
    }
  }
}

4.通過子級(jí)改變父級(jí)的選中狀態(tài)

子級(jí)HTML。需要注意的是,這里面綁定了兩次stateChanged事件,只是參數(shù)不同。@click="stateChanged(index, j, k)"代表第二層級(jí)的子級(jí)。@click="stateChanged(index, i)"代表第一層級(jí)的子級(jí)。

<ul class="item_second" v-show="isOpenItem[index] && isOpenItem[index].group">
  <div class="item_third" v-for="(second,j) in item.son" :key="second.id">
    <div @click="checkSecondItem(index, j)" class="item">
      <div class="checkGroup" @click="checkSecondAll(index, j)" @click.stop>
        <i class="iconfont"
          :class="{'icon-gouxuan':isSelectAll[index] && isSelectAll[index].child[j],'icon-checkboxround0':isSelectAll[index] && !isSelectAll[index].child[j]}"></i>
      </div>
      {{second.name}}
    </div>
    <ul class="item_fourth" v-show="isOpenItem[index] && isOpenItem[index].child[j]">
      <li v-for="(third,k) in second.member" :key="third.pid">
        <input @click="stateChanged(index, j, k)" type="checkbox" name="school"
            :id="'check'+third.pid"
            v-model="selectPeople"
            :value="third">
        <label class="content-wrap" :for="'check'+third.pid">
          <div class="item_img" :style="{ background: third.headColor }">{{ third.name }}</div>
          <div class="content">
            <p class="content_name">
              {{third.userName}}
            </p>
            <p class="vice">{{ third.job }}</p>
          </div>
        </label>
      </li>
    </ul>
  </div>
  <li v-for="(people,i) in item.member" :key="people.pid">
    <input @click="stateChanged(index,i)" type="checkbox" name="school" :id="'check'+people.pid"
        v-model="selectPeople"
        :value="people">
    <label class="content-wrap" :for="'check'+people.pid">
      <div class="item_img" :style="{ background: people.headColor }">{{ people.name }}</div>
      <div class="content">
        <p class="content_name">
          {{people.userName}}
        </p>
        <p class="vice">{{ people.job }}</p>
      </div>
    </label>
  </li>
</ul>

子級(jí)JS。其中,stateChanged函數(shù),通過傳入的參數(shù)不同來判斷當(dāng)前屬于哪一層級(jí)的數(shù)據(jù)。setFirstLevelChecked函數(shù),通過判斷所有子級(jí)選項(xiàng)的選中狀態(tài)來給第一層級(jí)添加選中狀態(tài)。

stateChanged(index, i, j) {
  if (j !== undefined) { //如果有j值,代表第三層級(jí)數(shù)據(jù)
    if (this.selectPeople.includes(this.jobList[index].son[i].member[j])) {//點(diǎn)擊之前為選中狀態(tài)
      this.$set(this.isSelectAll[index].child, i, false);//改變父級(jí)按鈕的選中狀態(tài)為非選中狀態(tài)
      this.$set(this.isSelectAll[index], 'group', false);//改變頂級(jí)按鈕的選中狀態(tài)為非選中狀態(tài)
    } else {//點(diǎn)擊之前為非選中狀態(tài)
      //給父級(jí)添加選中狀態(tài)
      for (let k = 0; k < this.jobList[index].son[i].member.length; k++) {
        if (!this.selectPeople.includes(this.jobList[index].son[i].member[k]) && this.jobList[index].son[i].member[k] != this.jobList[index].son[i].member[j]) {//只要有其中一個(gè)未選中,就跳出循環(huán),不給父級(jí)添加選中狀態(tài)
          return false
        }
      }
      this.$set(this.isSelectAll[index].child, i, true);//改變父級(jí)按鈕的選中狀態(tài)為選中狀態(tài)
      this.setFirstLevelChecked(index, this.jobList[index].son[i].member[j]);//給第一級(jí)添加選中狀態(tài)
    }
  } else {//沒有j值,第二層級(jí)數(shù)據(jù)
    if (this.selectPeople.includes(this.jobList[index].member[i])) {//點(diǎn)擊之前為選中狀態(tài)
      this.$set(this.isSelectAll[index], 'group', false);//改變父級(jí)按鈕的選中狀態(tài)為非選中狀態(tài)
    } else {//點(diǎn)擊之前為非選中狀態(tài)
      this.setFirstLevelChecked(index, this.jobList[index].member[i]);//給第一級(jí)添加選中狀態(tài)
    }
  }
},
setFirstLevelChecked(index, data) {//給第一級(jí)添加選中狀態(tài)
  for (let k in this.jobList[index].member) {
    if (!this.selectPeople.includes(this.jobList[index].member[k]) && data != this.jobList[index].member[k]) {//只要有其中一個(gè)未選中,就跳出循環(huán),不給父級(jí)添加選中狀態(tài)
      return false
    }
  }
  for (let i in this.jobList[index].son) {//循環(huán)添加有部門的人員(對(duì)應(yīng)列表第三層級(jí))
    for (let j in this.jobList[index].son[i].member) {
      if (!this.selectPeople.includes(this.jobList[index].son[i].member[j]) && data != this.jobList[index].son[i].member[j]) { //如果已經(jīng)存在,就不用再進(jìn)行添加
        return false
      }
    }
  }
  this.$set(this.isSelectAll[index], 'group', true);//改變第一級(jí)按鈕的選中狀態(tài)為選中狀態(tài)
}

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • vue-router路由跳轉(zhuǎn)問題 replace

    vue-router路由跳轉(zhuǎn)問題 replace

    這篇文章主要介紹了vue-router路由跳轉(zhuǎn)問題 replace,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • 在Vant的基礎(chǔ)上封裝下拉日期控件的代碼示例

    在Vant的基礎(chǔ)上封裝下拉日期控件的代碼示例

    這篇文章主要介紹了在Vant的基礎(chǔ)上封裝下拉日期控件的代碼示例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-12-12
  • 關(guān)于Vue中this.$set的正確使用

    關(guān)于Vue中this.$set的正確使用

    我們?cè)陧?xiàng)目開發(fā)的過程中,經(jīng)常會(huì)遇到這種情況:為data中的某一個(gè)對(duì)象添加一個(gè)屬性,我們?cè)撊绾谓鉀Q這個(gè)問題呢,下面小編給大家?guī)砹薞ue中this.$set的正確使用,感興趣的朋友跟隨小編一起看看吧
    2022-12-12
  • vue中created、watch和computed的執(zhí)行順序詳解

    vue中created、watch和computed的執(zhí)行順序詳解

    由于vue的雙向數(shù)據(jù)綁定,自動(dòng)更新數(shù)據(jù)的機(jī)制,在數(shù)據(jù)變化后,對(duì)此數(shù)據(jù)依賴?的所有數(shù)據(jù),watch事件都會(huì)被更新、觸發(fā),下面這篇文章主要給大家介紹了關(guān)于vue中created、watch和computed的執(zhí)行順序,需要的朋友可以參考下
    2022-11-11
  • vue項(xiàng)目打包為APP,靜態(tài)資源正常顯示,但API請(qǐng)求不到數(shù)據(jù)的操作

    vue項(xiàng)目打包為APP,靜態(tài)資源正常顯示,但API請(qǐng)求不到數(shù)據(jù)的操作

    這篇文章主要介紹了vue項(xiàng)目打包為APP,靜態(tài)資源正常顯示,但API請(qǐng)求不到數(shù)據(jù)的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09
  • element-ui循環(huán)顯示radio控件信息的方法

    element-ui循環(huán)顯示radio控件信息的方法

    今天小編就為大家分享一篇element-ui循環(huán)顯示radio控件信息的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2018-08-08
  • 前端框架Vue父子組件數(shù)據(jù)雙向綁定的實(shí)現(xiàn)

    前端框架Vue父子組件數(shù)據(jù)雙向綁定的實(shí)現(xiàn)

    Vue項(xiàng)目中經(jīng)常使用到組件之間的數(shù)值傳遞,實(shí)現(xiàn)的方法很多,但是原理上基本大同小異。這篇文章將給大家介紹Vue 父子組件數(shù)據(jù)單向綁定與Vue 父子組件數(shù)據(jù)雙向綁定的對(duì)比從而認(rèn)識(shí)雙向綁定
    2021-09-09
  • Vue3中父子組件之間相互通信的方式詳解

    Vue3中父子組件之間相互通信的方式詳解

    本文主要探討了 Vue 3 中父子組件之間的通信方式,包括父?jìng)髯?通過props傳遞數(shù)據(jù)和方法;子傳父,用emit觸發(fā)自定義事件并傳遞數(shù)據(jù);還介紹了使用ref直接操作子組件實(shí)例,借助defineExpose暴露子組件的屬性和方法給父組件,需要的朋友可以參考下
    2025-01-01
  • Vue 實(shí)例事件簡(jiǎn)單示例

    Vue 實(shí)例事件簡(jiǎn)單示例

    這篇文章主要介紹了Vue 實(shí)例事件,結(jié)合簡(jiǎn)單示例形勢(shì)分析了vue.js事件響應(yīng)與頁(yè)面元素相關(guān)操作技巧,需要的朋友可以參考下
    2019-09-09
  • vue3的自定義hook函數(shù)使用

    vue3的自定義hook函數(shù)使用

    這篇文章主要介紹了vue3的自定義hook函數(shù)使用,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-04-04

最新評(píng)論

苏尼特右旗| 顺昌县| 施甸县| 行唐县| 新河县| 宁波市| 克东县| 科技| 蒲江县| 嘉祥县| 连南| 沙坪坝区| 蛟河市| 马尔康县| 涟水县| 新田县| 迁西县| 万年县| 凤翔县| 晋城| 章丘市| 铁力市| 资兴市| 新河县| 哈巴河县| 新泰市| 锡林浩特市| 务川| 榆树市| 托克逊县| 东港市| 逊克县| 新竹市| 化隆| 尚志市| 德安县| 浦县| 观塘区| 大足县| 丰顺县| 内乡县|