1.computed
1)computed拥有缓存性,多次调用会直接从缓存中获取,而不会重新执行,只有相依赖的数据发生改变才会重新计算,所以说computed性能很高。
例:下面是同时调用三次计算属性firstTotal和三次函数firstTotalFun()的运行结果。可以发现,函数被执行了三次,而计算属性只被执行了一次。
代码:
<template><view class="container"><view class="item"><view>商品:</view><input type="text" v-model="firstGoods"></view><view class="item"><view>价格:</view><input type="text" v-model="firstPrice"></view><view class="item"><view>数量:</view><input type="text" v-model="firstNum"></view><view class="item"><view>总价格:</view><view>{{firstTotal}}, {{firstTotalFun()}}</view><view>{{firstTotal}}, {{firstTotalFun()}}</view><view>{{firstTotal}}, {{firstTotalFun()}}</view></view></view>
</template>
<script setup>
import { computed,ref } from 'vue';
let firstNum = ref(0)
let firstGoods = ref('')
let firstPrice = ref(0)
//计算属性
const firstTotal = computed(()=>{console.log("computed调用了");return firstPrice.value*firstNum.value})//普通函数
const firstTotalFun = ()=>{console.log("Function调用了")return firstPrice.value*firstNum.value
}
</script>
2)computed是只读的,不要去修改它,会报警告。
结果:
代码:
3)computed只能进行同步操作
4)computed在页面初始化加载的时候就会被立刻调用
5)必须要有返回值(return),如果代码只有一行也可以使用简写。
//正常写法
const firstTotal = computed(()=>{return firstPrice.value*firstNum.value})
//简写
const firstTotal = computed(()=>firstPrice.value*firstNum.value)
2.watch
1)watch可以监听到前一次的值和最新值。
结果:
代码:
let firstWatch = ref(0);
watch(firstWatch, (newValue,oldValue)=>{console.log("调用了watch:",newValue,oldValue)
});
2)如果需要监听对象类型具体属性的变化,需要设置deep:true,或者使用 “对象.value”。如下:
let goods = ref({name:'',price:0,num:0});
//法一:
watch(goods, (newValue,oldValue)=>{console.log("调用了watch:",newValue,oldValue)
},{deep:true});
//法二:
watch(goods.value, (newValue,oldValue)=>{console.log("调用了watch:",newValue,oldValue)
};
运行结果:
3)watch属性可以使用异步。(call一些api)
4) watch在页面初始化加载的时候不会被立刻调用,只有在监听的数据发生变化的时候才会调用。如果想要让他立刻调用可以添加immediate: true
watch(source,(newValue, oldValue) => {// 初始化的时候执行,且当 `source` 改变时再次执行},{ immediate: true }
)
- watchEffect
1)watchEffect资料上说不需要指定具体属性,只要是watchEffect里面使用的数据,都可以进行深层次的监听(可以监听到对象中每个属性的变化)。但是经过测试,发现只会监听使用到的对象的具体的属性,如下图代码,我在watchEffect方法中打印了goods.value和goods.value.name,但只有当我在name输入框中输入数据的时候才会出现打印结果,price,和num输入框都无法触发监听。不知为啥,欢迎交流。
let goods = ref({name:'',price:0,num:0});
watchEffect(()=>{console.log("调用了watchEffect",goods.value.name,goods.value)
})
2) 可以进行异步操作
3)在页面初始化加载的时候会被立刻调用,与watch的immediate类似。
补充:
computed是多对一,一般多个属性变化,会影响到一个属性的时候用computed。computed不可以使用异步。
watch是一对多,一般有一个属性变化,会影响到多个数据的时候使用watch。watch可以使用异步。