vue学习——computed&watch

这一章主要整理一下vue中computed(计算属性)和watch(监听属性)的用法。

1.computed

computed主要的做的是元数据进行加工返回一个新的数据。

案例一、现在data中有firstName 和lastName两个值,显示全名

解决方法一:{{firstName + ' ' +  lastName}}

            这是最简单的方法,在计算的数据量比较少的时候可以采用。

解决方法二:computed

    var vm = new Vue({
        el: "#app",
        template: `
            <div>
                <p>name : {{name}}</p>
            </div>
            `,
        data: {
            firstName: "zhu",
            lastName: "Ming"
        },
        computed: {
            name() {
                return `${this.firstName} ${this.lastName}`;
            }
        },
    })

解决方法三:methods

    var vm = new Vue({
        el: "#app",
        template: `
            <div>
                <p>name : {{getName()}}</p>
            </div>
            `,
        data: {
            firstName: "zhu",
            lastName: "Ming"
        },
        methods: {
            getName() {
                return `${this.firstName} ${this.lastName}`;
            }
        },
    })

可以看到其实方案二和方案三都实现的要求,但是推荐使用方案二,原因主要是:computed只有再依赖的数据发生改变的时候才会重新计算(缓存机制),而methods在任意数据改变的时候都会重新去计算。

测试案例:

    var vm = new Vue({
        el: "#app",
        template: `
            <div>
                <p>name1 : {{name}}</p>
                <p>name2 : {{getName()}}</p>
                <p>number: <input type="text" v-model='number' /> </p>
            </div>
            `,
        data: {
            firstName: "zhu",
            lastName: "Ming",
            number: 0
        },
        computed: {
            name() {
                console.log('recalculate computed')
                return `${this.firstName} ${this.lastName}`;
            }
        },
        methods: {
            getName() {
                console.log('recalculate methods')
                return `${this.firstName} ${this.lastName}`;
            }
        },
    })

输出结果(当在input框中不断改变number的值)

 

可以发现,这时候每次number的值改变都会触发methods中的getName()方法。 

computed执行setter操作(不推荐,但是有computed有这个功能)

案例二、输入全名,然后依据输入的全名改变data中的firstName和lastName。

    var vm = new Vue({
        el: "#app",
        template: `
            <div>
                <p>firstName : {{firstName}}</p>
                <p>lastName : {{lastName}}</p>
                <p>name : <input type="text" v-model='name' /> </p>
            </div>
            `,
        data: {
            firstName: "zhu",
            lastName: "Ming",
            number: 0
        },
        computed: {
            name: {
                get() {
                    console.log('recalculate computed')
                    return `${this.firstName} ${this.lastName}`;
                },
                set(name) {
                    const names = name.split(' ');
                    this.firstName = names[0];
                    this.lastName = names[1];
                }
            }
        }
    })

改变输入框中的name,得到输出结果:

2.watch

watch是监听一个值的变化,然后进行一系列的操作。

案例三、还是上面的例子用watch也能实现(比较麻烦,需要监听firstName和lastName两个值的变化,不推荐,这里只是作为一个例子)。

    var vm = new Vue({
        el: "#app",
        template: `
            <div>
                <p>firstName : <input type='text' v-model='firstName' /></p>
                <p>lastName : <input type='text' v-model='lastName' /> </p>
                <p>fullName : {{fullName}}</p>
            </div>
            `,
        data: {
            firstName: "zhu",
            lastName: "Ming",
            fullName: ''
        },
        watch: {
            firstName(newValue, oldValue) {
                this.fullName = newValue + ' ' + this.lastName;
            }
        }
    })

输出结果:

可以看出刚开始fullName是空的,这是因为第一次刚渲染完成的时候watch默认是不执行的,改变下firstName输出结果:

 这样就看到了我们想要的结果,那如果要求第一次渲染的时候就要执行watch,方法如下:

    var vm = new Vue({
        el: "#app",
        template: `
            <div>
                <p>firstName : <input type='text' v-model='firstName' /></p>
                <p>lastName : <input type='text' v-model='lastName' /> </p>
                <p>fullName : {{fullName}}</p>
            </div>
            `,
        data: {
            firstName: "zhu",
            lastName: "Ming",
            fullName: ''
        },
        watch: {
            firstName: {
                handler(newValue, oldValue) {
                    this.fullName = newValue + ' ' + this.lastName;
                },
                immediate: true  //即时,即立刻执行的意思。
            }
        }
    })

这样我们就可以得到第一次渲染的时候 watach方法也执行了 结果:

和上例中的immediate一样,还有设置deep参数

deep表示监听深度监听

案例四、在data中有一个obj对象,需要监听obj.a的变化

    var vm = new Vue({
        el: "#app",
        template: `
            <div>
                <p>obj.a : <input type='text' v-model='obj.a' /></p>
                <p>obj.b : <input type='text' v-model='obj.b' /></p>
            </div>
            `,
        data: {
            obj: {
                a: 0,
                b: 'a'
            }
        },
        watch: {
            obj: {
                handler(newValue, oldValue) {
                    console.log('watch obj.a changed')
                },
                immediate: false  //即时,即立刻执行的意思。
            }
        }
    })

可以看到上例监听了obj的变化,但是obj.a进行改变的时候,输出结果:

说明并没有执行watch下面监听的函数,这时候上deep:true,再次进行测试,输出结果:

但是,我们继续改变obj.b的值,发现监听又再次触发了,其输出结果:

这个说明,一旦加了deep:true的属性之后,vue会遍历监听的obj下面说有值,但其实我们只想要监听obj.a,而且这样效率也低下,再次修改:只需要将监听的obj改成'obj.a'即可

    var vm = new Vue({
        el: "#app",
        template: `
            <div>
                <p>obj.a : <input type='text' v-model='obj.a' /></p>
                <p>obj.b : <input type='text' v-model='obj.b' /></p>
            </div>
            `,
        data: {
            obj: {
                a: 0,
                b: 'a'
            }
        },
        watch: {
            'obj.a': {
                handler(newValue, oldValue) {
                    console.log('watch obj.a changed')
                },
                immediate: false,  //即时,即立刻执行的意思。
                deep: false
            }
        }
    })

改过之后发现及时deep为false,但是修改obj.a的时候能正常触发监听,改变obj.b的时候无法触发监听。

案例四、当在watch的中改变被监听的值。

可以试想一下,如果监听obj.a,你又在监听触发的方法中改变了obj.a的会造成什么后果。

ok,这想必大家都知道,那就是死循环,所以千万不要用。

    var vm = new Vue({
        el: "#app",
        template: `
            <div>
                <p>obj.a : <input type='text' v-model='obj.a' /></p>
                <p>obj.b : <input type='text' v-model='obj.b' /></p>
            </div>
            `,
        data: {
            obj: {
                a: 0,
                b: 'a'
            }
        },
        watch: {
            'obj.a': {
                handler(newValue, oldValue) {
                    this.obj.a += 1;
                    console.log('watch obj.a changed')
                },
                immediate: false,  //即时,即立刻执行的意思。
                deep: false
            }
        }
    })

稍稍改变一下a的值,可以看到结果: 

上图结果obj.a的值还为0是因为,浏览器直接卡崩了。好了,所以千万不要在watch监听中去改变本身。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值