Vue 中 computed和watch的区别

1、 computed 计算属性

1.1 computed使用

计算属性基于 data 中声明过或者父组件传递的 props 中的数据通过计算得到的一个新值,这个新值会根据已知值的变化而变化

简言之:这个属性依赖其他属性,由其他属性计算而来的

new Vue({
    el: '#id',
    template: `<div>
        <span>Name: {{fullName}}<span>
    </div>`,
    data: {
        firstName: 'Leo',
        lastName: 'Alan'
    },
    computed: {
        fullName () {
            return `${this.firstName} + ${this.lastName}`
        }
    }
})

computed 属性对象中 定义计算属性 的方法,和取data对象里的数据属性一样以属性访问的形式调用,即在页面中使用 {{ 方法名 }} 来显示计算的结果

注:

计算属性 fullName 不能在 data 中定义,而计算属性值的相关已知值在data中

如果 fullName 在 data 中定义了会报错如下图:

在这里插入图片描述
因为如果 computed 属性值是一个函数,那么默认会走 get 方法,必须要有一个返回值,函数的返回值就是属性的属性值。计算属性定义了 fullName 并返回对应的结果给这个变量,变量不可被重复定义和赋值

1.2 computed 带有缓存功能

计算结果并返回,只有当被计算的值发生改变时才会触发
(即:计算属性的结果会被缓存,除非依赖的响应式属性变化才会重新计算)

new Vue({
    el: '#id',
    template: `<div>
        <span>Name: {{fullName}}<span>
        <span>Name: {{fullName}}<span>
        <span>Name: {{fullName}}<span>
    </div>`,
    data: {
        firstName: 'Leo',
        lastName: 'Alan'
    },
    computed: {
        fullName () {
            console.log('computed') // 在控制台只打印了一次
            return `${this.firstName} + ${this.lastName}`
        }
    }
})

1.3 computed 数据的显示和监视

computed 中的属性都有一个 get 和一个 set 方法**,当数据变化时,调用 set 方法**。下面我们通过计算属性的 getter/setter 方法来实现对属性数据的显示和监视,即双向绑定

computed: {
    fullName: {
        get() { //读取当前属性值的回调,根据相关的数据计算并返回当前属性的值
            return this.firstName + ' ' + this.lastName
        },
        set(val) { // 当属性值发生改变时回调,更新相关的属性数据,val就是fullName的最新属性值
            const names = val ? val.split(' ') : [];
            this.firstName = names[0]
            this.lastName = names[1]
        }
    }
}

2、watch 监听属性

new Vue({
    el: '#id',
    template: `<div>
        // ...
    </div>`,
    data: {
        firstName: 'Leo',
        lastName: 'Alan',
        obj1: {
            a: 0
        }
    },
    watch: {
        // 监听firstName,当firstName发生变化时就会执行该函数
        firstName () {
            // 执行需要的操作...
            // 注:初始化不会执行,只有当被监听的值(firstName)发生变化时才会执行
        },

        // 监听lastName
        lastName: {
            handler (newName, oldName) {
                // 执行需要的操作...
            },
            immediate: true // true: 初始化时就会先执行一遍该监听对应的操作    
        },

        obj1: {
            handler () {
                // 执行需要的操作...
            },
            deep: true // 该属性默认值为false. 
            // 当被监听的值是对象,只有deep为true时,对应属性的值(obj1.a)发生变化时才能触发监听事件,但是这样非常消耗性能
        },

        // 监听对象具体的属性, deep就不需要设置为true了
        'obj1.a': {
            handler () {
                // 执行需要的操作...
            }
        }

    }
})

注意事项:

  • watch 中的函数名称必须是所依赖 data 中的属性名称

  • watch 中的函数是不需要调用的,只要函数所依赖的属性发生了改变 那么相对应的函数就会执行;

  • watch 中的函数会有2个参数 一个是新值,一个是旧值

  • watch 默认情况下无法监听对象的改变,如果需要进行监听则需要进行深度监听 深度监听需要配置 handler(vue2中才需要) 函数以及 deep 为true。(因为它只会监听对象的地址是否发生了改变,而值是不会监听的);

  • watch 默认情况下第一次的时候不会去做监听,如果需要在第一次加载的时候也需要去做监听的话需要设置 immediate:true

3、总结

3.1 功能上:

  • computed 是计算属性,也就是依赖其它的属性计算所得出最后的值。
  • watch 是去监听一个值的变化,然后执行相对应的函数

3.2 使用上:

  • computed中的函数必须要用return返回(不支持异步);
  • watch的回调里面会传入监听属性的新旧值,通过这两个值可以做一些特定的操作,不是必须要用return(支持异步)

3.3 性能上:

  • computed中的函数所依赖的属性没有发生变化,那么调用当前的函数的时候会从缓存中读取( 支持缓存)
  • watch在每次监听的值发生变化的时候都会执行回调( 不支持缓存)

3.4 场景上:

  • computed:当一个属性受多个属性影响的时候,例子:购物车商品结算;
  • watch:当一条数据影响多条数据的时候,例子:搜索框
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值