vue 的计算属性(computed)和侦听器(watch)

目录

一、计算属性(computed)

1、计算属性的特点

2、计算属性的原理——getter 和 setter

3、computed 里返回一个函数——给 computed 属性中的方法传参

4、computed 与 methods 的区别

二、侦听器(watch)

1、侦听器的特点

2、使用 watch的注意事项

3、watch的两个属性

(1)、deep

(2)、immediate

4、深度监听一个对象时如何避免新值与旧值相等呢?

5、watch 与 $watch 的关系

6、watch 的使用案例

三、计算属性 和 侦听器 适用场景

四、推荐几篇关于 computed 和 watch 的原理的深度解析好文


、计算属性(computed)

1、计算属性的特点

  • 支持 数据缓存——页面重新渲染时,只有数据发生了改变,才会执行相应的函数。
  • 减少模板中计算逻辑。
  • 依赖“响应式数据”。

2、计算属性的原理——getter 和 setter

在computed中的,属性都有一个get和一个set方法。当 computed 属性的属性值是函数,那么默认会走get方法,函数的返回值就是属性的值;当数据变化时,调用set方法。

计算属性默认只有 getter,在需要时你也可以提供一个 setter。

computed: {
  fullName: {
    // getter
    get: function () {
      return this.firstName + ' ' + this.lastName
    },
    // setter
    set: function (newValue) {
      var names = newValue.split(' ')
      this.firstName = names[0]
      this.lastName = names[names.length - 1]
    }
  }
}

再运行 vm.fullName = 'John Doe' 时,setter 会被调用,vm.firstName 和 vm.lastName 也会相应地被更新。 

实战应用案例:用computed监听:在子组件中更新父组件中传过来的变量

3、computed 里返回一个函数——给 computed 属性中的方法传参


使用了闭包。 

4、computed 与 methods 的区别



由上面这个例子可以看出:

computed 与 methods 的区别:

  • computed里定义的函数,函数名可以作为变量直接使用,默认 会执行该函数体。
  • methods里定义的函数,必须调用 才能执行该函数体。
  • computed里的数据会被缓存,每次更新都会先对比数据是否发生了变化,是才更新,否不执行,大大减少了渲染时间。
  • methods里的函数不会被缓存,只要数据有更新,就会执行对应的函数。
  • 如果你不希望有缓存,请用方法来替代。

二、侦听器(watch)

1、侦听器的特点

  • 支持异步
  • 可以侦听任何逻辑,比如:函数节流,Ajax异步获取的数据,甚至操作DOM(不建议)。
  • 页面重新渲染时,无论值变不变,都会重新执行,因为watch不支持数据缓存。
  • 监听的函数接收两个参数,第一个参数是:新值,第二个参数是:原来的值。

2、使用 watch的注意事项

不要在 watch 中使用箭头函数,因为箭头函数没有 this,它的 this 会继承它的父级函数,但是它的父级函数是 window,导致箭头函数的 this 指向 window,而不是 Vue 实例。

3、watch的两个属性

(1)、deep

默认情况下,侦听器只会监听数据本身的改变,若要进行深度监听,那就需要使用 deep。

deep:其值是 true 或 false。深度监听,用来控制是否要监听对象内布值的变化(在页面初始化化时不会触发,只有当值改变时才会触发)。

不过,deep 无法监听到数组的变动和对象的新增,参考 vue 数组变异,只有以响应式的方式触发才会被监听到——vm.$set。

(2)、immediate

默认情况下,侦听器需要 data 后面值改变了才会生效,若需要侦听器一进入页面就生效,那就需要使用 immediate。

immediate:其值是 true 或 false。组件加载时,用来控制是否要立即执行回调函数(在页面初始化后是否立即执行)。

4、深度监听一个对象时如何避免新值与旧值相等呢?

深度监听一个对象时,要监测到对象的具体需要被监听的属性,就能够解决新值与旧值相等的问题。

例如:问题再现

data () {
  return {
    obj: { a: 1 }
  }
},
watch: {
  obj (newVal, oldVal) {
    console.log(newVal, oldVal)
  }
}

上述代码中,当改变 obj 里属性的值时,打印 newVal 和 oldVal 的结果,发现他们是相等的。这是因为:改变一个对象里属性的值时,新值和旧值指向的是同一块内存区,所以无法拿到旧值,也可以理解为是浅拷贝的问题。我们可以通过直接监听该对象里的属性来解决这个问题:

data () {
  return {
    obj: { a: 1 }
  }
},
watch: {
  "obj.a": (newVal, oldVal) => {
    console.log(newVal, oldVal)
  }
}

5、watch 与 $watch 的关系

Vue 实例将会在实例化时调用$watch(),遍历 watch 对象的每一个属性

6、watch 的使用案例



三、计算属性 和 侦听器 适用场景

computed 能做的,watch 都能做,反之不行。不过,能用 computed 的尽量用 computed。

如果一个属性是由其他属性计算而来的,这个属性依赖其他属性,是一个 多对一 或者 一对一 ,一般用computed。

比如:



四、推荐几篇关于 computed 和 watch 的原理的深度解析好文

深入理解 Vue Computed 计算属性:https://segmentfault.com/a/1190000010408657
Vue的数据依赖实现原理简析:https://segmentfault.com/a/1190000010014281#articleHeader2
vue中$watch源码阅读笔记:vue中$watch源码阅读笔记 - Clarence2J - 博客园

你可能感兴趣的:(#,Vue.js,vue,computed计算属性,watch侦听器)