一、computed
作用:根据已有的数据计算出新数据,具有缓存性(如果依赖的计算数据不更新就只执行一次,更新再执行)
只读写法:
let fullName = computed(() => {return 计算结果;
})
可读可写:
let fullName = computed({get() {return 计算结果;},set(newVal) {// newVal是触发时传进来的参数...修改数据以达到修改计算属性的效果 } })
二、watch
作用:监视数据的变化
特点:Vue3中的watch只能监视以下四种数据:
1.ref定义的数据
情况一:监视【ref】定义的【基本类型】数据
let sum = ref(0);// 监视 情况一:监视【ref】定义的【基本类型】数据watch(sum, (newVal, oldVal) => {console.log('sum变化了',newVal, oldVal);})
情况二:监视【ref】定义的【对象类型】数据
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})
延伸:停止监视写法
const stopWatch = watch(sum, (newVal, oldVal) => {console.log('sum变化了',newVal, oldVal);if (newVal >= 10) {stopWatch();}})
2.reactive定义的数据
情况一:监视【reactive】定义的【对象类型】数据(默认开启深度监视,因为reactive的局限性,不能重新分配一个新对象)
let person = reactive({name: '张三',age: 18,}) // 监视 reactive的响应式数据时默认开启深度监视,且不能通过deep:false来关闭watch(person, (newVal, oldVal) => {console.log('person改变了', newVal, oldVal);})
若是要监听【对象中的某一属性】,可以将这个属性写成【getter函数】(即返回一个值的函数)
person中的不同属性进行监听
let person = reactive({name: '张三',age: 18,car: {c1: '奔驰',c2: '宝马'}})
watch(() => person.name, (newVal, oldVal) =>{console.log('person.name发生了变化', newVal, oldVal);})
②若该属性值是【对象类型】,可直接编,也可以写成函数,建议写成函数
-直接编写,只能监视内部属性的变化,对整个car的修改无法监视,因为person.car指的就是当前的person.car,一旦更改就找不到了
watch(person.car, (newVal, oldVal) => {console.log('person.car发生了变化', newVal, oldVal);})
-函数式编写,只能监视person.car地址的变化,无法监视内部属性变化,可以通过配置deep:true解决(同ref监视对象类型一样)
watch(() => person.car, (newVal, oldVal) => {console.log('person.car发生了变化', newVal, oldVal);}, {deep: true})
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分别实现:
let temp = ref(10);let height = ref(0);
// 通过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('达到要求');}})