vue3 计算与监视注意的点 | 青训营笔记

87 阅读2分钟

这是我参与「第四届青训营 」笔记创作活动的第13天。

我之前使用的是 vue2 ,这次也算过度到 vue3 ,一起来看看计算属性和监视的用法区别。

计算属性与监视

1.computed函数

  • 与Vue2.x中computed配置功能一致

  • 写法

     import {computed} from 'vue'
     ​
     setup(){
         ...
         //计算属性——简写[只读、没考虑修改]
         let fullName = computed(()=>{
             return person.firstName + '-' + person.lastName
         })
         //计算属性——完整
         let fullName = computed({
             get(){
                 return person.firstName + '-' + person.lastName
             },
             set(value){
                 const nameArr = value.split('-')
                 person.firstName = nameArr[0]
                 person.lastName = nameArr[1]
             }
         })
     }
    

2.watch函数

  • 与Vue2.x中watch配置功能一致

  • 两个小“坑”:

    • 监视reactive定义的响应式数据时:oldValue无法正确获取、强制开启了深度监视(deep配置失效)。
    • 监视reactive定义的响应式数据中某个属性时:deep配置有效。
     //情况一:监视ref定义的响应式数据
     watch(sum,(newValue,oldValue)=>{
         console.log('sum变化了',newValue,oldValue)
     },{immediate:true})
     ​
     //情况二:监视多个ref定义的响应式数据
     watch([sum,msg],(newValue,oldValue)=>{
         console.log('sum或msg变化了',newValue,oldValue)
     }) 
     ​
     /* 情况三:监视reactive定义的响应式数据
                 若watch监视的是reactive定义的响应式数据,则无法正确获得oldValue
                 若watch监视的是reactive定义的响应式数据,则强制开启了深度监视 
     */
     watch(person,(newValue,oldValue)=>{
         console.log('person变化了',newValue,oldValue)
     },{immediate:true,deep:false}) //此处的deep配置不再奏效
     ​
     //情况四:监视reactive定义的响应式数据中的某个属性
     watch(()=>person.job,(newValue,oldValue)=>{
         console.log('person的job变化了',newValue,oldValue)
     },{immediate:true,deep:true}) 
     //此处由于监视的是reactive素定义的对象中的某个属性,所以deep配置有效
     ​
     //情况五:监视reactive定义的响应式数据中的某些属性
     watch([()=>person.job,()=>person.name],(newValue,oldValue)=>{
         console.log('person的job变化了',newValue,oldValue)
     },{immediate:true,deep:true})
     ​
    

    监视reactive定义的响应式数据中某个属性时

    不能直接侦听响应式对象的属性值,例如:

    const obj = reactive({ count: 0 })
    
    // 错误,因为 watch() 得到的参数是一个 number
    watch(obj.count, (count) => {
      console.log(`count is: ${count}`)
    })
    

    这里需要用一个返回该属性的 getter 函数:

    // 提供一个 getter 函数
    watch(
      () => obj.count,
      (count) => {
        console.log(`count is: ${count}`)
      }
    )
    

3.watchEffect函数

  • watch的套路是:既要指明监视的属性,也要指明监视的回调。

  • watchEffect的套路是:不用指明监视哪个属性,监视的回调中用到哪个属性,那就监视哪个属性。

  • watchEffect有点像computed:

    • 但computed注重的计算出来的值(回调函数的返回值),所以必须要写返回值。
    • 而watchEffect更注重的是过程(回调函数的函数体),所以不用写返回值。
     //watchEffect所指定的回调中用到的数据只要发生变化,则直接重新执行回调。
     watchEffect(()=>{
         const x1 = sum.value
         const x2 = person.age
         console.log('watchEffect配置的回调执行了')
     })
    

总结

如果 vue2 掌握了,只要换一下写法即可(除了改动太大的地方),可以直接去官网查看过度文档:v3-migration.vuejs.org/