欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

vue?tree封裝一個(gè)可選的樹(shù)組件方式

 更新時(shí)間:2022年03月30日 09:12:44   作者:秋刀魚(yú)笛滋味  
這篇文章主要介紹了vue?tree封裝一個(gè)可選的樹(shù)組件方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

組件實(shí)現(xiàn)的基本功能

1,根據(jù)后端返回的數(shù)據(jù)格式,傳入組件動(dòng)態(tài)的渲染出當(dāng)前角色有哪些權(quán)限(新建,修改)

2,適配有2級(jí)和只有一級(jí)多選的數(shù)據(jù)

3,有全選(√) ,全不選 ,部分已選(-)的3裝狀態(tài),每一級(jí)都支持(用的iview2次封裝)

4,改變之后返回當(dāng)前選中的所有權(quán)限的id,用于提交

5,手風(fēng)琴效果,小屏適配

先看效果圖

有部分權(quán)限沒(méi)打開(kāi)

關(guān)閉狀態(tài)

打開(kāi)

在這里插入圖片描述

小屏

在這里插入圖片描述

權(quán)限數(shù)據(jù)結(jié)構(gòu),select_status=1表示選中

在這里插入圖片描述

默認(rèn)添加沒(méi)有權(quán)限的初始數(shù)據(jù)結(jié)構(gòu)

在這里插入圖片描述

有些數(shù)據(jù)只有一級(jí)子菜單,有些有兩級(jí)

核心代碼.vue

<template>
  <div class="powerList">
    <div v-for="(item,index) in powers" :key="item.id" :class="{item:true,active:item.active}">
      <Checkbox :indeterminate="item.indeterminate" :value="item.val1" @click.prevent.native="handleCheckAll(index)">
        <span style="color:#1C213A;font-weight:600;">&nbsp;{{item.name}}</span>
      </Checkbox>
      <div style="font-size:30px;float:right;width:220px;cursor: pointer;color:#BEC1C8;text-align:right;" @click="open(item.active,index)">
        <Icon :type="item.active? 'md-arrow-dropup': 'md-arrow-dropdown'" />
      </div>
      <!-- 全部都是只有一級(jí)子菜單的 -->
      <CheckboxGroup v-if="oneChild(item.child)" v-model="item.checked" @on-change="checkGroupChange($event,index)">
        <Checkbox v-for="item2 in item.child" :key='item2.id' :label="item2.id">{{item2.name}}</Checkbox>
      </CheckboxGroup>
      <template v-else>
        <div v-for='(item3,index3) in item.child' :key="item3.id" class="item3">
          <!-- 有二級(jí)子菜單的 -->
          <template v-if="item3.child">
            <Checkbox :indeterminate="item3.indeterminate" :value="item3.val1" @click.prevent.native="level2CheckAll(index,index3)">&nbsp;{{item3.name}}</Checkbox>
            <CheckboxGroup v-model="item3.checked" @on-change='checkGroupChange($event,index,index3)'>
              <Checkbox v-for="item4 in item3.child" :key='item4.id' :label="item4.id">{{item4.name}}</Checkbox>
            </CheckboxGroup>
          </template>
        </div>
      </template>
    </div>
  </div>
</template>
<script>
/**
 *公共的權(quán)限選擇組件,接受后端返回的權(quán)限列表powerData
 *返回選中的權(quán)限的id的arr @change接受
  */
