目录
解答:watch函数监视ref定义的响应式数据是否需要加 .value
一、computed函数
- 与Vue2中computed配置功能一致
- 写法
<template>
<h1>一个人的信息</h1>
姓:<input type="text" v-model="person.firstName"><br>
名:<input type="text" v-model="person.lastName"><br>
<span>全名:{{person.fullName}}</span><br>
全名:<input type="text" v-model="person.fullName">
</template>
<script>
import {reactive,computed} from 'vue'
export default {
name: 'Demo',
setup() {
//数据
let person = reactive({
firstName: '张',
lastName: '三'
})
//计算属性-简写(没有考虑计算属性被修改的情况,只能读取)
person.fullName = computed(()=>{
return person.firstName +'-'+ person.lastName
})
//计算属性-完整写法(可以读取和修改)
person.fullName = computed({
get(){
return person.firstName +'-'+ person.lastName
},
set(value){
const nameArr = value.split('-')
person.firstName = nameArr[0]
person.lastName = nameArr[1]
}
})
//返回一个对象(常用)
return {
person,
}
}
}
</script>
二、watch函数
-
与Vue2中watch配置功能一致
-
两个“小坑”
- 监视reactive定义的响应式数据时:oldValue无法正确获取,强制开启了深度监视(deep配置也无效)。
- 监视reactive定义的响应式数据中某个属性(这个属性的值是一个对象)时:deep配置有效。
-
六种情况
//情况一:监视ref所定义的一个响应式数据
watch(sum,(newValue,oldValue)=>{
console.log('sum的值变化了',newValue,oldValue)
},{immediate:true})
//情况二:监视ref所定义的多个响应式数据
watch([sum,msg],(newValue,oldValue)=>{
console.log('sum或msg的值变化了',newValue,oldValue)
},{immediate:true})
/*情况三:监视reactive所定义的一 个响应式数据
1.注意:此处无法正确的获取oldValue//ref定义的对象和数组,最终实质都是通过reactive,所以改为ref定义也不行
2.注意:强制开启了深度监视(deep配置false也无效)*/
watch(person,(newValue,oldValue)=>{
console.log('person变化了',newValue,oldValue)
},{deep:false}) //此处的deep配置无效
//情况四:监视reactive所定义的一个响应式数据中的某个属性
// 此处不能直接写person.age,要写成一个函数
watch(()=>person.age,(newValue,oldValue)=>{
console.log('person的age变化了',newValue,oldValue)
},)
//情况五:监视reactive所定义的一个响应式数据中的某些属性
watch([()=>person.name,()=>person.age],(newValue,oldValue)=>{
console.log('person的age或name变化了',newValue,oldValue)
},)
//特殊情况
watch(()=>person.job,(newValue,oldValue)=>{
console.log('person的job变化了',newValue,oldValue)
},{deep:true})//此处由于监视的是reactive定义的对象中的某个属性(这个属性依然是个对象),所以deep配置有效
代码:
<template>
<h2>当前求和为:{{sum}}</h2>
<button @click="sum++">点我+1</button>
<hr>
<h2>当前信息为:{{msg}}</h2>
<button @click="msg+='!'">修改信息</button>
<hr>
<h2>姓名:{{person.name}}</h2>
<h2>年龄:{{person.age}}</h2>
<button @click="person.name+='~'">修改姓名</button>
<button @click="person.age++">增加年龄</button>
<hr>
<h2>薪资:{{person.job.j1.salary}}K</h2>
<button @click="person.job.j1.salary++">涨薪</button>
</template>
<script>
import {ref,reactive,watch} from 'vue'
export default {
name: 'Demo',
//Vue2中
watch:{
//简写
sum(newValue,oldValue){
console.log(newValue,oldValue)
},
//完整版
sum:{
immediate:true,
deep:true,//深层监视
handler(newValue,oldValue){
console.log('sum的值变化了',newValue,oldValue)
}
}
},
setup() {
//数据
let sum = ref(0)
let msg = ref('你好啊')
let person = reactive({
name:'张三',
age:18,
job:{
j1:{
salary:20
}
}
})
//情况一:监视ref所定义的一个响应式数据
watch(sum,(newValue,oldValue)=>{
console.log('sum的值变化了',newValue,oldValue)
},{immediate:true})
//情况二:监视ref所定义的多个响应式数据
watch([sum,msg],(newValue,oldValue)=>{
console.log('sum或msg的值变化了',newValue,oldValue)
},{immediate:true})
/*情况三:监视reactive所定义的一 个响应式数据
1.注意:此处无法正确的获取oldValue//ref定义的对象和数组,最终实质都是通过reactive,所以改为ref定义也不行
2.注意:强制开启了深度监视(deep配置false也无效)*/
watch(person,(newValue,oldValue)=>{
console.log('person变化了',newValue,oldValue)
},{deep:false}) //此处的deep配置无效
//情况四:监视reactive所定义的一个响应式数据中的某个属性
// 此处不能直接写person.age,要写成一个函数
watch(()=>person.age,(newValue,oldValue)=>{
console.log('person的age变化了',newValue,oldValue)
},)
//情况五:监视reactive所定义的一个响应式数据中的某些属性
watch([()=>person.name,()=>person.age],(newValue,oldValue)=>{
console.log('person的age或name变化了',newValue,oldValue)
},)
//特殊情况
watch(()=>person.job,(newValue,oldValue)=>{
console.log('person的job变化了',newValue,oldValue)
},{deep:true})//此处由于监视的是reactive定义的对象中的某个属性(这个属性依然是个对象),所以deep配置有效
//返回一个对象(常用)
return {
sum,
msg,
person
}
}
}
</script>
解答:watch函数监视ref定义的响应式数据是否需要加 .value
由ref定义的响应式数据,若数据为基本数据类型,则不需要.value;若数据为对象这种引用类型,则监视时需要加 .value 或开启deep:true深度监视。
//数据
let sum = ref(0)
let msg = ref('你好啊')
let person = ref({
name:'张三',
age:18,
job:{
j1:{
salary:20
}
}
})
//监视基本数据类型
watch(sum,(newValue,oldValue)=>{
console.log('sum的值变化了',newValue,oldValue)
})
//监视person 加 .value或开启deep深度监视
//此处存在oldValue无法正确获取的问题
watch(person.value,(newValue,oldValue)=>{
console.log('person的值变化了',newValue,oldValue)
})
watch(person,(newValue,oldValue)=>{
console.log('person的值变化了',newValue,oldValue)
},{deep:true})
三、watchEffect函数
- watch的套路是,既要指明监视的属性,也要指明监视的回调。
- watchEffect的套路是:不用指明监视哪个属性,监视的回调中用到哪个属性,就会自动监视哪个属性。
- watchEffect有点像computed:
- 但 computed 注重计算出来的值(回调函数的返回值),所以必须要写返回值。
- 而 watchEffect 更注重的是过程(回调函数的函数体),所以不用写返回值。
//数据
let sum = ref(0)
let msg = ref('你好啊')
let person = reactive({
name:'张三',
age:18,
job:{
j1:{
salary:20
}
}
})
// 监视
/*watch(sum,(newValue,oldValue)=>{
console.log('sum的值变化了',newValue,oldValue)
},{immediate:true})*/
//用到哪个数据,监视哪个数据
watchEffect(()=>{
const x1 = sum.value //sum变化会监视到
const x2 = person.job.j1.salary //salary变化会监视到
console.log('watchEffect所指定的回调执行了!')
})