一文详解Vue中watch和watchEffect的区别

前言

watch函数与watcheffect函数都是监听器,在写法和用法上有一定区别,是同一功能的两种不同形态,底层都是一样的。【相关推荐:vue.js视频教程】

watch和watchEffect的对比

watch

watch显式指定依赖数据,依赖数据更新时执行回调函数具有一定的惰性lazy 第一次页面展示的时候不会执行,只有数据变化的时候才会执行(设置immediate: true时可以变为非惰性,页面首次加载就会执行)监视ref定义的响应式数据时可以获取到原值既要指明监视的属性,也要指明监视的回调

watchEffect

watchEffect自动收集依赖数据,依赖数据更新时重新执行自身

立即执行,没有惰性,页面的首次加载就会执行

无法获取到原值,只能得到变化后的值

不用指明监视哪个属性,监视的回调中用到哪个属性就监视哪个属性

立即学习“前端免费学习笔记(深入)”;

深度解析watch函数

watch函数有两个小坑:

监视reactive定义的响应式数据(该数据为一个对象,因为reactive只能定义数组或对象类型的响应式)时:oldValue无法正确获取,会强制开启深度监视,deep配置不生效。

监视reactive定义的响应式数据中的某个属性时,且该属性是一个对象,那么此时deep配置生效。

具体的watch函数的用法在下面代码中都有所体现,注释详细

    
        

当前求和为:{{sum}}

                
        

当前的信息为:{{msg}} 

                        
        

姓名:{{person.name}}

        

年龄:{{person.age}}

        

薪资:{{person.job.j1.salary}}

                            
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 } }}

登录后复制

watch取消监听

const stop1 = watch(  [() => nameObj.name, () => nameObj.name],  ([curName, curEng], [prevName, curEng]) => {    console.log(curName, curEng, "----", prevName, curEng);    setTimeout(() => {      stop();    }, 5000);  });

登录后复制

深度解析watchEffect函数

函数用法如下代码所示,注释详细:

    
        

当前求和为:{{sum}}

                
        

当前的信息为:{{msg}} 

                        
        

姓名:{{person.name}}

        

年龄:{{person.age}}

        

薪资:{{person.job.j1.salary}}

                            
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 } }}

登录后复制

watchEffect取消监听

const stop = watchEffect(() => {  console.log(nameObj.name);  setTimeout(() => {    stop();  }, 5000);});

登录后复制

watchEffect与computed

watchEffect与computed有点像:

但是computed注重的计算出来的值(回调函数的返回值),所以必须要写返回值。

而watchEffect更注重的是过程(回调函数的函数体),所以不用写返回值。

computed若是值没有被使用时不会调用,但是watchEffect始终会调用一次

举例:

    
        

当前求和为:{{sum}}

                
        

当前的信息为:{{msg}} 

                        
        

姓名:{{person.name}}

        

年龄:{{person.age}}

        

薪资:{{person.job.j1.salary}}

                            
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 } }}

登录后复制

以上就是一文详解Vue中watch和watchEffect的区别的详细内容,更多请关注【创想鸟】其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/3231798.html

(0)
上一篇 2025年4月1日 17:01:43
下一篇 2025年3月9日 03:00:36

AD推荐 黄金广告位招租... 更多推荐

相关推荐

  • VUE实例解析之mount实例挂载的实现

    本篇文章给大家带来了关于javascript的相关知识,其中主要介绍了关于mount实例挂载的相关问题,vue2中是通过new操作符生成实例并将根作为el传入,vue3中使用mount方法代替是el配置项,使用导出的createapp代替了…

    2025年4月1日 编程技术
    100
  • vue3 axios的使用介绍及数据渲染

    本篇文章给大家介绍如何使用axios方式调用接口以及获取的数据渲染,希望对需要的朋友有所帮助! 1、axios的作用是什么呢? axios主要是用于向后台发起请求的,还有在请求中做更多是可控功能。【相关推荐:vue.js视频教程】 2、项目…

    2025年4月1日 编程技术
    100
  • 归纳整理VUE实例参数与MVVM模式知识点

    本篇文章给大家带来了关于vue的相关知识,其中主要介绍了关于vue实例参数以及mvvm模式的相关问题,实例化一个vue对象,参数是一个选项对象,下面一起来看一下,希望对大家有帮助。 【相关推荐:vue、vue】 配置参数 实例化一个Vue对…

    2025年4月1日
    100
  • Vue基础知识总结之vue组件化开发

    本篇文章给大家带来了关于vue其中主要介绍了关于vue组件化开发的相关问题,组件化开发提供了一种抽象, 我们可以开发出一个独立可复用的小组件来构造我们的应用组件,下面一起来看一下,希望对大家有帮助。 【相关推荐:vue、vue】 一、函数式…

    2025年4月1日 编程技术
    100
  • 深入浅析Vue的动态属性绑定指令v-bind

    v-bind的作用和插值表达式差不多, 只不过v-bind主要用于动态设置标签的属性。下面本篇文章就来带大家详细了解一下vue的动态属性绑定指令v-bind,希望对大家有所帮助! v-bind指令是专门操作属性的指令,那么什么是属性呢?例如…

    2025年4月1日 编程技术
    100
  • 解析vue中axios的封装请求(附步骤代码)

    一、简介 axios 是一个轻量的http客户端,它基于 xmlhttprequest 服务来执行 http 请求,支持丰富的配置,支持 promise,支持浏览器端和 node.js 端。自vue2.0起,尤大大宣布取消对vue-reso…

    编程技术 2025年4月1日
    100
  • VUE组件的创建、渲染、及注册(总结分享)

    本篇文章给大家带来了关于vue的相关知识,其中主要介绍了关于组件的创建、渲染以及注册的相关问题,创建的组件不要写el因为最终所有的组件都要被vm管理,由vm决定服务的对象,下面一起来看一下,希望对大家有帮助。 【相关推荐:vue、vue】 …

    2025年4月1日
    100
  • 简单分析vue组件scoped的作用

    本篇文章给大家带来了关于vue的相关知识,其中主要介绍了关于scoped属性的相关问题,在style上加入scoped属性, 就会在此组件的标签上加上一个随机生成的data-v开头的属性,下面一起来看一下,希望对大家有帮助。 【相关推荐:v…

    2025年4月1日 编程技术
    100
  • 详解v-bind怎么动态绑定style属性

    v-bind怎么动态绑定style属性?本篇文章带大家详细了解一下v-bind指令动态绑定style属性的多种语法,希望对大家有所帮助! v-bind可以动态设置style属性,用以绑定内联样式。写法: 登录后复制 一、v-bind动态绑定…

    2025年4月1日 编程技术
    100
  • 实例解决vue中使用lang=“scss“出现的报错

    本篇文章给大家带来了关于vue的相关知识,其中主要介绍了关于使用 lang=“scss“ 报错的相关问题,这是因为当前sass-loader的版本太高,webpack编译时出现了错误,下面一起来看一下,希望对大家有帮助。 【相关推荐:vue…

    2025年4月1日
    100

发表回复

登录后才能评论