Javascript 阵列上未检测到Vue更改

Javascript 阵列上未检测到Vue更改,javascript,vue.js,vuejs2,Javascript,Vue.js,Vuejs2,大家好,我正在使用Vue,我正在尝试从平面列表中创建递归树,我想在有人单击每个项时调整它的扩展属性,但由于某些原因,它并没有改变 它发生在这个函数中 expandNode(item) { console.log("HERERERER"); item.expand = false; this.$set(item, "expand", false); } 我希望我的阵列是被动的,但由于某些原因,它不是,这可能是我重新打包数据的方式还是其他方式,有人可

大家好,我正在使用Vue,我正在尝试从平面列表中创建递归树,我想在有人单击每个项时调整它的扩展属性,但由于某些原因,它并没有改变

它发生在这个函数中

  expandNode(item) {
      console.log("HERERERER");
      item.expand = false;
      this.$set(item, "expand", false);
    }
我希望我的阵列是被动的,但由于某些原因,它不是,这可能是我重新打包数据的方式还是其他方式,有人可以看一下吗

这是我的代码沙盒

这是组件代码

<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
    <tr v-for="(item ,index)  in flatArray" :key="index">
      <div class="item" @click="expandNode(item)">
        <div class="element" v-show="item.expand">
          {{ item.expand }}
          <span>{{ item.label }}</span>
        </div>
      </div>
    </tr>
  </div>
</template>

<script>
export default {
  name: "HelloWorld",
  props: {
    msg: String,
    data: { default: () => null, type: Array }
  },
  data() {
    return {
      flatArray: []
    };
  },
  mounted() {
    let arr = [];
    console.log("HERERER");
    this.recursive(this.data, arr, 0, null, -1);
    this.flatArray = arr;
    console.log(this.flatArray);
  },
  computed: {
    setPadding(item) {
      return `padding-left: ${item.level * 30}px;`;
    }
  },
  methods: {
    recursive(obj, newObj, level, parent, parentIndex) {
      obj.forEach(node => {
        if (node.children && node.children.length != 0) {
          node.level = level;
          node.leaf = false;
          node.expand = true;
          node.parent = parent;
          node.parentIndex = parent ? parentIndex : null;
          newObj.push(node);
          this.recursive(
            node.children,
            newObj,
            node.level + 1,
            node,
            newObj.indexOf(node)
          );
        } else {
          node.level = level;
          node.leaf = true;
          node.expand = true;
          node.parent = obj;
          node.parentIndex = parent ? parentIndex : null;
          newObj.push(node);
          return false;
        }
      });
    },
    expandNode(item) {
      console.log("HERERERER");
      item.expand = false;
      this.$set(item, "expand", false);
    }
  }
};
</script>