export default {
  props: {
    powerData: Array
  },
  data () {
    return {
      powers: []
    }
  },
  watch: {
    powerData: {
      handler (val, old) {
        if (val && val.length && JSON.stringify(val) !== JSON.stringify(old)) {
          this.powers = this.formatData(val)
          this.save([...this.powers])
        }
      },
      immediate: true,
      deep: true
    }
  },
  methods: {
    // 保存返回選中的項(xiàng)的數(shù)組
    save (arr) {
      let auth_id = []
      arr.forEach(item => {
        if (item.indeterminate || item.val1) {
          auth_id.push(item.id)
          if (this.oneChild(item.child)) {
            auth_id = auth_id.concat([...item.checked])
          } else {
            item.child.forEach(item2 => {
              if (item2.indeterminate || item2.val1) {
                auth_id.push(item2.id)
                auth_id = auth_id.concat([...item2.checked])
              }
            })
          }
        }
      })
      console.log(auth_id)
      this.$emit('change', auth_id)
    },
    //把獲取到的權(quán)限格式化成需要的格式
    /**
     * active :dom開(kāi)關(guān)
     * indeterminate: 勾選狀態(tài)為-的樣式
     * val1 全選的狀態(tài)
     * total 有多級(jí)時(shí)子菜單的總數(shù)
     * checked 二級(jí)多選當(dāng)前選中的值
      */
    formatData (arr) {
      return arr.map(item => {
        item.active = false //用于開(kāi)關(guān)下拉
        if (!this.oneChild(item.child)) { // 有多級(jí)子菜單
          let total = 0 //計(jì)算當(dāng)前項(xiàng)下的底級(jí)子菜單的總數(shù) 用于給主一級(jí)全選相應(yīng)的狀態(tài)
          item.child.map(item => item.child.length).forEach(item => {
            total += item
          })
          item.total = total
          item.child = item.child.map(item2 => {
            item2.checked = item2.child.filter(item3 => item3.select_status === 1).map(item4 => item4.id)
            if (item2.checked.length === item2.child.length) { //選中的子選項(xiàng)數(shù)量等于子選項(xiàng)數(shù)量 就是全選
              item2.indeterminate = false
              item2.val1 = true
            } else if (item2.checked.length === 0) { // 沒(méi)有選中的
              item2.indeterminate = false
              item2.val1 = false
            } else { //<
              item2.indeterminate = true
              item2.val1 = false
            }
            return item2
          })
          this.changeLevel1Status(item) // 設(shè)置一級(jí)全選的狀態(tài)
        } else { // 只有一級(jí)子菜單的
          item.checked = item.child.filter(item => item.select_status === 1).map(item => item.id) //子菜單當(dāng)前選中的值
          let childNum = item.child.length
          let checkedNum = item.child.filter(item5 => item5.select_status === 1).length
          if (checkedNum === 0) {
            item.indeterminate = false
            item.val1 = false
          } else if (checkedNum < childNum) {
            item.indeterminate = true
            item.val1 = false
          } else {
            item.indeterminate = false
            item.val1 = true
          }
        }
        return item
      })
    },
    // 權(quán)限展開(kāi),手風(fēng)琴
    open (val, index) {
      // 關(guān)閉所有的
      this.powers = this.powers.map(item => {
        item.active = false
        return item
      })
      let obj = this.powers[index]
      obj.active = !val
      // 打開(kāi)點(diǎn)擊的
      this.powers.splice(index, 1, obj)
    },
    // 只有一級(jí)子菜單的
    oneChild (arr) {
      return arr.every(item => item.child === undefined)
    },
    /**
    * 主菜單的全選
    * @param index (索引)
    */
    handleCheckAll (index) {
      if (this.oneChild(this.powers[index].child)) { //只有一級(jí)子菜單的
        let powers = [...this.powers]
        let obj = powers[index]
        if (obj.indeterminate) { //當(dāng)前項(xiàng)有子菜單選中的
          obj.val1 = false;
        } else {
          obj.val1 = !obj.val1
        }
        obj.indeterminate = false;
        if (obj.val1) { // 如果是全選
          obj.checked = obj.child.map(item => item.id);
        } else {
          obj.checked = [];
        }
        this.powers = [...powers]
        this.save([...this.powers])
      } else {
        this.checkAllOther(index)
      }
    },
    // 有多級(jí)子菜單的全選
    checkAllOther (index) {
      let powers = [...this.powers]
      if (powers[index].indeterminate) { //當(dāng)前項(xiàng)有子菜單選中的
        powers[index].val1 = false;
      } else {
        powers[index].val1 = !powers[index].val1
      }
      powers[index].indeterminate = false;
      if (powers[index].val1) { // 如果是全選
        powers[index].child.forEach(item => {
          item.val1 = true // 所有2級(jí)全選選中
          item.indeterminate = false //狀態(tài)去掉
          item.checked = item.child.map(item2 => item2.id) //2級(jí)全選的子菜單都選中
        })
      } else {
        powers[index].child.forEach(item => {
          item.val1 = false
          item.checked = [];
          item.indeterminate = false //狀態(tài)去掉
        })
      }
      this.powers = [...powers]
      this.save([...this.powers])
    },
    // 子菜單的checkGrounp改變,data選中的項(xiàng)的id構(gòu)成的arr
    checkGroupChange (data, index, index3) {
      let powers = [...this.powers]
      let obj = index3 === undefined ? powers[index] : powers[index].child[index3]// 有index3就是二級(jí)子菜單的checkGroup
      if (data.length === obj.child.length) { //全部勾選
        obj.indeterminate = false;
        obj.val1 = true;
      } else if (data.length > 0) { //有選中的
        obj.indeterminate = true;
        obj.val1 = false;
      } else { //沒(méi)選中的
        obj.indeterminate = false;
        obj.val1 = false;
      }
      // 有二級(jí)子菜單的項(xiàng)改變的時(shí)候
      if (index3 !== undefined) {
        this.changeLevel1Status(powers[index])
      }
      this.powers = [...powers]
      this.save([...this.powers])
    },
    // 2級(jí)的全選
    level2CheckAll (index, index3) {
      let powers = [...this.powers]
      let obj = powers[index].child[index3] //當(dāng)前操作的2級(jí)全選
      if (obj.indeterminate) { //當(dāng)前項(xiàng)有子菜單選中的
        obj.val1 = false;
      } else {
        obj.val1 = !obj.val1
      }
      obj.indeterminate = false;
      if (obj.val1) { // 如果是全選
        obj.checked = obj.child.map(item => item.id);
      } else {
        obj.checked = [];
      }
      this.changeLevel1Status(powers[index])
      this.powers = [...powers]
      this.save([...this.powers])
    },
    // 二級(jí)子菜單或2級(jí)全選時(shí)更改一級(jí)全選的狀態(tài)
    changeLevel1Status (obj) {
      let checkedNum = 0
      obj.child.map(item => item.checked.length).forEach(item => {
        checkedNum += item
      })
      if (checkedNum === 0) {
        obj.indeterminate = false
        obj.val1 = false
      } else if (checkedNum < obj.total) {
        obj.indeterminate = true
        obj.val1 = false
      } else {
        obj.indeterminate = false
        obj.val1 = true
      }
    }
  },
}
</script>
<style lang="scss" scoped>
.powerList {
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  .item {
    width: 370px;
    height: 58px;
    background: #f9f9f9;
    line-height: 58px;
    margin-bottom: 20px;
    padding: 0 10px 0 20px;
    overflow: hidden;
    &.active {
      height: auto;
    }
    /deep/ .ivu-checkbox-group label {
      display: block;
    }
    .item3 {
      /deep/ .ivu-checkbox-group {
        padding-left: 20px;
        label {
          display: inline-block;
        }
      }
    }
  }
}
</style>

核心代碼主要就是數(shù)據(jù)的處理,底級(jí)的更改都觸發(fā)上一級(jí)的狀態(tài)和值得改變

用的時(shí)候主要就是一個(gè)props傳入數(shù)據(jù), 一個(gè)方法返回給父組件選中的值

<power :powerData='powers' @change="powerChange" />

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。 

相關(guān)文章

最新評(píng)論