Vue的计算属性和监视属性

704 阅读3分钟

「这是我参与11月更文挑战的第21天,活动详情查看:2021最后一次更文挑战

计算属性

  1. 定义:要用的属性不存在,要通过已有属性计算得来。
  2. 原理:底层借助了Objcet.defineproperty方法提供的getter和setter。
  3. get函数什么时候执行? (1).初次读取时会执行一次。 (2).当依赖的数据发生改变时会被再次调用。
  4. 优势:与methods实现相比,内部有缓存机制(复用),效率更高,调试方便。计算属性是基于它的响应式依赖进行缓存的。只有在计算属性的相关响应式依赖发生改变时才会重新求值。这就意味着只要data里的相应依赖的数据没有发生改变,那个多次访问计算属性里相关的函数会立即返回之前的计算结果,而不会再次执行函数;但是如果采用计算方法,那么不管什么时候访问方法里的函数,该函数都会被调用。
  5. 备注: (1) 计算属性最终会出现在vm上,直接读取使用即可。 (2) 如果计算属性要被修改,那必须写set函数去响应修改,且set中要引起计算时依赖的数据发生改变。
// 完整形式
fullName:{
    // get有什么作用?当有人读取fullname时,get就会被调用,且返回值就作为fullname的值
    // get什么时候被调用?1.初次读取fullname时 2.所依赖的数据发生变化时
    get(){
        console.log('get被调用了')
        return this.firstName+'-'+this.lastName
    },
    // set什么时候被调用?当fullname被修改时
    set(value){
        const arr = value.split('-')
        this.firstName = arr[0]
        this.lastName = arr[1]    
    }
}

计算属性的完整写法如上,一个属性有get,set两种方法,当有人读取fullname时,get就会被调用,且返回值就作为fullname的值,当计算属性所依赖的数据发生变化时get也会调用。set的调用,一般发生在fullname被修改时。计算属性也可以简写,如下,但这样不能修改计算属性,而且简写不能配置其他属性,比如immediate,deep

// 简写,只读不写
    fullName(){
        return this.firstName+'-'+this.lastName
    }

监视属性

监视属性watch:

  1. 当被监视的属性变化时, 回调函数自动调用, 进行相关操作
  2. 监视的属性必须存在,才能进行监视
  3. 监视的两种写法: (1).new Vue时传入watch配置 (2).通过vm.$watch监视
// new Vue时传入watch配置
watch:{
        isHot:{
            immediate:true, //初始化时,让handler调用一下
            // handler什么时候调用?当isHot发生改变时
            handler(newValue,oldValue){
                console.log('isHot被修改了', newValue, oldValue)
            }
        }
// vm.$watch配置监视方法
vm.$watch('isHot',{
    immediate:true, //初始化时,让handler调用一下
    // handler什么时候调用?当isHot发生改变时
    handler(newValue,oldValue){
        console.log('isHot被修改了', newValue, oldValue)
}})

深度监视

深度监视:

  1. Vue中的watch默认不监测对象内部值的改变(一层)。
  2. 配置deep:true可以监测对象内部值改变(多层)。 备注:
  3. Vue自身可以监测对象内部值的改变,但Vue提供的watch默认不可以!
  4. 使用watch时根据数据的具体结构,决定是否采用深度监视。
// new Vue时传入watch配置
watch:{
    // 正常写法
    isHot:{
        immediate:true, //初始化时,让handler调用一下
        deep:true, //深度监视
        // handler什么时候调用?当isHot发生改变时
        handler(newValue,oldValue){
            console.log('isHot被修改了', newValue, oldValue)
        }
    },  
    // 简写
    isHot(newValue,oldValue){
        console.log('isHot被修改了', newValue, oldValue)
    }
}
// 通过vm.$watch监视
/* vm.$watch('isHot',{
    immediate:true, //初始化时,让handler调用一下
    deep:true, //深度监视
    // handler什么时候调用?当isHot发生改变时
    handler(newValue,oldValue){
        console.log('isHot被修改了', newValue, oldValue)
    }
}) */
// 简写,简写不能配置其他属性,比如immediate,deep
vm.$watch('isHot',function(newValue,oldValue){
    console.log('isHot被修改了', newValue, oldValue)
})

computed和watch之间的区别:

  1. computed能完成的功能,watch都可以完成。

  2. watch能完成的功能,computed不一定能完成,例如:watch可以进行异步操作。

两个重要的小原则:

  1. 所被Vue管理的函数,最好写成普通函数,这样this的指向才是vm 或 组件实例对象。
  2. 所有不被Vue所管理的函数(定时器的回调函数、ajax的回调函数等、Promise的回调函数),最好写成箭头函数,这样this的指向才是vm 或 组件实例对象。