【Vue】Computed和watch使用场景(细数深度监听那些事)

Computed和watch使用场景和方法+细数深度监听那些事

  • 一、computed和watch的共通点
  • 二、computed
  • 三、watch
    • 1.普通监听:不能监听对象的属性,刷新/首次加载不能执行
    • 2.高级监听:能做普通监听做不了的事
      • (1)使用`immediate: true`①解决刷新/首次加载函数不执行的问题 ②监听路由变化
      • (2)使用`deep: true`解决监听不到对象属性变化的问题
    • 3. 关于注销watch

一、computed和watch的共通点

不要在computed和watch里面修改依赖的值,尽量只是生成新的值。


二、computed

适用情况:拿到的值不是我们想要直接显示的。(一般仅读取,不建议做set操作)

<span>{
    { name }}span>
data () {
     
  return {
     
  	firstName: '张',
  	lastName: '三'
  }
},
computed: {
     
  name () {
     
    return `${
       this.firstName}${
       this.lastName}`
  }
}

如上述,name依赖的值firstName、lastName,有任何一个变化了,都会去重新计算它的值(缓存起来)


三、watch

适用情况:监听到了某个数据的变化,需要执行异步(访问API)或开销较大的操作。

1.普通监听:不能监听对象的属性,刷新/首次加载不能执行

watch: {
     
   // 如果 `firstName` 发生改变,这个函数就会运行
   firstName (newName, oldName) {
     
      this.fullName = newName + ' ' + this.lastName
    },
 },

Q1:为什么组件首次加载的时候,firstName方法不执行咧?
A1:其实普通监听等价于下面这种写法。Vue.js会去处理这样的一个逻辑:上面firstName函数里的东西,最终编译出来其实就是下面的handler里的东西。且默认将immediate设为false,表示不会在firstName函数绑定时,就执行handler方法。

watch: {
     
   // 如果 `firstName` 发生改变,这个函数里的handler方法就会运行
   firstName (newName, oldName) {
     
      handler (newName, oldName) {
     
        this.fullName = newName + ' ' + this.lastName
      },
      immediate: false // 不会在firstName函数绑定时,就执行handler方法
    },
 },


2.高级监听:能做普通监听做不了的事

handler:watch中需要具体执行的方法。与immediate、deep选项配合使用

(1)使用immediate: true①解决刷新/首次加载函数不执行的问题 ②监听路由变化

① 解决刷新/首次加载函数不执行的问题

watch: {
     
   // 首次加载/刷新/`firstName`发生改变,这个函数里的handler方法就会执行
   firstName (newName, oldName) {
     
      handler (newName, oldName) {
     
        this.fullName = newName + ' ' + this.lastName
      },
      immediate: true // 表示在wacth里声明了firstName函数后,立即触发这里的handler方法。
    },
 },

② 监听路由变化

watch: {
     
  '$route': {
     
    handler (newVal) {
     
      console.log('this.$route.query', this.$route.query)
    },
    immediate: true
  }
}

(2)使用deep: true解决监听不到对象属性变化的问题

data () {
     
  return {
     
  	firstName: '张',
  	lastName: '三'
  }
},
watch: {
     
   // 监听obj对象里所有所有属性的变化 -- 首次加载/刷新/`obj`里的任一属性发生改变,这个函数里的handler方法就会执行
   obj: {
     
     handler (newName, oldName) {
     
       console.log('obj changed')
     },
     immediate: true,
     deep: true
   },
   // 监听对象里的某个属性 -- 监听obj对象里所有属性的变化开销较大,若只监听某一属性的变化,可优化性能
    'obj.a': {
     
      handler(newName, oldName) {
     
          console.log('obj.a changed')
      },
      immediate: true,
      deep: true
    }
 },


3. 关于注销watch

Q:为什么要注销?
A:可能会导致内置溢出
Q:如何注销?
A:我们日常开发watch都是写在组件的选项中的,他会随着组件的销毁而销毁,无需手动注销。

你可能感兴趣的:(vue,vue,js)