一、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: {
      handler (newName, oldName) {
        this.fullName = newName + ' ' + this.lastName
      },
      immediate: false // 不会在firstName函数绑定时,就执行handler方法
    },
 },


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

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

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

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

watch: {
   // 首次加载/刷新/`firstName`发生改变,这个函数里的handler方法就会执行
   firstName: {
      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都是写在组件的选项中的,他会随着组件的销毁而销毁,无需手动注销

Logo

前往低代码交流专区

更多推荐