计算属性computed
当需要根据已有的响应式属性计算出一个新的值时,就需要用到计算属性来完成,来降低模板的复杂度。计算属性是基于依赖的响应式数据进行缓存的,在相关响应式依赖发生改变时它们才会重新求值。
使用
// vue2写法简写形式
computed: {
"计算属性名" () {
return "值"
}
}
// 完整形式
computed: {
"计算属性名" : {
// getter
get: function () {
......
return ...
},
// setter
set: function (newValue) {
......
}
}
}
// vue3写法
import {computed} from 'vue'
// 简写形式
let 属性名 = computed(()=>{
return ......
})
//完整形式
let 属性名 = computed({
get(){
// 该属性值用到的响应式数据发生改变时走get
return
},
set(value){
// 有响应式用到该属性值,再改属性值改变时走set
......
}
})
侦听属性watch
当需要在响应式属性发生变化时执行一些特定的操作时,可以使用Vue的侦听属性。
使用
//vue2写法
watch: {
'要侦听的属性名': {
handler(newValue,oldValue) {
// 在组件实例创建时会立即调用
},
// 强制立即执行回调
immediate: true,
//开启深度侦听
deep:true,
}
}
//vue3写法,接收三个参数,(要侦听的的属性,回调,配置)
watch(
person,
(newValue,oldValue)=>{
console.log('person变化了',newValue,oldValue)
},
{immediate:true,deep:false}
)
# 注意
- 在Vue3中若侦听的是reactive定义的响应式数据,默认开启了深度侦听且不能关闭
- Vue2中watch侦听的,Vue3中若watch侦听的是reactive定义的响应式数据,则无法正确获得oldValue!!!(这是因为复杂类型的数据watch侦听到的新旧值都指向了同一块堆地址)
- 侦听reactive定义的响应式数据中的某一个属性传入的第一个参数需要为`()=>person.job`函数返回值的形式
- 侦听多个属性的话第一个参数应为`[]`数组形式
- 如果侦听的是reactive定义的响应式数据中的一个对象,deep深度侦听属性需要自己开启
解决无法获得oldValue
// 我们只需要将想要侦听的数据在计算属性中将obj进行深拷贝,然后侦听拷贝的内容就可以了(都用到了lodash这个js库)
import {cloneDeep} from 'lodash'
// vue2写法
computed:{
newobj(){
return cloneDeep(this.obj)
}
},
// vue3写法
watch(
() => _.cloneDeep(obj)
(newValue,oldValue) => { ...... }
)
watchEffect函数
watchEffect,不用指明侦听哪个属性,监视的回调中用到哪个属性,那就侦听哪个属性,类似计算属性,但computed注重的计算出来的值(回调函数的返回值),所以必须要写返回值,而watchEffect更注重的是过程(回调函数的函数体),不用写返回值。
使用
watchEffect为立即执行函数,类似开启了watch的immediate属性,没有newValue和oldValue,可以手动停止侦听
//watchEffect所指定的回调中用到的数据只要发生变化,则直接重新执行回调。
const textAsync= (number:number)=>{
return setTimeout(()=>{
console.log(number);
},3000)
}
const watch_Number = watchEffect(async(onCleanup)=>{
const timer = textAsync(number.value)
// 只有以来的响应式变量发生变化才会执行
onCleanup(()=>{
clearTimeout(timer) //清除定时器
})
})
setTimeout(_=>{
number.value++
},2000)
// setTimeout(_=>{
// watch_Number() // 两秒之后停止侦听
// },2000)
如上代码,模拟访问接口,刚进来的时候number发生变化调用textAsync函数,两秒后number会增加,增加之后又会调用textAsync函数,函数三秒钟后返回数据,这样相当于调用了两次接口,如果加上onCleanup的话就会清除之前内容,只返回最后一次的数据。
小结
用这么久Vue居然才发现这个问题,哈哈哈哈哈,看来要学的东西还很多嘛!
本文正在参加「金石计划」