Vue 2.0 권한 트 리 구성 요소 구현 코드

프로젝트 에 사용 되 는 배 고 픈 Element-Ui,권한 트 리 는 트 리 컨트롤 을 사용 합 니 다:

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

처음에는 특별한 수요 가 없 었 고 3 급 분기 로 효과 가 괜찮아 보 였 다.그러나 다음 의 새로운 수요:페이지 조작 버튼 권한 을 증가 합 니 다.즉,4 급 분기 에 달 하 는 동시에 4 급 권한 레이아웃 방식 이 가로 이 고 조작 버튼 권한 은 고정 4 급 트 리 가 아니 지만 스타일 요구 가 일치 합 니 다.이렇게 하면 조작 하기 가 매우 어렵 습 니 다.만약 에 4 급 나무 만 가로 면 스타일 을 조정 할 수 있 습 니 다.원래 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 
 } 
실제 데 이 터 는 상기 대상 의 배열 이다.
여기 에는 버튼 권한 의 스타일 판단 과 선택,취소 작업 을 편리 하 게 할 수 있 는 checkbox 급 연결 작업buttonControlsupMenuId이 추가 되 었 습 니 다.
구성 요소 코드 참조:

<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 를 되 돌려 줍 니 다.
선택 한 권한 메뉴 의 데 이 터 를 다음 그림 과 같이 가 져 옵 니 다:

총결산
위 에서 말 한 것 은 소 편 이 소개 한 Vue 2.0 권한 트 리 구성 요소 구현 코드 입 니 다.여러분 에 게 도움 이 되 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 메 시 지 를 남 겨 주세요.소 편 은 바로 답 해 드 리 겠 습 니 다.여기 서도 저희 사이트 에 대한 여러분 의 지지 에 감 사 드 립 니 다!

좋은 웹페이지 즐겨찾기