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) })
-
重点注意事项
-
若watch监视的是reactive定义的响应式数据,则无法正确获得oldValue,oldValue会自动被更新为最新的值。这点是设计问题,需要额外设置方法修复。
-
若watch监视的是reactive定义的响应式数据,则强制开启深度监视,即便通过deep:false也无法关闭
-
若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
})
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!