国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

Vue2.0權限樹組件實現代碼

2019-11-19 15:38:34
字體:
來源:轉載
供稿:網友

項目使用的餓了么的Element-Ui,權限樹使用其樹形控件:

<el-tree :data="data" ></el-tree> 

剛開始沒有特殊需求,三級分支,效果看著還可以。但是接下來的新需求:增加頁面操作按鈕權限,即達到四級分支,同時要求四級權限布局方式為橫向,而且操作按鈕權限非固定四級樹,但是樣式要求一致。這樣子就很難操作了,如果單單是四級樹為橫向,還可以調調樣式完成。本來想修改element的tree控件源碼來實現,網上查了一些資料,還沒有很好的辦法生成其編譯文件。最終決定自己寫組件完成上述需求。

先上效果圖:

基本可以滿足需求,樣式稍微比element差點,后期再優化。

組件代碼如下:

<template>  <li :class="[isButton, hasBorder]" style="list-style:none;">   <span @click="toggle" v-show="model.menuLevel!==1" >    <i v-if="isFolder" class="icon" :class="[open ? 'folder-open': 'folder']" style="margin-bottom: 3px;"></i>    <i v-if="!isFolder" class="icon file-text"></i>    <input type="checkbox" class="checkCls" @click.stop="selTree(model)" :id="'menu'+model.id" :class="'group'+label">    {{ model.menuName }}   </span>   <ul v-show="open" v-if="isFolder">    <tree-menu v-for="(item, index) in model.childNode" :model="item" :key="index" :menuList="menuList" :label="label" :selectKeys="selectKeys" ></tree-menu>   </ul>  </li> </template>  <script type="text/ecmascript-6"> import $ from 'jquery' export default {  name: 'treeMenu',  props: ['model', 'menuList', 'label', 'selectKeys'],  data () {   return {    open: true, // 默認打開彩單樹    selAllkeys: []   }  },  computed: {   isFolder: function () {    return this.model.childNode && this.model.childNode.length   },   isButton: function () {    if (this.model.buttonControl === '1') {     return 'btnCls'    } else {     return 'menuCls'    }   },   hasBorder: function () {    if (this.model.menuLevel === 1) {     return 'blk_border'    }   }  },  methods: {   getAllKeys () {    var keys = []    var objs = $('.group' + this.label + ':checked')    for (let i = 0; i < objs.length; i++) {     let id = objs[i].id     id = id.substring(4)     keys.push((id - 0)) // 保存選中菜單id    }    return keys   },   toggle: function () {    if (this.isFolder) {     this.open = !this.open    }   },   // 根據id獲取menu對象   getMeunById (id, allMenuList) {    var menu = {}    if (allMenuList.id === id) { // 一級菜單     menu = allMenuList    } else if (allMenuList.childNode && allMenuList.childNode.length) { // 二級菜單     for (let i = 0; i < allMenuList.childNode.length; i++) {      if (allMenuList.childNode[i].id === id) {       menu = allMenuList.childNode[i]       break      } else if (allMenuList.childNode[i].childNode && allMenuList.childNode[i].childNode.length) { // 三級       for (let j = 0; j < allMenuList.childNode[i].childNode.length; j++) {        if (allMenuList.childNode[i].childNode[j].id === id) {         menu = allMenuList.childNode[i].childNode[j]         break        }       }      }     }    }    return menu   },   // checkbox點擊事件   selTree (model) {    var obj = $('#menu' + model.id)[0] // checkbox DOM對象    if (obj.checked) { // 選中     // 若存在下級,下級全部選中     if (model.childNode && model.childNode.length) {      this.subMenusOp(model.childNode, 1)     }     // 若存在上級,確認是否需要選中上級CheckBox     if (model.supMenuID !== 0 && model.menuLevel > 2) {      this.supMenusOp(model.supMenuID, 1)     }    } else { // 取消     // 若存在下級,下級全部取消     if (model.childNode && model.childNode.length) {      this.subMenusOp(model.childNode, 0)     }     // 若存在上級,確認是否需要取消上級CheckBox     if (model.supMenuID !== 0 && model.menuLevel > 2) {      this.supMenusOp(model.supMenuID, 0)     }    }    this.getAllKeys()   },   // 下級菜單操作 flag=1為選中,flag=0為取消   subMenusOp (childNodes, flag) {    for (let i = 0; i < childNodes.length; i++) {     var menu = childNodes[i]     var id = menu.id     if (flag === 1) { // 選中      $('#menu' + id)[0].checked = true     } else { // 取消      $('#menu' + id)[0].checked = false     }     if (menu.childNode && menu.childNode.length) {      this.subMenusOp(menu.childNode, flag)     }    }   },   // 上級菜單操作(選中:flag=1,取消:flag=0)   supMenusOp (id, flag) {    var menu = this.getMeunById(id, this.menuList)    if (menu.childNode && menu.childNode.length) {     var childLength = menu.childNode.length // 直接子級個數     var selectCount = 0     for (let i = 0; i < childLength; i++) {      let id1 = menu.childNode[i].id      if ($('#menu' + id1)[0].checked) {       selectCount++      }     }     if (flag === 1) { // 選中      if (childLength === selectCount) {       $('#menu' + id)[0].checked = true       if (menu.supMenuID !== 0 && menu.menuLevel > 2) {        this.supMenusOp(menu.supMenuID, flag)       }      }     } else if (flag === 0) {      if (childLength !== selectCount) {       $('#menu' + id)[0].checked = false       if (menu.supMenuID !== 0 && menu.menuLevel > 2) {        this.supMenusOp(menu.supMenuID, flag)       }      }     }    }   },   // 計算所有下級節點是否全部選中,是返回true,否返回false   isAllSel (childNodes, selectKeys) {    var nodeKeys = [] // 選中的id集合    this.addKeys(childNodes, selectKeys, nodeKeys)    var allKeys = []    this.getNodesCount(childNodes, allKeys)    if (nodeKeys.length === allKeys.length) {     return true    } else {     return false    }   },   // 計算childNodes下選中的id集合   addKeys (childNodes, selectKeys, Arrs) {    for (let i = 0; i < childNodes.length; i++) {     if (selectKeys.indexOf(childNodes[i].id) >= 0) {      Arrs.push(childNodes[i].id)     }     if (childNodes[i].childNode && childNodes[i].childNode.length) {      this.addKeys(childNodes[i].childNode, selectKeys, Arrs)     }    }   },   // 計算childNodes的子級數   getNodesCount (childNodes, allKeys) {    for (let i = 0; i < childNodes.length; i++) {     allKeys.push(childNodes[i].id)     if (childNodes[i].childNode && childNodes[i].childNode.length) {      this.getNodesCount(childNodes[i].childNode, allKeys)     }    }   }  },  mounted () {   // 禁止復選框的冒泡事件   $("input[type='checkbox']").click(function (e) {    e.stopPropagation()   })   // 選中菜單使能   if (this.selectKeys instanceof Array && this.selectKeys.length > 0 && this.selectKeys.indexOf(this.model.id) >= 0) {    if (this.model.childNode && this.model.childNode.length && this.model.menuLevel !== 1) { // 包含子級,一級菜單除外     // 計算所有子節點是否全部選中     if (this.isAllSel(this.model.childNode, this.selectKeys)) {      $('#menu' + this.model.id)[0].checked = true     }    } else {     $('#menu' + this.model.id)[0].checked = true    }   }  } } </script>  <style> .blk_border{  border:1px solid #d1dbe5;  padding-bottom: 15px; } .blk_border ul{  padding-left: 15px; } ul {  list-style: none; } i.icon {  display: inline-block;  width: 15px;  height: 15px;  background-repeat: no-repeat;  vertical-align: middle; } .icon.folder {  background-image: url(../../images/close.png); } .icon.folder-open {  background-image: url(../../images/open.png); } .tree-menu li {  line-height: 1.5; } li.btnCls {  float: left;  margin-right: 10px; } li.menuCls {  clear: both;  line-height:30px; } .checkCls {  vertical-align: middle; } .el-tabs__content{  color:#48576A; } </style> 權限樹的數據結構有一定要求,比element的tree控件數據結構屬性稍多一些,否則實現也不會這么簡單了,優化后的權限樹數據結構在選中菜單返回上簡化了很多,也沒有用到vuex。權限樹數據結構為:{   'childNode': [    {     'childNode': [      {       'icon': '',       'id': 242,       'menuLevel': 3,       'menuName': '旅游訂單',       'menuTop': 1,       'menuUrl': '/',       'buttonControl': '0',       'supMenuID': 241      },      {       'icon': '',       'id': 243,       'menuLevel': 3,       'menuName': '簽證訂單',       'menuTop': 2,       'menuUrl': '/',       'buttonControl': '0',       'supMenuID': 241      },      {       'icon': '',       'id': 244,       'menuLevel': 3,       'menuName': '出團通知書',       'menuTop': 3,       'menuUrl': '/',       'buttonControl': '0',       'supMenuID': 241      }     ],     'icon': '',     'id': 241,     'menuLevel': 2,     'menuName': '訂單管理',     'menuTop': 1,     'menuUrl': '/',     'buttonControl': '0',     'supMenuID': 240    },    {     'childNode': [      {       'icon': '',       'id': 246,       'menuLevel': 3,       'menuName': '旅游產品',       'menuTop': 1,       'menuUrl': '/tourProduct',       'buttonControl': '0',       'supMenuID': 245      },      {       'icon': '',       'id': 247,       'menuLevel': 3,       'menuName': '圖庫',       'menuTop': 2,       'menuUrl': '/basePicStore',       'buttonControl': '0',       'supMenuID': 245      },      {       'icon': '',       'id': 248,       'menuLevel': 3,       'menuName': '簽證產品',       'menuTop': 3,       'menuUrl': '/',       'buttonControl': '0',       'supMenuID': 245      }     ],     'icon': '',     'id': 245,     'menuLevel': 2,     'menuName': '產品管理',     'menuTop': 2,     'menuUrl': '/',     'buttonControl': '0',     'supMenuID': 240    },    {     'childNode': [      {       'icon': '',       'id': 250,       'menuLevel': 3,       'menuName': '旅游廣告',       'menuTop': 1,       'menuUrl': '/',       'buttonControl': '0',       'supMenuID': 249      }     ],     'icon': '',     'id': 249,     'menuLevel': 2,     'menuName': '廣告管理',     'menuTop': 3,     'menuUrl': '/',     'buttonControl': '0',     'supMenuID': 240    }   ],   'icon': '',   'id': 240,   'menuLevel': 1,   'menuName': '業務中心',   'menuTop': 1,   'menuUrl': '/',   'buttonControl': '0',   'supMenuID': 0  } 

實際數據為上述對象的數組。

這里主要增加了buttonControlsupMenuId,方便實現按鈕權限的樣式判斷和選中、取消操作的checkbox級聯操作。

引用組件代碼:

<el-tab-pane v-for="(menu, index) in theModel" :key="index" :label="menu.menuName">  <my-tree :model="menu" ref="tree" :menuList="menu" :label="index" :selectKeys="selectKeys"></my-tree> </el-tab-pane>

theModel即為權限樹數組,selectKeys為選中的權限數組集合,即id集合。

mounted()實現初始化操作:禁止checkbox的冒泡時間,selectKeys的賦值操作。

其實權限樹或者說菜單樹的要點就在遞歸算法上,按鈕的選中或取消,都需要執行遞歸操作。這里使用jQuery來協助操作,簡化了許多事情,應該還是數據綁定的精神沒有掌握好吧。getAllKeys()獲取checkbox為true的權限id返回。
實際獲取選中的權限菜單的數據如下圖:

總結

以上所述是小編給大家介紹的Vue2.0權限樹組件實現代碼,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對武林網網站的支持!

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 故城县| 乌苏市| 大兴区| 邢台市| 新田县| 镇赉县| 寻乌县| 永寿县| 岫岩| 五家渠市| 元朗区| 阿巴嘎旗| 阿尔山市| 永顺县| 灵丘县| 三原县| 太谷县| 武胜县| 苏尼特左旗| 都匀市| 曲靖市| 台湾省| 青铜峡市| 武冈市| 小金县| 淮北市| 洛宁县| 绥江县| 湘乡市| 壶关县| 高要市| 高邮市| 宣化县| 五常市| 乌兰县| 涡阳县| 噶尔县| 泊头市| 池州市| 邵武市| 唐河县|