0


Vue —— watch和watchEffect的区别

目录

前言

watch函数与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'exportdefault{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'exportdefault{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'exportdefault{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>

本文转载自: https://blog.csdn.net/weixin_52148548/article/details/125073998
版权归原作者 甜甜酷盖 所有, 如有侵权,请联系我们删除。

“Vue —— watch和watchEffect的区别”的评论:

还没有评论