其他分享
首页 > 其他分享> > Vue 2在v-for中变异数据属性会导致无限循环/问题

Vue 2在v-for中变异数据属性会导致无限循环/问题

作者:互联网

尽管我在文档中找不到,但似乎突变数据数组属性似乎不是一个好主意,即使没有将其呈现给视图也是如此.

看到这个小提琴:https://jsfiddle.net/078v5142/3/

我需要减少conditionalSet.我在每个v-for循环上使用pop()来检查索引的条件.我不能使用计算属性,因为我需要传递索引.

我也不能只复制conditionalSet数组,因为在设置和弹出条件时需要对其进行跟踪.

这是我面临的一个大大简化的问题.

new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue.js! I do not like loops, all that much.',
    imageSet: [
     'a','b','c','d','e','f','g', 'h', 'i', 'j'
    ],
    conditionalSet: [1,2]
  },
  methods: {
    doShow(index){
     if(this.someInnerConditionThatsNotRenderedOut()){
       if( index === 1 || index === 4 || index === 5 || index === 6){
         this.conditionalSet.pop(); // <-- this is the problem, but how to I track?
         return true;
       }
     }
     console.log('I should no show index 5 and index 6')
    },
    someInnerConditionThatsNotRenderedOut(){
     return true //comment this out. No error.
     return this.conditionalSet.length > 0
    }
  }
})

解决方法:

简短的答案

简而言之,我认为您可以(并且应该)使用计算属性来显示过滤列表.我不是100%清楚您在示例中要实现的目标,但是希望这个小提琴能为您提供一个指针:https://jsfiddle.net/dtchqpjd/如果您在控制台运行时查看它,您将能够看到逻辑的结果.

更长的答案

该问题实际上是由以下三点引起的:

> doShow函数具有副作用.
>副作用与VueJS“监视”的数据属性有关.
>该数据属性是一个数组,您需要对其进行“获取”才能进行修改/弹出.

VueJS的reactivity system可以监视数据,并在数据更改时确定其对DOM的影响.这使得它可以有效地更新DOM以响应数据更改,而无需在每次更改时都完全重新创建DOM.

在这种情况下,VueJS知道以下内容:

>您将获得conditionalSet属性.您必须执行此操作才能调用pop方法.但是Vue不知道您对返回的值做了什么.
>您可以通过调用pop方法来更改conditionalSet属性.

因为您获取并设置了属性,所以VueJS假定doShow函数返回的结果是陈旧的,因此对其进行了重新评估,然后您将得到一个无限循环.它看不到您仅“获得”它是因为您想“弹出”它!

当您在计算属性内全部执行过滤和修改时,避免混淆VueJS(和无限循环),因为它可以看到结果是稳定的,不需要重新计算.由于逻辑都在一个地方,因此它也恰好是更清晰的代码.但是,您的计算属性仍然具有副作用,如果我对您要执行的操作了解更多,也许也可以避免.

一个小插图

为了说明正在发生的情况,请参见here’s a slight modification to your fiddle,在这里我对数组采用了一个单独的引用(对于Vue来说是未知的).当我使用该引用调用“ pop”时,您不会得到无限循环:Vue仍然可以看到我们已经更改了数组,但是因为我们没有“获取”它,所以它不会假定该函数的输出现在已过时.取消对只是“获取”数组的调用的注释,问题又回来了:Vue认为它需要重新评估该函数.

有趣的是,Vue似乎没有查看依赖关系的顺序:“先获取”然后“设置”还是“先设置”再“获取”都没有关系.事实是,您同时执行这两个操作都会导致循环依赖关系-它们被添加为依赖关系并导致对队列的重新评估.

注释掉return true语句可以避免无限循环,这仅仅是因为它防止了数组被连续“弹出”:一旦数组被弹出两次,您的someInnerConditionThatsNotRenderedOut函数将返回false,并消除了无限循环的可能性.

标签:vuejs2,javascript
来源: https://codeday.me/bug/20191025/1929750.html