权限菜单从后台获取,在编辑角色菜单权限时,从后台获取角色权限,根据角色权限设置菜单的勾选情况,但是发现设置完后,菜单树没有更新,而是需要手动点击展开或闭合之后才会刷新,如下图
点击节点折叠展开操作后,可以看到实际需要勾选的菜单项
按正常操作,数据更新的,View就会自动渲染,既然没有重新渲染,那么我们就可以断定要么数据没有更新,要么这种更新VUE认为不是更新(不能识别这种更新)。实际我看到数据是有被修改的,实现代码如下
// 递归判断子节点 checkPermTree (menusData, rolePerms) { let that = this menusData.forEach(function (p) { if (that.hasPerm(p, rolePerms) && p.status !== -1) { p.checked = true } else { p.checked = false } if (p.children && p.children.length > 0) { that.checkPermTree(p.children, rolePerms) } }) },代码是没有问题,数据的确被更新。那么只能往VUE不识别这种更新方向思考。所以我对数据做了一个深度拷贝,修改后赋值回去,如下
editPerm (v) { this.permModalVisible = true this.editRolePermId = v.id this.modalTitle = '分配 ' + v.name + ' 的菜单权限' // 匹配勾选 let rolePerms = [] // 对象深度拷贝,否则 let allMenus = JSON.parse(JSON.stringify(this.menusData)) rolePerms = v.role_menus this.editRole = v if (this.treeLoading) { this.$Message.warning('菜单权限数据加载中,请稍后点击查看') return } // 递归判断子节点 this.checkPermTree(allMenus, rolePerms) this.expandNode(this.expandLevel, allMenus) // 重新赋值回去 this.menusData = allMenus // },然后果然,有效果。
这种更新是什么,为何不给识别?进过分析发现。在从后台获取的数据中,并没有checked这个属性,我从后台获取数据后,直接给Tree组件,这时所有菜单都是没有勾选的。(Modal隐藏)
getPermList () { this.treeLoading = true getMenuTreeList().then(res => { if (res.message === 'success') { this.deleteDisableNode(res.data.list) this.expandNode(3, res.data.list) // 菜单赋值 this.menusData = res.data.list this.treeLoading = false } this.treeLoading = false }) },checked这个属性也没有被监控,当我修改这个属性,显示Modal时,VUE并没有认为我修改了数据,所以没有重新渲染。为了验证我的想法。我在赋值给Tree菜单数据之前就全都添加checked属性
getPermList () { this.treeLoading = true getMenuTreeList().then(res => { if (res.message === 'success') { this.deleteDisableNode(res.data.list) this.expandNode(3, res.data.list) // 添加 checked 属性 this.checkPermTree(res.data.list, []) // 菜单赋值 this.menusData = res.data.list this.treeLoading = false } this.treeLoading = false }) },当然为了不干扰,需要把深度拷贝干掉,如下
editPerm (v) { this.permModalVisible = true this.editRolePermId = v.id this.modalTitle = '分配 ' + v.name + ' 的菜单权限' // 匹配勾选 let rolePerms = [] // 对象深度拷贝,否则 // let allMenus = JSON.parse(JSON.stringify(this.menusData)) rolePerms = v.role_menus this.editRole = v if (this.treeLoading) { this.$Message.warning('菜单权限数据加载中,请稍后点击查看') return } // 递归判断子节点 this.checkPermTree(this.menusData, rolePerms) this.expandNode(this.expandLevel, allMenus) // 重新赋值回去 // this.menusData = allMenus // },然后再次尝试,结果也是可以自动刷新渲染的