Vue3——计算属性和监听
一、computed
作用:根据已有的数据计算出新数据,具有缓存性(如果依赖的计算数据不更新就只执行一次,更新再执行)
只读写法:
1 2 | let fullName = computed(() => { return 计算结果;<br>}) |
可读可写:
1 2 3 4 5 6 7 8 9 | let fullName = computed({ get() { return 计算结果; }, set(newVal) { // newVal是触发时传进来的参数 ...修改数据以达到修改计算属性的效果 } }) |
二、watch
作用:监视数据的变化
特点:Vue3中的watch只能监视以下四种数据:
1.ref定义的数据
情况一:监视【ref】定义的【基本类型】数据
1 2 3 4 5 | let sum = ref(0); // 监视 情况一:监视【ref】定义的【基本类型】数据 watch(sum, (newVal, oldVal) => { console.log( 'sum变化了' ,newVal, oldVal); }) |
情况二:监视【ref】定义的【对象类型】数据
1 2 3 4 5 6 7 8 9 10 11 12 13 | let person = ref({ name: '张三' , age: 18, }) // 监视 此时监视的是对象的地址值,只有对象地址改变时才会触发,如果想监听对象内部属性的变化,需要配置第三个参数对象:deep: true // immediate: true 无论person是否变化,都先执行一次里面的回调函数(第二个参数) watch(person, (newVal, oldVal) => { // 这里的newVal和oldVal值是否一致要看情况,他们指向的地址是person // 如果改变了地址,比如person.value = xxx,就会有不同的newVal和oldVal值,因为指向的地址不是一个 // 如果只改变了里面的属性,那newVal和oldVal指向的地址是一个,所以改变后newVal和oldVal都只能查询到最新的值,看起来newVal和oldVal就是一样的 console.log( 'person改变了' , newVal, oldVal); }, {deep: true , immediate: true }) |
延伸:停止监视写法
1 2 3 4 5 6 | const stopWatch = watch(sum, (newVal, oldVal) => { console.log( 'sum变化了' ,newVal, oldVal); if (newVal >= 10) { stopWatch(); } }) |
2.reactive定义的数据
情况一:监视【reactive】定义的【对象类型】数据(默认开启深度监视,因为reactive的局限性,不能重新分配一个新对象)
1 2 3 4 5 6 7 8 | let person = reactive({ name: '张三' , age: 18, }) // 监视 reactive的响应式数据时默认开启深度监视,且不能通过deep:false来关闭 watch(person, (newVal, oldVal) => { console.log( 'person改变了' , newVal, oldVal); }) |
若是要监听【对象中的某一属性】,可以将这个属性写成【getter函数】(即返回一个值的函数)
person中的不同属性进行监听
1 2 3 4 5 6 7 8 | let person = reactive({ name: '张三' , age: 18, car: { c1: '奔驰' , c2: '宝马' } }) |
1 2 3 | watch(() => person.name, (newVal, oldVal) =>{ console.log( 'person.name发生了变化' , newVal, oldVal); }) |
②若该属性值是【对象类型】,可直接编,也可以写成函数,建议写成函数
-直接编写,只能监视内部属性的变化,对整个car的修改无法监视,因为person.car指的就是当前的person.car,一旦更改就找不到了
1 2 3 | watch(person.car, (newVal, oldVal) => { console.log( 'person.car发生了变化' , newVal, oldVal); }) |
-函数式编写,只能监视person.car地址的变化,无法监视内部属性变化,可以通过配置deep:true解决(同ref监视对象类型一样)
1 2 3 | watch(() => person.car, (newVal, oldVal) => { console.log( 'person.car发生了变化' , newVal, oldVal); }, {deep: true }) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | let person = reactive({ name: '张三' , age: 18, car: { c1: '奔驰' , c2: '宝马' } }) // 监视 watch([() => person.name, () => person.car.c1], (newVal, oldVal) => { // newVal和oldVal是name和c1的值 console.log( 'person.car发生了变化' , newVal, ); }, {deep: true }) |
三、watchEffect
介绍:立即运行的一个函数(启动即会执行一次),同时响应式地追踪其依赖(可以灵活监控用到的数据),并在依赖更改时重新执行该函数
watch和watchEffect的区别
1.都能监听响应式数据的变化,但是方式不同
3.watchEffect:不用明确指出监视的数据(函数中用到哪些属性,那就监视哪些属性)
watch和watchEffect分别实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | let temp = ref(10); let height = ref(0);<br> // 通过watch监听实现 watch([temp, height], (value) => { const [newTemp, newHeight] = value; if (newTemp >= 60 || newHeight >= 80) { console.log(value); } }) // 通过watchEffect监听实现(更方便) watchEffect(() => { /** * 有一个小Bug,一旦temp值大于60之后,再去点击height增加按钮无法输出条件语句内的内容, * 是因为||运算符一旦前面条件满足就不会再执行||后面的语句,因此无法在temp条件满足的情况下去监听height * 解决办法:在watchEffect再使用一下height.value即可监听,或者使用其他运算符 */ if (temp.value >= 60 || height.value >= 80) { console.log( '达到要求' ); } }) |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)