Vuewatch和watchEffect的区别
前言
watch和watchEffect的对比
watch
watch
显式指定依赖数据,依赖数据更新时执行回调函数- 具有一定的惰性lazy 第一次页面展示的时候不会执行,只有数据变化的时候才会执行(设置
immediate: true
时可以变为非惰性,页面首次加载就会执行) - 监视ref定义的响应式数据时可以获取到原值
- 既要指明监视的属性,也要指明监视的回调
watchEffect
-
watchEffect
自动收集依赖数据,依赖数据更新时重新执行自身 -
立即执行,没有惰性,页面的首次加载就会执行
-
无法获取到原值,只能得到变化后的值
-
不用指明监视哪个属性,监视的回调中用到哪个属性就监视哪个属性
深度解析watch函数
watch函数有两个小坑:
-
监视reactive定义的响应式数据(该数据为一个对象,因为reactive只能定义数组或对象类型的响应式)时:oldValue无法正确获取,会强制开启深度监视,deep配置不生效。
-
监视reactive定义的响应式数据中的某个属性时,且该属性是一个对象,那么此时deep配置生效。
具体的watch函数的用法在下面代码中都有所体现,注释详细
<template>
<div>
<h2>当前求和为:{{sum}}</h2>
<button @click="sum ">点我 1</button>
<hr>
<h2>当前的信息为:{{msg}} </h2>
<!-- 点击button拼接! -->
<button @click="msg ='!'">修改数据</button>
<hr>
<h2>姓名:{{person.name}}</h2>
<h2>年龄:{{person.age}}</h2>
<h2>薪资:{{person.job.j1.salary}}</h2>
<button @click="person.name ='~'"> 修改姓名</button>
<button @click="person.age "> 增长年龄</button>
<button @click="person.job.j1.salary "> 增长薪资</button>
</div>
</template>
<script>
import {ref,reactive,watch,watchEffect} from 'vue'
export default {
name:'demo',
setup(){
//数据
let sum = ref(0)
let msg = ref('hello')
let person = reactive({
name:'zhangsan',
age:'18',
job:{
j1:{
salary:20
}
}
})
//监视(三个参数,第一个是监视的对象,第二个是监视的回调函数,第三个是监视的配置)
//情况一:监视ref所定义的一个响应式数据
watch(sum,(newValue,oldValue)=>{
console.log('sum的值变化了',newValue,oldValue)
},{immediate:true,deep:true})
//immediate的值为true时表示非惰性的立即执行的(默认情况下是false)
//deep深层次触发(此处设置deep无意义)
//情况二:监视ref所定义的多个响应式数据,写成数组的形式
watch([sum,msg],(newValue,oldValue)=>{
console.log('sum或者msg变了',newValue,oldValue)
})
//情况三:监视reactive所定义的响应式数据
//若监视的是reactive定义的响应式数据,则无法正确获得oldValue
//若监视的是reactive定义的响应式数据,则watch会强制开启深度监视
//我们发现改变person的任意一个属性都会被监视到
watch(person,(newValue,oldValue)=>{
console.log('person改变了',newValue,oldValue)
})
//我们尝试设置deep:false,关闭深度监听(目的:改变job的值不会被watch监听到)
//但是我们发现deep:false并没有生效,原因是此时watch监视的是reactive定义的响应式对象,默认强制开启了深度监听
watch(person,(newValue,oldValue)=>{
console.log('person改变了',newValue,oldValue)
},{deep:false})
//情况四:监视reactive所定义的响应式数据中的某个属性
watch(()=>person.name,(newValue,oldValue)=>{
console.log('person的job改变了',newValue,oldValue)
})
watch(()=>person.age,(newValue,oldValue)=>{
console.log('person的job改变了',newValue,oldValue)
})
watch(()=>person.job,(newValue,oldValue)=>{
console.log('person的job改变了',newValue,oldValue)
})
//从上边我们发现改变name,age都会触发监听,但是改变job不会
//这是因为name和age属性的值只是一个简单的基本类型数据,
//而job属性的值是一个对象,比较深,想要监视到,就要开启深度监视,程序如下:
watch(()=>person.job,(newValue,oldValue)=>{
console.log('person的job改变了',newValue,oldValue)
},{deep:true})//此时job改变,会被监视到,此处的deep配置生效
//需要和情况三进行区分,此处watch监视的是reactive所定义的对象中的某个属性,而情况三watch监视的是reactive所定义的对象
//情况五:监视reactive所定义的响应式数据中的某些属性,写成数组的形式
watch([()=>person.name,()=>person.age],(newValue,oldValue)=>{
console.log('person的name或age改变了',newValue,oldValue)
})
//返回一个对象(常用)
return{
sum,
msg,
person
}
}
}
</script>
watch取消监听
const stop1 = watch(
[() => nameObj.name, () => nameObj.name],
([curName, curEng], [prevName, curEng]) => {
console.log(curName, curEng, "----", prevName, curEng);
setTimeout(() => {
stop();
}, 5000);
});
深度解析watchEffect函数
函数用法如下代码所示,注释详细:
<template>
<div>
<h2>当前求和为:{{sum}}</h2>
<button @click="sum ">点我 1</button>
<hr>
<h2>当前的信息为:{{msg}} </h2>
<!-- 点击button拼接! -->
<button @click="msg ='!'">修改数据</button>
<hr>
<h2>姓名:{{person.name}}</h2>
<h2>年龄:{{person.age}}</h2>
<h2>薪资:{{person.job.j1.salary}}</h2>
<button @click="person.name ='~'"> 修改姓名</button>
<button @click="person.age "> 增长年龄</button>
<button @click="person.job.j1.salary "> 增长薪资</button>
</div>
</template>
<script>
import {ref,reactive,watch,watchEffect} from 'vue'
export default {
name:'demo',
setup(){
//数据
let sum = ref(0)
let msg = ref('hello')
let person = reactive({
name:'zhangsan',
age:'18',
job:{
j1:{
salary:20
}
}
})
//watchEffect函数内部所指定的回调中用到的数据只要发生变化,就会重新执行回调
//只有一个参数,就是回调
watchEffect(()=>{
const x1 = sum.value//因为sum是ref定义的响应式数据,需要使用.value调用
const x2 = person.age
console.log('watchEffect配置的回调执行了')
})
return{
sum,
msg,
person
}
}
}
</script>
watchEffect取消监听
const stop = watchEffect(() => {
console.log(nameObj.name);
setTimeout(() => {
stop();
}, 5000);});
watchEffect与computed
watchEffect与computed有点像:
-
但是computed注重的计算出来的值(回调函数的返回值),所以必须要写返回值。
-
而watchEffect更注重的是过程(回调函数的函数体),所以不用写返回值。
-
computed若是值没有被使用时不会调用,但是watchEffect始终会调用一次
举例:
<template>
<div>
<h2>当前求和为:{{sum}}</h2>
<button @click="sum ">点我 1</button>
<hr>
<h2>当前的信息为:{{msg}} </h2>
<!-- 点击button拼接! -->
<button @click="msg ='!'">修改数据</button>
<hr>
<h2>姓名:{{person.name}}</h2>
<h2>年龄:{{person.age}}</h2>
<h2>薪资:{{person.job.j1.salary}}</h2>
<button @click="person.name ='~'"> 修改姓名</button>
<button @click="person.age "> 增长年龄</button>
<button @click="person.job.j1.salary "> 增长薪资</button>
</div>
</template>
<script>
import {ref,reactive,watch,watchEffect, computed} from 'vue'
export default {
name:'demo',
setup(){
//数据
let sum = ref(0)
let msg = ref('hello')
let person = reactive({
name:'zhangsan',
age:'18',
job:{
j1:{
salary:20
}
}
})
let person1 = reactive({
firstName:'张',
lastName:'三'
})
//computed
//计算属性——简写(没有考虑计算属性被修改的情况)
person1.fullName = computed(()=>{
//必须含有返回值
return person1.firstName '-' person1.lastName
})
//计算属性——完整写法(考虑读和写)
person1.fullName = computed({
//必须含有返回值
get(){
return person1.firstName '-' person1.lastName
},
set(value){
const nameArr = value.split('-')
person1.firstName = nameArr[0]
person1.lastName = nameArr[1]
}
})
//watchEffect
//可以不写给返回值
watchEffect(()=>{
const x1 = sum.value//因为sum是ref定义的响应式数据,需要使用.value调用
const x2 = person.age
console.log('watchEffect配置的回调执行了')
})
return{
sum,
msg,
person,
person1
}
}
}
</script>
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanfigeb
系列文章
更多
同类精品
更多
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
excel下划线不显示怎么办
PHP中文网 06-23 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
怎样阻止微信小程序自动打开
PHP中文网 06-13 -
photoshop蒙版画笔没反应怎么办
PHP中文网 06-24