computed函数
vue3中的计算属性与vue2的配置功能一致,但在setup函数中使用必须先引入,写法如下:
import { reactive, computed } from 'vue'
setup(){
const person = reactive({
firstName: '张',
lastName: '三',
})
// 计算属性——只读当修改fullName时,firstName和lastName不变
person.fullName = computed(() => {
return person.firstName + '-' + person.lastName
})
// 计算属性——可以读写
person.fullName = computed({
// 读取fullName
get(){
return person.firstName + '-' + person.lastName
},
// 修改fullName
set(newValue){
// 修改后的fullName分割得到firstName和lastName
const nameArr = newValue.split('-')
person.firstName = nameArr[0]
person.lastName = nameArr[1]
}
})
return {
person
}
}
watch函数
vue3的watch函数参数分别为被监视属性、回调函数和其他配置,与vue2的配置功能一致,根据ref或reactive定义响应式数据分为以下几种情况:
- watch监视ref定义的响应式数据
<button @click="sum++"></button>
...
let sum = ref(0)
watch(sum, (newValue, oldValue)=>{
console.log('sum变化了',newValue,oldValue)
}, {immediate: true})
// 'sum变化了,1,0'
特殊情况:watch监听ref定义的响应式数据为对象
<button @click="person.age++"></button>
let person = ref({
name: 'ls',
age: 20
})
// ref定义的person是一个RefImpl对象,真正的数据存放在value属性中,无法直接监视person
watch(person, (newValue, oldValue)=> {
console.log('person的age变化了')
})
// 解决方法1:监视真正的数据(等同于情况3)
watch(person.value, (newValue, oldValue)=> {
console.log('person的age变化了')
})
// 解决方法2:value属性的值是一个proxy对象,开启deep(等同于情况4的特殊情况)
watch(person, (newValue, oldValue)=> {
console.log('person的age变化了')
}, {deep:true})
- watch监视多个ref定义的响应式数据
<button @click="sum++"></button>
<button @click="msg+='!'"></button>
let sum = ref(0)
let msg = '你好啊'
// 被监视的多个属性放在一个数组中
watch([sum, msg], (newValue, oldValue)=>{
console.log('sum或msg变化了',newValue,oldValue)
}, {immediate: true})
// 'sum或msg变化了,[1,'你好啊'],[0,'你好啊']'
// 'sum或msg变化了,[1,'你好啊!'],[1,'你好啊']'
- watch监视reactive定义的响应式数据
<button @click="person.name+='~'"></button>
<button @click="person.age++"></button>
let person = reactive({
name: 'zs',
age: 18
})
watch(person, (newValue, oldValue)=>{
console.log('person变化了',newValue,oldValue)
}, {immediate: true, deep: false}) // 此处deep配置不生效
// 'person变化了', {name: 'zs~',age: 18},{name: 'zs~',age: 18}
// 'person变化了', {name: 'zs~',age: 19},{name: 'zs~',age: 19}
当监视reactive定义的响应式数据时,oldValue无法获取,且深度监视被强制开启。
- watch监视reactive定义的响应式数据的某个属性
<button @click="person.name+='~'"></button>
let person = reactive({
name: 'zs',
age: 18,
job: {
j1: {
salary: 20
}
}
})
// 此时被监视对象需要放入函数中
watch(()=>person.name, (newValue, oldValue)=>{
console.log('person的name变化了',newValue,oldValue)
})
// 'person的name变化了,zs~, zs'
特殊情况:当reactive定义的响应式数据的某个属性的值为对象时,需要开启deep配置
<button @click="person.job.j1.salary++"></button>
let person = reactive({
name: 'zs',
age: 18,
job: {
j1: {
salary: 20
}
}
})
watch(()=>person.job, (newValue, oldValue)=>{
console.log('person的job变化了',newValue,oldValue)
}, {deep: true})
// person的job变化了 {j1:{salary:21}} {j1:{salary:21}}
- watch监视reactive定义的响应式数据的多个属性
<button @click="person.name+='~'"></button>
<button @click="person.age++'~'"></button>
let person = reactive({
name: 'zs',
age: 18
})
watch([()=>person.name, ()=>person.age], (newValue, oldValue)=>{
console.log('person的name或age变化了',newValue,oldValue)
})
// person的name或age变化了 ['zs~', 18] ['zs', 18]
// person的name或age变化了 ['zs~', 19] ['zs~', 18]
watchEffect函数
watchEffect函数监视所指定回调函数中用到的属性,若回调中的数据发生变化,则会重新执行回调。
import { watchEffect } from 'vue'
// ...
setup(){
let sum = ref(0)
// 回调中用到sum,只要sum变化就会打印'watchEffect回调执行了'
watchEffect(()=>{
const x1 = sum.value
console.log('watchEffect回调执行了')
})
return {
sum
}
}
与computed和watch比较
- watch函数既指明监视的属性,也指明监视的回调;watchEffect函数不指明监视的属性
- computed注重计算出来的值(回调函数的返回值),所以必须写
return;watchEffect注重执行过程(回调函数的函数体),所以不用写return