Vue 2.0 권한 트 리 구성 요소 구현 코드
<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 급 연결 작업
buttonControl
과supMenuId
이 추가 되 었 습 니 다.구성 요소 코드 참조:
<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 권한 트 리 구성 요소 구현 코드 입 니 다.여러분 에 게 도움 이 되 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 메 시 지 를 남 겨 주세요.소 편 은 바로 답 해 드 리 겠 습 니 다.여기 서도 저희 사이트 에 대한 여러분 의 지지 에 감 사 드 립 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Vue Render 함수로 DOM 노드 코드 인스턴스 만들기render에서createElement 함수를 사용하여 DOM 노드를 만드는 것은 직관적이지 않지만 일부 독립 구성 요소의 디자인에서 특수한 수요를 충족시킬 수 있습니다.간단한 렌더링 예는 다음과 같습니다. 또한 v...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.