前端工作总结112-结构 vue操作一个很有意思的报错 [Vue warn]: You may have an infinite update loop in a component

结构

vue操作一个很有意思的报错

[Vue warn]: You may have an infinite update loop in a component render function. 

代码:

    <template>
           <span class="show-filters" :class="show = !show">
                    {{ show ? '隐藏过滤器 ↑' :'显示过滤器 ↓' }}
         </span>
    </template>
     <script>       
        export default {
              data() {
                return {
                      show: true
                    }
               }
          };
      </script>

分析

问题的本质

    NOTE: render method is triggered whenever any state changes

即任何时候vue实例状态的改变都会触发渲染方法的执行

    组件初始化时,将数据属性show值为true
    当渲染方法执行,内联表达式show = !show改变了状态
    响应状态show改变,重新执行render方法,企图生成新的VNode节点(以便生成真实节点插入页面)
    于是产生的局面会无尽循环这样:render - show改变 - render 重复执行步骤2-3-2

v-for

类似同样的报错,还很有可能在v-for指令中产生,如下

    <div v-for="item in model.items" v-bind:class="test(item.result)">
    {{item.id}}
    </div>

vue部分

    data() {
        return {
            accept: false,
            not_accept: false,
        };
    },
    methods: {
        test(result) {
            if (result == 'accept') {
                this.accept = true;
                this.not_accept = false;
            } else if (result == 'Not accept') {
                this.accept = false;
                this.not_accept = true;
            } else {
                console.log(result);
            }
     
            return {
                success: this.accept,
                danger: this.not_accept,
            };
        },
    },

    也会出现如题报错,其原因是在for循环中 (render - test - render )间接修改了data响应数据而且没有终止条件。但是记住状态的改变会导致渲染方法的执行,上述两种情况的相同点在于,执行渲染时,又会改变状态,于是又渲染,迟迟不能生成真实节点,不休了。

解决方案

对同一依赖响应数据属性在同一实例的生命周期内只作一次变更。
比如:对示例一,将属性绑定改为vue事件绑定,事件是在下一次tick执行渲染
对于示例二,for指令通常只用来读取数据,而非写入响应数据。如需写入数据,无论直接还是间接操作都不要改变响应数据,如下所示:

    methods: {
        test(result) {
            let accept;
            if (result == 'accept') {
                accept = true;
            } else if (result == 'Not accept') {
                accept = false;
            } else {
                console.log(result);
            }
     
            return {
                success: accept,
                danger: !accept,
            };
        },
    }

小结

    慎用内联表达式,对于自定义vue属性而言,它会被渲染器自执行,上述两个小错误同样报错便如此
    尽可能用事件改变状态 ,驱动页面渲染重绘
 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值