el-tree踩坑总结:
今天有个需求要在子组件中(弹窗中写一个el-tree)因为要做回显,也就是一点进去就有上一次勾选过的。
通过查看文档,觉得用setCheckedNodes最合适,然后在点进来就展示,我的第一反应就是在挂载的时候调用以下办法
setCheckedNodes() {
this.$nextTick(() => {
this.$refs.tree.setCheckedNodes(this.selectedAssign);
});
},
报错写法:
(弹窗子组件)
<template>
<div class="dialog">
<el-dialog
title="权限分配"
:visible.sync="dialogVisible"
width="45%"
top="8vh"
ref="tk"
:before-close="dialogClose"
>
<div class="dialog-mid">
<div class="online-detail">
<div class="od-content">
<div class="select-box">
<div class="all-select">
<div class="all-tit"><span></span></div>
<div class="all-con">
<el-tree
:data="assignData"
show-checkbox
default-expand-all
node-key="id"
ref="tree"
:highlight-current="true"
:props="defaultProps"
@check-change="checkChange"
>
</el-tree>
</div>
</div>
</div>
</div>
</div>
<div class="foot-botton">
<el-button type="primary" @click="open">提交修改</el-button>
<el-button @click="dialogClose">取消</el-button>
</div>
</div>
</el-dialog>
</div>
</template>
<script>
export default {
props: ["dialogVisible"],
data() {
return {
assignData: [ //树的数据
{
id: 1,
label: "1",
children: [
{
id: 101,
label: "101",
},
{
id: 102,
label: "102",
},
],
},
{
id: 2,
label: "2",
children: [
{
id: 201,
label: "201",
},
{
id: 202,
label: "202",
},
{
id: 203,
label: "203",
},
{
id: 204,
label: "204",
},
{
id: 205,
label: "205",
},
],
},
{
id: 3,
label: "3",
children: [
{
id: 301,
label: "301",
},
],
},
],
defaultProps: {
children: "children",
label: "label",
},
selectedAssigns: [ //模仿点进弹窗的起始数据
{
id: 1,
label: "1"
},
{
id: 101,
label: "101",
},
{
id: 102,
label: "102",
},
],
};
},
methods: {
dialogSure() {
this.$emit("dialogSure");
},
dialogClose() {
this.$parent.dialogClose();
},
open() {
this.$confirm("此操作将改变该用户权限, 是否继续?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
// this.dialogVisible = false;
this.dialogSure();
})
.catch(() => {
this.$message({
type: "info",
message: "已取消修改",
});
});
},
setCheckedNodes() {
this.$nextTick(() => {
console.log(this.$refs.tree,"this.$refs.tree");
this.$refs.tree.setCheckedNodes(this.selectedAssigns);
});
},
resetChecked() {
this.$refs.tree.setCheckedKeys([]);
},
},
mounted() {
// 设置屏幕高度90%
this.$refs.tk.$el.firstChild.style.height = "70%";
this.setCheckedNodes(); // 准备在弹窗挂载的时候调用就可以点进去就有回显,但是出现了报错,148打印出来的结果是undefined
//this.$nextTick(() => { // 上网查询一下别人的写法,说要用this.$nextTick写在挂载的时候。
// this.setCheckedNodes();
// });
},
};
</script>
<style scoped>
</style>
以为这样准备在弹窗挂载的时候调用就可以点进去就有回显,但是出现了报错,148打印出来的结果是undefined。
报错信息如图:
看到这样的报错经验告诉我是在执行这个方法的时候弹窗的DOM还没创建完成,找不到这个tree,但是很奇怪我明明在这个方法中写了this.$nextTick(this.$nextTick这个函数可以使里面的方法在DOM完成创建以后才运行),并且有什么操作都是在this.$nextTick里面执行的。
上网查询一下别人的写法,说要用this.$nextTick写在挂载的时候。然后就有了挂载中注释掉的那一段代码,但是这样写了仍然报错,报一样的错。
就猜想这个弹窗的DOM是在点击打开这个弹窗以后才开始创建,所以我就在父组件中打开弹窗的方法中this.dialogVisible = true;之后去调用这个setCheckedNodes方法
如何调用呢,父组件调用子组件的方法有个很简单的写法,就是在子组件上给一个 ref="dialog"
如:
<Dialog :dialogVisible="dialogVisible" @dialogSure="dialogSure" ref="dialog"></Dialog>
然后在打开这个弹窗的方法中去调用子组件的那个方法://selectedAssign是起始数组,可以由父组件中传过去
handleAssign(row,selectedAssign) {
//selectedAssign是起始数组,可以由父组件中传过去
this.dialogVisible = true;
this.$refs.dialog.setCheckedNodes(selectedAssign);
},
最后再保存刷新重新运行就不会有报错了,也有起始数据了。