1.需求
这里有个需求就是我要修改子节点。修改之后又不能刷新整棵树,要记录当前点击的节点,如果刷新了就记不住了,想记录会比较麻烦,一般的都是不会刷新整棵树,局部刷新
我这里的需求是点击这棵树的时候发送请求获取他的子节点,把子节点添加进去,
在template中
<el-tree
class="firstTree-tree"
:data="treeData"
node-key="classCode"
highlight-current
ref="menuTree"
:props="defaultProps"
style="overflow: scroll;"
:style="{height: treeHeight + 'px'}"
@node-click="handleNodeClick"
:default-expanded-keys="defaultShowNodes" // 自动展开哪项
>
<span class="custom-tree-node" slot-scope="{ node, data }" style="width: 100%;">
<el-tooltip popper-class="" effect="dark" placement="top" v-if="data.toolshow">
<span slot="content">{{ node.label }}</span>
<span class="tree-nood">{{ node.label }}</span>
</el-tooltip>
<span v-else class="tree-nood">{{ node.label }}</span>
<span style="position: absolute;right: 0;width: 112px;" class="node-none">
<el-tooltip effect="dark" content="新增" placement="top" style="margin-left: 8px;">
<span v-if="data.validFlag==='1'">
<el-button
type="text"
size="mini"
class="purchmanager-button-add"
@click="() => parentTreeNode(node, data, '1')">
</el-button>
</span>
</el-tooltip>
<el-tooltip effect="dark" content="修改" placement="top" style="margin-left: 40px;">
<span v-if="data.validFlag==='1'">
<el-button
type="text"
size="mini"
class="purchmanager-button-edit"
@click="() => openEditWindow('2', data)">
</el-button>
</span>
</el-tooltip>
<el-tooltip effect="dark" content="停用" placement="top" style="margin-left: 32px;">
<span style="margin-right: 5px;" v-if="data.validFlag==='1'">
<el-button
type="text"
size="mini"
class="purchmanager-button-stop"
@click="() => userStop('stop', data)">
</el-button>
</span>
</el-tooltip>
<el-tooltip effect="dark" content="启用" placement="top" style="margin-left: 80px;">
<span style="margin-right: 5px;" v-if="data.validFlag==='0'">
<el-button
type="text"
size="mini"
class="purchmanager-button-use"
@click="() => userStop('use', data)">
</el-button>
</span>
</el-tooltip>
</span>
</span>
</el-tree>
在data中:
data () {
return {
defaultShowNodes: []
}
}
在methods中:
handleNodeClick (data, node) {
let _this = this
_this.params = data
_this.axios.get('xxx/xxx/xxx', {params: params}).then(function (res) {
if (res.code === '0') {
// _this.$refs['menuTree'].setCurrentKey(res.data.id);
// item.children = []
let tree = res.data.list
// 如果已经存在则不添加进去,不存在就添加子节点
tree.forEach(item => {
for (let index in data.children) {
if (item.classCode === data.children[index].classCode) {
// 如果已经存在就先删除这个子节点,在append新的这个子节点进去,达到局部刷新的效果,这有个缺点就是如果一直一直一直点的话就会看到节点被删除掉又被添加上去了,这个需要优化,正常看来是没问题的,先放着,以后看还有更好的解决方法没有
_this.$refs.menuTree.remove(data.children[index])
// data.children.splice(idnex, 1) 解决不了问题
_this.$refs.menuTree.append(item, data);
return false;
}
}
// 如果不存在直接添加
_this.$refs.menuTree.append(item, data);
// 保存当前展开的节点
let flag = false
_this.defaultShowNodes.some(item => {
if (item === data.classCode) { // 判断当前节点是否存在, 存在不做处理
flag = true
return true
}
})
if (!flag) { // 不存在则存到数组里
_this.defaultShowNodes.push(data.classCode)
}
})
}
}).catch(function () {
});
_this.doQueryTableData()
},
上面优化了一下,我不做删除操作,这样影响用户体验。还有个办法达到刷新效果。比如我们的需求是点击父节点获取子节点,会调用接口,这个就好办一些了,
1.我获取当前修改、删除的节点:
let node = this.$refs.menuTree.getNode(data) // data放当前的data对象
2.获取他的父级节点,并判断他的父级节点是数组还是对象,如果是数组,证明就是第一层,如果是对象,证明上面还有一层
if (node.parent.data.constructor === Array) {
// 是数组,最外面的,第一层做什么操作啦
} else if (node.parent.data.constructor === Object) {
// 如果是对象就点击父级,重新发送接口,达到局部更新的效果
this.handleNodeClick(node.parent.data) // 点击他的父级节点
this.$refs.menuTree.setCurrentNode(parentNode.parent.data) // 选中、高亮父级节点。
this.$refs.menuTree.remove(data) // 删掉刚刚那条数据,否则会出现修改之前和修改之后的数据
}
获取祖父节点、就是父亲的父亲:node.parent.parent.data
还有一种方法就是,不是点击父级节点调用接口的,这种方法调不调接口都适用,
let node = this.$refs.menuTree.getNode(data) // data放当前的data对象
在node.parent里面有个children[]还是childrenNodes[]的数组node.parent.children[]打印看下就成
如果数据是有唯一id标识不重复的数据。找到children[]里面操作的数据,把当前操作的数据替换掉即可,删除就删掉,修改就替换掉
假如我修改了如下图的第二级菜单,那么我就把当前操作的这条表单数据替换掉之前children[]数组里面的数据。
如果没有唯一标识获取数组重复,那就在操作这条数据之前先给个状态值,比如:
obj.matDesc = '办公耗材类'
obj.repflag = true // 要替换的状态值,加在老数据上,我点击某条数据进行操作时,就在那里加上此状态
.....
修改之后,对children[]进行循环。找到有repflag
node.parent.children.forEach(item => {
if (item.repflag) {
// 如果数据中有这个状态值,就把表单对象数据替换这条数据
item = obj // 假设obj是操作成功后的表单对象数据
}
})
2.第二个小问题
如果想清掉当前选择的节点和高亮状态,直接
this.$refs.menuTree.setCurrentNode(’’)就可以了