基于Vue的树形菜单权限分配
组件-vue
<template>
<el-row class="prems-setting">
<el-col :span="24" class="prems-area">
<el-row>
<el-col :span="10" class="card-prems-tree">
<div class="div-title">待分配权限</div>
<el-tree
:data="leftData"
ref="leftTree"
:props="leftDefaultProps"
node-key="menuId"
show-checkbox
:filter-node-method="leftFilterNode"
:default-checked-keys="defCheckedKeys"
:default-expanded-keys="defaultExpandedKeys"
class="role-tree"
>
</el-tree>
</el-col>
<el-col :span="4" class="setting-btn-area">
<el-button class="circleBtn" @click="addPrems"><i class="el-icon-arrow-right"></i></el-button>
<el-button class="circleBtn" @click="removePrems" style="margin-top:20px"><i class="el-icon-arrow-left"></i></el-button>
</el-col>
<el-col :span="10" class="card-prems-tree">
<div class="div-title">已分配权限</div>
<div>
<el-tree
:data="rightData"
ref="rightTree"
:props="rightDefaultProps"
show-checkbox
node-key="menuId"
:filter-node-method="rightFilterNode"
:default-expanded-keys="defaultExpandedKeys"
class="role-tree"
>
</el-tree>
</div>
</el-col>
</el-row>
</el-col>
<el-col :span="24" class="bottom-btn">
<el-button @click="handleCancel">取 消</el-button>
<el-button type="primary" :loading="saveBtnLoading" @click="handleSave">保 存</el-button>
</el-col>
</el-row>
</template>
<script>
import ajax from './../../../pub/utils/ajaxUtil.js';
import {showMessage} from '../../../pub/utils/promptUtil';
import {getTreeData,getmenuList,submitUrl} from './config/baseUrl'
export default{
props:{
roleData:Array,
model:Object
},
data() {
return {
leftData:null,
leftDefaultProps:{
label:'label',
children:'childMenus'
},
defaultExpandedKeys:[],
checkedData:[],
rightData:null,
rightDefaultProps:{
label:'label',
children:'childMenus'
},
parentFuncName:'智慧管理平台',
filterText:'',
defaultCheckedKeys:[],
defCheckedKeys:[],
isEdit:false,
selectTreeData0:[],
saveBtnLoading:false,
}
},
created:function () {
this.getPremsByOsId();
},
watch: {
filterText: {
immediate: true,
handler: function (v, oldv) {
if(this.$refs.rightTree){
this.$refs.rightTree.filter(v);
}
}
},
defaultCheckedKeys: {
immediate: true,
handler: function (v, oldv) {
this.defCheckedKeys = v;
this.setLeftCheckedKeys(v);
}
}
},
methods:{
/**
* 根据系统ID获取权限树
*
*/
getPremsByOsId:function () {
var _self = this;
var treeData1=[]
ajax.getJson(getTreeData, {},(res)=> {
if (res.success) {
//这是后台返回的数组结构 this.fromData=res.dataList
// this.fromData=res.dataList
//自己写一个数据结构
this.fromData = [
{
dr: 0,
label: "项目管理",
level: null,
menuId: "dafa521094644ec7a9c7fa882696351b",
menuOder: 1,
menuType: "sunsea",
parentId: "",
url: "/sunSea",
childMenus:[
{
childMenus: [],
disable: 1,
dr: 0,
label: "大区档案",
level: null,
menuId: "ad6dd4eff5a14735b27ab4e15a4d30b0",
menuOder: 1,
menuType: "sunsea",
parentId: "dafa521094644ec7a9c7fa882696351b",
path: null,
style: null,
ts: 1578479397000,
url: "/areaConfig",
},
{
childMenus: [],
disable: 1,
dr: 0,
label: "项目档案",
level: null,
menuId: "a8ee0ec251d34affa647496acca98428",
menuOder: 2,
menuType: "sunsea",
parentId: "dafa521094644ec7a9c7fa882696351b",
url: "projectInfo",
}
]
},{
disable: 1,
dr: 0,
label: "系统管理",
level: null,
menuId: "b8bf0135-9318-4e35-a3ea-4c8f2bd807ff",
menuOder: 50,
menuType: "sunsea",
parentId: null,
path: "0",
url: "/sunSea",
childMenus:[
{
childMenus: [],
disable: 1,
dr: 0,
label: "用户管理",
level: null,
menuId: "39216b30b6234d66a4405ba7275d9beb",
menuOder: 1,
menuType: "sunsea",
parentId: "b8bf0135-9318-4e35-a3ea-4c8f2bd807ff",
url: "/userManage",
},
{
childMenus: [],
disable: 1,
dr: 0,
label: "角色管理",
level: null,
menuId: "8d1c9229-4f00-4ef9-9c38-bc460bf716a8",
menuOder: 3,
menuType: "sunsea",
parentId: "b8bf0135-9318-4e35-a3ea-4c8f2bd807ff",
path: "",
style: null,
ts: 1578479397000,
url: "/roleManage",
},{
childMenus: [],
disable: 1,
dr: 0,
label: "自定义档案",
level: null,
menuId: "e83938a83a5948e3a6a530d4c4e671e5",
menuOder: 11,
menuType: "sunsea",
parentId: "b8bf0135-9318-4e35-a3ea-4c8f2bd807ff",
url: "/userDefined",
}
]
}
]
treeData1 = [{
menuId:'all',
label:_self.parentFuncName,
childMenus:this.fromData
}];
treeData1.forEach(function(item,index){
if(index == 0){
_self.defaultExpandedKeys = [item.menuId];
}
});
_self.leftData = treeData1;
_self.getFunctionsByRoleId();
} else {
this.$alert(res.msg, "信息操作", {
confirmButtonText: "确定"
})
}
})
},
/**
* 查询功能权限
*/
getFunctionsByRoleId:function () {
var _self = this;
ajax.getJson(getmenuList, {},(res)=> {
if (res.success) {
var backData=[]
// backData=res.dataList //这是后台返回的选中的节点menuId
backData=['e83938a83a5948e3a6a530d4c4e671e5','a8ee0ec251d34affa647496acca98428'] //自己先模拟写一下
if(backData){
var functionList = backData.length>0?backData:[];
/**新增状态 来回切换系统时,带出原来选择的数据 begin**/
if(functionList.length == 0){
if(_self.checkedData.length>0){
_self.rightData = _self.leftData;
_self.$nextTick(function () {
_self.$refs.rightTree.filter(_self.checkedData);
});
}
return;
}
/**新增状态 来回切换系统时,带出原来选择的数据 end**/
_self.rightData = _self.leftData;
var funcIds = [];
functionList.forEach(function (item) {
funcIds.push(item.menuId);
});
_self.defaultCheckedKeys = funcIds;
_self.setLeftCheckedKeys(funcIds);
_self.checkedData = functionList;
if(functionList && functionList.length>0){
_self.isEdit = true;
}
_self.$nextTick(function () {
_self.$refs.rightTree.filter(_self.checkedData);
});
}else{
_self.$nextTick(function () {
_self.$refs.rightTree.filter(_self.selectTreeData0);
});
}
} else {
this.$alert(res.msg, "信息操作", {
confirmButtonText: "确定"
})
}
})
},
rightFilterNode:function (value, data) {
if (!value) return true;
for(var i= 0;i<value.length;i++){
if(data.menuId == value[i].menuId){
return true;
}
}
},
leftFilterNode:function (value, data) {
if (!value) return true;
for(var i= 0;i<value.length;i++){
if(value[i].menuId == data.menuId){
return false;
}else{
return true;
}
}
},
/**
* 获取已选择节点
*/
getLeftCheckedNodes:function(){
return this.$refs.leftTree.getCheckedNodes();
},
/**
* 设置选择节点
* @params checkedData
*/
setLeftCheckedKeys:function (checkedData) {
if(this.$refs.leftTree){
this.$refs.leftTree.setCheckedKeys(checkedData);
}
},
setLeftCheckedNodes:function (checkedData) {
if(this.$refs.leftTree){
this.$refs.leftTree.setCheckedNodes(checkedData);
}
},
/**
* 设置
*
*/
addPrems:function(){
var _self = this;
if(!_self.rightData || _self.rightData.length == 0){
_self.rightData = _self.leftData;
}
var selectedData = this.getLeftCheckedNodes();
_self.selectTreeData0 = selectedData;
_self.checkedData = selectedData;
console.log(_self.checkedData)
_self.$nextTick(function () {
_self.$refs.rightTree.filter(selectedData);
});
},
/**
* 取消
*/
removePrems:function(){
var _self = this;
var selectedData = [];
var treeName = 'rightTree';
selectedData = _self.getRightCheckedNodes(treeName);
var checkedData = _self.checkedData;
if(JSON.stringify(_self.checkedData) == '{}'){
return;
}
var treeData = [];
checkedData.forEach(function(item,index){
for(var i=0;i<selectedData.length;i++){
if(item.menuId == selectedData[i].menuId){
return;
}
}
treeData.push(item);
});
if(treeData.length>0){
var leftCheckedKeys = [];
for(var i=0;i<treeData.length;i++){
leftCheckedKeys.push(treeData[i].menuId);
}
_self.defaultCheckedKeys = leftCheckedKeys;
_self.$refs[treeName].filter(treeData);
_self.checkedData = treeData;
}else{
_self.rightData = [];
_self.defaultCheckedKeys = [];
_self.checkedData = treeData;
_self.$refs[treeName].filter(treeData);
}
},
/**
* 获取已选择节点
*/
getRightCheckedNodes:function(treeName){
return this.$refs[treeName].getCheckedNodes();
},
//确定
handleSave:function(){
var _self = this;
var functionIds = [];
_self.checkedData.forEach(function(item){
functionIds.push(item.menuId);
});
if(!_self.isEdit) {
if (functionIds.length == 0) {
showMessage('提示', '您未选择功能权限', 'warning');
return;
}
}
var params = {
isEdit:_self.isEdit,
};
if(functionIds.length >0){
params.functionIds = functionIds.join(',')
}
_self.saveBtnLoading = true;
ajax.postJson(submitUrl,params, {},(data)=> {
if(data && data.result == 200){
_self.saveBtnLoading = false;
showMessage('成功','分配操作权限成功!','success');
_self.handleCancel();
_self.$emit('refresh');
}else{
_self.saveBtnLoading = false;
showMessage('失败',data.message?data.message:'分配操作权限失败!','error');
}
})
},
//取消
handleCancel:function(){
this.$emit('closeDialog');
},
}
}
</script>
<style scoped>
.role-tree{
height: 300px;
overflow-y: scroll;
}
.div-title{
height: 40px;
line-height: 40px;
background: #f5f7fa;
margin: 0;
padding-left: 15px;
border: 1px solid #EBEEF5;
border-bottom: none;
}
.setting-btn-area {
height:340px;
display: flex;
justify-content: center;
flex-direction: column;
}
.setting-btn-area .circleBtn{
width:40px;
height:40px;
border-radius: 50%;
display: flex;
justify-content: center;
margin: 0 auto;
color: #FFF;
background-color: #409EFF;
border:1px solid #409EFF;
}
.bottom-btn{
text-align:center;
margin:20px 0;
}
</style>
引用组件
<template>
<treeSetting></treeSetting>
</template>
<script>
import treeSetting from '../../../pub/components/treeSetting.vue'
export default {
components: {treeSetting}
}
</script>
粗浅的写了一下,那块需要进一步优化,欢迎指出,共同进步