Vue3笔记 - Vue3中的计算属性、监视属性和watchEffect函数

计算属性与监视属性

1. 计算属性

Vue3中的计算属性仅在书写方式上与Vue2略有不同,功能上基本一致

  • Vue2中的计算属性

    computed:{
    	fullName:{
    		get(){
    			return this.firstName + '-' + this.lastName;
    		},
    		set(value){
    			const arr = value.split('-')
    			this.firstName = arr[0]
    			this.lastName = arr[1]
    		}
    	}
    }
    
  • Vue3中的计算属性

    import { reactive,computed } from "vue";
    export default {
      name: "App",
      setup() {
        let person = reactive({
          name: "张三",
          age: 18,
          hobby: ["学习", "吃饭"],
        });
          
        //计算属性无法写到person内部
        //此处为简写形式
        person.fullName = computed(()=>{
            return person.firstName + '-' + person.lastName
        })
        //完整形式
        person.fullName2 = computed({
            get(){
                return person.firstName + '-' + person.lastName
            },
            set(value){
                const nameArr = value.split('-')
                person.firstName = nameArr[0]
                person.lastName = nameArr[1]
            }
        })
    
        return {
          person
        };
      },
    };
    
  • 注意事项

    由于ref常常搭配.value获取属性值,所以容易出现以下错误

    watch(sum.value,(newValue,oldValue)=>{
        //...
    })
    

    此时sum.value是不会被监视的,因为只有sum才是具有响应式的数据,而sum.value仅仅只是基本类型数据

    对于被ref包裹的对象类型数据也需要注意

    //对对象类型数据使用ref,会自动调用reactive设置响应式
    //下列写法无法正常监视person内部属性变化,因为该对象类型是通过ref设置的,reactive设置的Proxy对象被包裹在ref设置的RefImpl对象内。也就是说,person是对象中的对象,需要深层监视才能检测到属性变化
    watch(person,(newValue,oldValue)=>{
        //...
    })
    
    //正确写法1
    //.value将Proxy对象提取出来,由于reactive自带深度监视,所以自然能检测到属性变化
    watch(person.value,(newValue,oldValue)=>{
        //...
    })
    
    //正确写法2
    watch(person.value,(newValue,oldValue)=>{
        //...
    },{deep:true})
    

2. 监视属性

Vue3的监视属性虽然与Vue2的功能基本一致,但细节和书写方面有很大不同

  • Vue2监视属性

    watch:{
    	'numbers':{
    		deep:true,
    		handler(){
    			console.log('numbers改变了')
    		}
    	}
    }
    
  • Vue3监视属性 - 监视ref定义的响应式数据

    //1.监视单个ref定义的响应式数据
    watch(sum,(newValue,oldValue)=>{
        console.log('sum变化了',newValue,oldValue)
    },{immediate:true})
    
    //2.监视多个ref定义的响应式数据
    watch([sum,msg],(newValue,oldValue)=>{
        console.log('sum或msg变化了',newValue,oldValue)
    })
    
  • Vue3监视属性 - 监视reactive定义的响应式数据

    //1.监视reactive定义的响应式数据中的全部属性(任何属性被修改都会触发)
    /*
    注意:
    	- 若watch监视的是reactive定义的响应式数据,则无法正确获得oldValue
    	- 若watch监视的是reactive定义的响应式数据,则强制开启深度监视
    */
    watch(person,(newValue,oldValue)=>{
        console.log('person变化了',newValue,oldValue)
    })
    
    //2.监视reactive定义的响应式数据中的某个属性
    watch(()=>person.job,(newValue,oldValue)=>{
        console.log('person的job变化了',newValue,oldValue)
    })
    
    //3.监视reactive定义的响应式数据中的某些属性
    watch([()=>person.job,()=>person.age],(newValue,oldValue)=>{
        console.log('person的job或age变化了',newValue,oldValue)
    })
    
  • 重点注意事项

    1. 若watch监视的是reactive定义的响应式数据,则无法正确获得oldValue,oldValue会自动被更新为最新的值。这点是设计问题,需要额外设置方法修复。

    2. 若watch监视的是reactive定义的响应式数据,则强制开启深度监视,即便通过deep:false也无法关闭

    3. 若watch监视的是reactive定义的响应式数据中的某个属性,且该属性为对象类型,则此时需要开启deep才能深度监视到该对象属性的内部元素变化

      这里一定要和2.区分开来,2.监控的是整个响应式数据对象,3.监控的是该响应式数据对象中的某个属性。虽然听起来很不合理,但是2.的情况是可以监控到深层的,deep是强制开启的,而3.是无法监视到深层的,deep需要手动开启

3. watchEffect函数

  • watchEffect有点像计算属性和监视属性和结合体
  • 与watch的对比
    • watchEffect不用指明监视某个属性,监视的回调中用到了哪个属性,就监视哪个属性
    • watch既要指明监听的属性,也要指明监视的回调
  • 与computed的对比
    • watchEffect更注重的是计算出来的值(回调函数的函数体),必须要写返回值
    • computed注重的是计算出来的值(回调函数的返回值),必须要写返回值
//此处x1,x2会被监视
watchEffect(()=>{
    const x1 = sum.value
    const x2 = person.job.j1.salary
})
posted @   Solitary-Rhyme  阅读(314)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示