javascript - Vue $watch 死循环问题

查看:194
本文介绍了javascript - Vue $watch 死循环问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问 题

如果watch中的两个data变量相互调用了,会发生死循环。

watch:{
    'a':{
        handler:function(val,oldVal){
            if(this.b == 0){
                this.b = 1;
            }else{
                this.b = 0;
            }
        },
        deep:true
    },
    'b':{
        handler:function(val,oldVal){
            if(this.a == 0){
                this.a = 1;
            }else{
                this.a = 0;
            }
        },
        deep:true
    },
}

类似于这样,监听当a改变了去改变b,监听当b改变了去改变a
这样的话a和b会一直死循环下去,是在写全选、反选的时候遇到这个问题,当用户勾选全选后,再取消勾选一个条目,全选也会相对应取消勾选,这样就一直死循环下去了。
vue提供了相关的api解决这个问题吗?我在官网没有找到。

解决方案

谢邀。
虽然不知道你的实际开发需求是什么?但是你的程序在逻辑上就是你自己分析的死循环。
watch是监控对象属性值的变化,即是你的a, b对应的值的变化了会回调触发这个监控函数下对应的键名表达式函数,函数会传入两个参数,一个是变化后的值,一个是变化前的值。
如何解决这个问题?
其实我也没想到好的办法,脑海里面一直是个死循环。要么就是数据单向,输入事件触发,但当前值的变化与否对实际结果不影响。a的变化结果不关心,只是关心它变化了会触发b。但是下一次a怎么判断它的变化又是问题了。

还有一种就是固定判断零点值,b = 0b = 1两个极端条件,同理a也一样。

a: function() {
    this.b == this.b == 0 ? 1 : (this.b == 1 ? 0 : 1);
}

前提条件是:a不能等于0或者1,否则又会触发死循环


更新:

实现全选功能

    <div id="app">
        <ol>
            <li>
                <span><input type="checkbox" v-model="selectAll"></th></span>
                <span align="left">全选</span>
            </li>
            <li v-for="answer in answers">
                <span>
                    <input type="checkbox" v-model="selected" :value="answer.id" >
                </span>
                <span>{{ answer.name }}</span>
            </li>
        </ol>
    </div>
    <script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.0.5/vue.js"></script>
    <script>
        new Vue({
            el: '#app',
            data: {
                answers: [ 
                    { "id": 1, "name": "A" },
                    { "id": 2, "name": "B" }, 
                    { "id": 3, "name": "C" }, 
                    { "id": 4, "name": "D" }
                ],
                selected: []
            },
            computed: {
                selectAll: {
                    get: function () {
                        return this.answers ? this.selected.length == this.answers.length : false;
                    },
                    set: function (value) {
                        var selected = [];

                        if (value) {
                            this.answers.forEach(function (user) {
                                selected.push(user.id);
                            });
                        }

                        this.selected = selected;
                    }
                }
            }
        });
    </script>

这篇关于javascript - Vue $watch 死循环问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