{{msg}}
{{item.expand}
{{item.label}
导出默认值{
名称:“HelloWorld”,
道具:{
msg:String,
数据:{default:()=>null,类型:Array}
},
数据(){
返回{
平面阵列:[]
};
},
安装的(){
设arr=[];
控制台日志(“HERERER”);
this.recursive(this.data,arr,0,null,-1);
this.flatraray=arr;
console.log(this.flatraray);
},
计算:{
设置填充(项目){
返回`padding left:${item.level*30}px;`;
}
},
方法:{
递归(对象、新对象、级别、父级、父索引){
对象forEach(节点=>{
if(node.children&&node.children.length!=0){
node.level=级别;
node.leaf=false;
node.expand=true;
node.parent=父节点;
node.parentIndex=parent?parentIndex:null;
newObj.push(节点);
这是递归的(
node.children,
newObj,
node.level+1,
节点,
newObj.indexOf(节点)
);
}否则{
node.level=级别;
node.leaf=true;
node.expand=true;
node.parent=obj;
node.parentIndex=parent?parentIndex:null;
newObj.push(节点);
返回false;
}
});
},
扩展节点(项目){
控制台日志(“Hererer”);
item.expand=false;
此.$set(项目“展开”,false);
}
}
};

如果
对象没有初始的
展开
属性,则必须使用
此。$set(项,…)
将其声明为可观察

直接添加新属性,如
item.expand=…
跳过此步骤,而
this.$set将忽略它。这种性质不会是反应性的


这里有更多信息:

如果
item
对象没有初始
expand
属性,则必须使用
this.$set(item,…)
将其声明为可观察

直接添加新属性,如
item.expand=…
跳过此步骤,而
this.$set将忽略它。这种性质不会是反应性的


这里有更多信息:

您没有看到更新的原因是数组没有重新计算的理由。您正在更新此。$set(项“展开”,false)非反应性对象。它不是被动的原因是,在创建对象时没有使用
$set
方法

以下是在对象创建过程中正确使用
$set
时的效果

递归(对象、新对象、级别、父级、父级索引){ 对象forEach(节点=>{ 此.$set(节点,“级别”,级别); 此.$set(节点“展开”,true); 此.$set(节点“parentIndex”,parent?parentIndex:null); if(node.children&&node.children.length!==0){ 此.$set(节点“叶”,false); 此.$set(节点,“父节点”,父节点); newObj.push(节点); 这是递归的( node.children, newObj, node.level+1, 节点, newObj.indexOf(节点) ); }否则{ 此.$set(节点“叶”,true); 该.$set(节点,“父节点”,obj); newObj.push(节点); 返回false; } }); },
请注意,现在可以使用
item.expand=false

expandNode(项目){
item.expand=false;
//此.$set(项目“展开”,false){
常数flatTreeArr=[];
设深度=0;
常数展平=(节点,父节点)=>{
扁平耳推(节点);
node.level=深度;
node.leaf=true;
node.parent=父节点;
node.expand=node.expand==未定义?true:node.expand;
if(节点子节点){
node.leaf=false;
if(node.expand){
深度++;
node.children.forEach(br=>flatten(br,node));
深度--;
}
}
};
对象forEach(br=>flatten(br,null));
返回扁平耳环;
};
导出默认值{
道具:{
数据:{default:()=>null,类型:Array}
},
数据(){
返回{
平面阵列:[]
};
},
安装的(){
this.flatArray=flattree(this.data);
},
方法:{
切换ExpandNode(项目){
item.expand=!item.expand;
this.flatArray=flattree(this.data);
}
}
};

查看它的运行情况

您没有看到更新的原因是数组没有重新计算的理由。您正在更新此。$set(项,“expand”,false);
一个非反应性对象。它不是反应性对象的原因是您在创建对象时没有使用
$set
方法

以下是在对象创建过程中正确使用
$set
时的效果

递归(对象、新对象、级别、父级、父级索引){ 对象forEach(节点=>{ 此.$set(节点,“级别”,级别); 此.$set(节点“展开”,true); 此.$set(节点“parentIndex”,parent?parentIndex:null); if(node.children&&node.children.length!==0){ 此.$set(节点“叶”,false); 此.$set(节点,“父节点”,父节点); newObj.push(节点); 这是递归的( node.children, newObj, node.level+1, 节点, newObj.indexOf(节点) ); }否则{
<template>
  <div class="hello">
    <tr v-for="(item ,index) in flatArray" :key="index">
      <div
        @click="toggleExpandNode(item)"
        class="item"
        :style="{'margin-left':item.level * 1.6 +'em'}"
      >
        <div class="element">
          <span v-if="item.leaf">&#9900;</span>
          <span v-else-if="item.expand">&#9662;</span>
          <span v-else>&#9656;</span>
          &nbsp;
          <span>{{ item.label }}</span>
        </div>
      </div>
    </tr>
  </div>
</template>

<script>
const flattenTree = obj => {
  const flatTreeArr = [];
  let depth = 0;

  const flatten = (node, parentNode) => {
    flatTreeArr.push(node);
    node.level = depth;
    node.leaf = true;
    node.parent = parentNode;
    node.expand = node.expand === undefined ? true : node.expand;
    if (node.children) {
      node.leaf = false;
      if (node.expand) {
        depth++;
        node.children.forEach(br => flatten(br, node));
        depth--;
      }
    }
  };

  obj.forEach(br => flatten(br, null));
  return flatTreeArr;
};

export default {
  props: {
    data: { default: () => null, type: Array }
  },
  data() {
    return {
      flatArray: []
    };
  },
  mounted() {
    this.flatArray = flattenTree(this.data);
  },
  methods: {
    toggleExpandNode(item) {
      item.expand = !item.expand;
      this.flatArray = flattenTree(this.data);
    }
  }
};
</script>