如何解决如何使用 VUE 更新树视图
我在树组件结构管理方面遇到问题。 就像一棵树有很多节点一样,当我删除一个节点时,渲染功能会运行,但页面没有根据树数据显示正确的信息。
我在这里附上了源代码,请任何人都可以帮助我摆脱这种混乱的情况。 非常感谢。
代码示例: 这是树渲染组件,树数据在store.state.tree中定义,我这里标记为reactive,每次删除树中的一个节点,都会调用render函数,我从console.log看到('渲染')
import Node from "./Node";
import {reactive,h} from 'vue';
import store from '@/store';
export default {
name: 'Tree',components: {Node},data(){
return reactive({
tree: store.state.tree
});
},render(){
console.log('render');
let tree = this.tree;
let renderChildNodes = (node)=>{
let vnodes = [];
node.nextnodes.forEach(node => {
vnodes.push(renderChildNodes(node));
});
let vnode = h(Node,{node: node},{
default: ()=>{
return vnodes;
}
}
);
return vnode;
};
return h('ul',null,renderChildNodes(tree));
}
}
</script>
这是节点代码,我从默认插槽的道具中获取节点,并将其标记为反应式。然后我只是从 store.state.tree 中删除节点。我希望树会刷新视图,但看起来实际上删除了节点,但视图中删除的节点没有更新。
<template>
<li>
<div class="node">
{{state.node.id}}
<input v-model="state.node.msg"/>
<button @click="add(state.node)">add</button>
<button @click="del(state.node)">del</button>
</div>
<ul>
<li>
<slot :node="node"></slot>
</li>
</ul>
</li>
</template>
<script>
import {onMounted,reactive} from 'vue';
import store from '@/store';
export default {
name: 'Node',props: {
node: {
type: Object,required: true
}
},setup(props){
console.log('node setup');
const state = reactive({
node: props.node,})
onMounted(()=>{
console.log('node onMounted');
})
function add(node){
let sub_node = JSON.parse(JSON.stringify(node));
sub_node.id = node.id + "-" + (node.nextnodes.length+1);
sub_node.nextnodes = [];
node.nextnodes.push(sub_node);
}
function del(node){
findAndRemoveNode(store.state.tree,node);
console.log(store.state.tree.nextnodes);
}
return{
state,add,del
}
}
}
function findAndRemoveNode(root,target){
if(!root.nextnodes.findremove(target)){
for(let i=0; i<root.nextnodes.length; i++){
if(findAndRemoveNode(root.nextnodes[i],target))
return true;
}
}else{
console.log(`removed node:` + target.id);
return true;
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style lang="scss" scoped>
.node{
background-color: #e6e4e4;
text-align:left;
&:hover{
background-color: #c0bdbd;
}
}
li{
margin: .2em;
}
</style>
这是商店代码:
import { createStore } from 'vuex';
export default createStore({
state:{
tree: {
msg: "this is root.",nextnodes: [{
id:"1",msg: "node 1",nextnodes: []
},{
id:"2",msg: "node 2",{
id:"3",msg: "node 3",{
id:"4",msg: "node 4",{
id:"5",msg: "node 5",{
id:"6",msg: "node 6",{
id:"7",msg: "node 7",nextnodes: []
}]
}
},mutations: {},actions: {},modules: {
}
});
import { createApp } from 'vue'
import App from './App.vue'
const app = createApp(App);
app.mount('#app')
//app.config.warnHandler = () => null;
Array.prototype.findone = function(val) {
for (var i = 0; i < this.length; i++) {
// if (this[i].id == val.id) return i;
if (this[i] === val) return i;
}
return -1;
};
Array.prototype.findremove = function(val) {
var index = this.findone(val);
if (index > -1) {
this.splice(index,1);
return true;
}
return false;
};
如果我删除第二个节点, 您可以看到第 7 个节点消失了,但实际上 store.state.tree 被删除了第 2 个节点。视图不更新,只去掉最后一个节点,只反映列表大小 delete 2nd node View updated
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。