不习惯的Vue3起步三 の computed和watch

计算属性和侦听器

Computed计算属性

在模板内表达式非常简单,如果在模板内放入过多的逻辑会使得模板过重并且难以维护。

示例:

<template><div> {{ admin.friends.filter((item)=>{ if (item.name == '李四') { return true } else return false; }).length > 0 ? `${admin.name}有李四这个朋友`: `${admin.name}没有李四这个朋友` }} </div>
</template>

<script setup lang="ts"> import { ref, reactive, onMounted } from "vue";let admin = ref({name: '张三',friends: [{name: '李四',age: 15}]}) </script> 

在上述例子中,div元素中进行判断编写的就过于复杂了,此时模板不再是简单的,必须先看一下,才能意识到结果取决于admin.friend中是否有李四,如果要在模板中多次包含改计算,template会更加糟糕

对于任何包含响应式数据的复杂逻辑,都可以使用计算属性

computed: 接收一个回调函数,返回一个通过其他属性经过计算的新值,此新值是通过ref包装过的常量

对于上面的例子,可以使用computed抛出一个计算量

// 传参
let showres = computed(()=>(admin)=>{return admin.friends.filter((item)=>{ if (item.name == '李四') { return true } else return false; }).length > 0 ? `${admin.name}有李四这个朋友`: `${admin.name}没有李四这个朋友`
}) 

template中使用<div> {{ showres(admin) }} </div>即可显示,并且如果对admin做修改,showres也可以生效修改,这其实与Vue2中的computed是一样的,只不过写法上有了一些区别

<template><div> {{ showres(admin) }} </div><button @click="change">改变</button>
</template>

<script setup lang="ts"> import { ref, reactive, onMounted, computed } from "vue";let admin = ...// 传参let showres = ...function change() {admin.value = {name: '王五',friends: []}} </script> 

效果:

computed 对比 methods

当然如果写一个methods方法来代替计算属性,也是能够实现相同的效果的,两者之间的区别在于计算属性基于反应依赖关系缓存的,只有相关响应式依赖发生改变时才会重新求值。而方法是每当触发重新渲染时,调用方法将总会再次执行函数。

比如下面:只改变数值t,但是随着渲染刷新,methods方法产生的showres2也会随之改变,而computed因为响应式依赖没有改变,所以不动。

<template><div> {{ showres }} </div><div> {{ showres2() }} </div>{{ t }}<button @click="change">改变</button>
</template>

<script setup lang="ts"> import { ref, reactive, onMounted, computed } from "vue";let t = ref(1);// 传参let showres = computed(()=>{return new Date()})let showres2 = ()=>{return new Date()}function change() {setInterval(()=>{t.value++;}, 1000)} </script> 

效果:

使用 computed 会产生一个缓存,所以在性能上比methods更好,不过如果不希望缓存,也可以使用methods。


watch侦听器

watch API 与选项式 API this.$watch (以及相应的 watch 选项) 完全等效

当需要在数据变化时执行异步或开销较大的操作时,使用watch比使用computed更有效。

watch有三个参数:

  • 一个想要侦听的响应式引用或 getter 函数
  • 回调函数
  • 监听的配置(可选)

对于监听的对象,ref定义和reactive定义时监听方式也是不同的

对于ref

/* watch */ 
let count1 = ref(10), count2 = ref(20)
watch(count1, (newval, oldval)=>{console.log(newval, oldval)
})
// 监听多个值
watch([count1, count2], (newval, oldval)=>{console.log(newval, oldval)
})
function change() {count1.value++
} 

ref,可以监听单个值,也可以同时监听多个值,第一个参数直接写ref或者ref数组即可。

对于reactive:

1.如果将state对象传入watch,只能监听到新值,对于老值是无法监听的

const state = reactive({ count: 0 })
watch(state, (newval, oldval)=>{console.log(newval.count, oldval.count)
})

function change() {state.count++
} 

2.如果想要监听state对象中某一属性,要使用()=> ...函数的方式,并且这样对于count的改变新值和老值都能监听到

watch(()=>state.count, (newval, oldval)=>{console.log(newval, oldval)
}) 

3.如果想要监听state对象多个属性,可以像之前监听ref时一样使用[]

const state = reactive({ count: 0, age: 1 })

watch([()=>state.count, ()=>state.age], (newval, oldval)=>{console.log(newval, oldval)
}) 

watchEffect

watchEffect属于对watch的一些补充吧,不过大部分时候还是使用watch就足够了。

watchEffect:

1.不需要手动传入依赖
2.不是lazy初始化执行分析依赖,而watch是lazy的,页面第一次加载不会触发,除非使用immediate。watchEffect会在onMounted之前调用
3.watchEffect无法获取老值,只能获取新值
4.一些异步操作放里面比watch更合适
5.watch的第三个参数是处理副作用的,watchEffect靠第一个参数,watchEffect第二个参数可以设置onTriggerflush等侦听器行为调试,参考API

示例:

let stop = watchEffect((onInvalidate)=>{console.log(count1.value)onInvalidate(()=>{// onInvalidate清除副作用})
})
// 结束watch监听
stop(); 

PS: 并且watchEffect无法对reactive进行监听,因为无法监测对象内部的变化

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值