问题???
需要在点击编辑的时候打开弹窗,回显当前这行的具体信息,这里会遇到勾选回显的时候,明显有渲染过程,会比其他的回显慢上半拍
具体代码如下
1.我有一个按钮控制该行的编辑
<el-button v-if="checkPermission(scope.row.roleType)" size="mini" type="text" icon="el-icon-edit"
@click="handleUpdate(scope.row)">编辑</el-button>
2.同时有一个弹窗
<!-- 添加或修改角色配置对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body :close-on-click-modal="false">
<el-form>
<el-form-item label="菜单组件权限" prop="components">
<el-tree class="tree-border" :data="processedMenuOptions" show-checkbox ref="tree" node-key="id"
empty-text="加载中,请稍候" :props="defaultMenuProps" @check="handleCheck" default-expand-all
:default-checked-keys="defaultCheckedKeys">
<template v-slot="{ node, data }">
<span :style="getNodeStyle(node, data)" :class="data.type == 'comp' ? 'levelname' : ''">
{{ data.menuTitle }}
<el-button type="primary" size="mini"
style="position: absolute; right:12px;margin-top: 8px;height: 26px;" v-if="data.type == 'menu'"
@click.stop="toggleSubMenuSelection(data)" :disabled="!data.isButton">
全选/反选</el-button>
</span>
</template>
</el-tree>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm">确 定</el-button>
<el-button @click="cancel">取 消</el-button>
</div>
</el-dialog>
3.具体方法
/** 编辑按钮操作 */
handleUpdate(row) {
this.reset();
const roleId = row.id;
getRole({ id: roleId }).then(res => {
if (res.success) {
this.open = true;
this.form = res.data;
this.title = "修改角色";
// 递归清除 isButton 属性
this.processedMenuOptions.forEach(node => {
this.clearIsButtonRecursive(node);
});
const processedComponents = this.form.components.map(componentId => 'comp_' + componentId);
const allProcessedNodeIds = processedComponents.concat(this.form.menus);
// this.defaultCheckedKeys = deepClone(allProcessedNodeIds)
// 在数据加载完成后再设置选中节点
this.$nextTick(() => {
allProcessedNodeIds.forEach(id => {
this.$refs.tree.setChecked(id, true, false);
});
this.changeCss()
this.getMenuAllCheckedKeys() //要放在最后,否则容易出现数据未加载就执行问题
});
}
});
},
// 修改样式
changeCss() {
// levelname是上面的最底层节点的名字
var levelName = document.getElementsByClassName('levelname');
// console.log(levelName, 'levelName');
if (levelName.length > 0) {
for (var i = 0; i < levelName.length; i++) {
levelName[i].parentNode.style.cssFloat = 'left';
levelName[i].parentNode.style.styleFloat = 'left';
levelName[i].parentNode.style.paddingLeft = '0px'
levelName[i].parentNode.style.paddingRight = '10px'
levelName[i].parentNode.style.marginLeft = '54px'
}
}
},
// 获取所有被选中的节点的key并且给选中的新增isButton属性
getMenuAllCheckedKeys() {
// 目前被选中的节点
let checkedKeys = this.$refs.tree.getCheckedKeys();
// 半选中的节点
let halfCheckedKeys = this.$refs.tree.getHalfCheckedKeys();
checkedKeys.unshift.apply(checkedKeys, halfCheckedKeys)
let checkedMenuKeys = checkedKeys.filter(nodeId => typeof nodeId !== 'string' || !nodeId.startsWith('comp_'))
let checkedCompKeys = checkedKeys.filter(nodeId => typeof nodeId === 'string' && nodeId.startsWith('comp_'));
// 递归更新 isButton 属性
const updateIsButton = (node) => {
if (checkedMenuKeys.includes(node.id)) {
this.$set(node, 'isButton', true);
} else {
this.$delete(node, 'isButton');
}
if (node.children) {
node.children.forEach(child => {
updateIsButton(child);
});
}
};
this.processedMenuOptions.forEach(node => {
updateIsButton(node);
});
return {
menuKeys: checkedMenuKeys,
compKeys: checkedCompKeys
};
},
/** 查询菜单树和组件树结构 */
getMenuComptTreeselect() {
listComponent().then(res => {
if (res.success) {
this.menuOptions = res.data.menus.map(menu => ({
...menu,
type: 'menu'
}));;
this.componentsOptions = res.data.components.map(component => ({
...component,
menuTitle: component.componentName,
type: 'comp',
id: 'comp_' + component.id, // 添加前缀
}))
const menu = { id: 'root', menuTitle: '全部', children: [...deepClone(this.menuOptions)], type: 'menu' };
this.$nextTick(() => {
this.changeCss()
})
// 创建新的数组来存储处理后的菜单数据,不修改原始数据
this.processedMenuOptions = deepClone([menu])
// 递归遍历菜单树,将匹配的组件数据作为子集添加到菜单中
for (let menu of this.processedMenuOptions) {
this.updateComponents(menu);
}
}
})
},
// 递归函数,用于处理多层嵌套的菜单树
updateComponents(menu) {
const children = menu.children;
menu.type = 'menu'; // 设置当前节点的类型为菜单
if (children && children.length > 0) {
for (let child of children) {
this.updateComponents(child);
}
} else {
const menuId = menu.id;
const matchedComponents = this.componentsOptions.filter(component => component.menuId === menuId);
menu.children = matchedComponents;
}
},
4. 页面展示
5.视频展示效果
选中回显慢半拍的问题