位置: IT常识 - 正文

Vue3中watch监听对象的属性值,监听源必须是一个getter函数(vue watch监听localstorage变化)

编辑:rootadmin
Vue3中watch监听对象的属性值,监听源必须是一个getter函数 Vue3 中使用 watch 侦听对象中的具体属性1.前言<script lang="ts" setup>// 接受父组件传递的数据 const props = defineProps({ test: { type: String, default: '' } }) // 使用 watch 侦听 props 中的 test 属性 watch( // 这种写法不会侦听到 props 中 test 的变化 props.test, () => { console.log("侦听成功") } ) watch( // 这种写法会侦听到 props 中 test 的变化 () => props.test, () => { console.log("侦听成功") } )</script>

推荐整理分享Vue3中watch监听对象的属性值,监听源必须是一个getter函数(vue watch监听localstorage变化),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:vue的watch监听props,vuewatch监听对象及对应值的变化,vuewatch监听data里的数据,vue watch监听vuex数据,vuewatch监听对象及对应值的变化,vue3中watch监听对象的变化,vuewatch监听对象及对应值的变化,vue3中watch监听对象的变化,内容如对您有帮助,希望把文章链接给更多的朋友!

watch 的基本用法

watch() 默认是懒侦听的,即仅在侦听源发生变化时才执行回调函数

第一个参数:侦听源,侦听源可以是一下几种

一个函数,返回一个值一个 ref一个响应式对象(reactive)或是由以上类型的值组成的数组

第二个参数:侦听源发生变化时要触发的回调函数。

​ (newValue, oldValue) => { /* code */}

​ 当侦听多个来源时,回调函数接受两个数组,分别对应源数组中的新值和旧值

Vue3中watch监听对象的属性值,监听源必须是一个getter函数(vue watch监听localstorage变化)

​ ( [ newValue1, newValue2 ] , [ oldValue1 , oldValue2 ]) => {/* code */}

第三个参数:可选对象,可以支持一下这些选项

immediate:侦听器创建时立即触发回调deep:如果源是一个对象,会强制深度遍历,以便在深层级发生变化时触发回调函数flush:调整回调函数的刷新时机onTrack / onTrigger:调试侦听器的依赖2. 原因

因为watch的侦听源只能是上面的4中情况

const obj = reactive({ count: 0 })// 错误,因为 watch() 中的侦听源是一个 number,最终 source 返回的 getter 函数是一个空,所以就得不到侦听的数据watch(obj.count, (count) => { console.log(`count is: ${count}`)})// 正确,主要思想是,将侦听源转化为以上4种类型(转化为getter函数是最简单方便的)watch( () => obj.count, (count) => { console.log(`count is: ${count}`) })3.watch源码分析export function watch<T = any, Immediate extends Readonly<boolean> = false>( source: T | WatchSource<T>, cb: any, options?: WatchOptions<Immediate>): WatchStopHandle { if (__DEV__ && !isFunction(cb)) { warn( `\`watch(fn, options?)\` signature has been moved to a separate API. ` + `Use \`watchEffect(fn, options?)\` instead. \`watch\` now only ` + `supports \`watch(source, cb, options?) signature.` ) } return doWatch(source as any, cb, options)}

从源码中可以看出,watch接收三个参数:source侦听源、cb回调函数、options侦听配置,最后会返回一个doWatch

4.doWatch源码分析function doWatch( source: WatchSource | WatchSource[] | WatchEffect | object, cb: WatchCallback | null, { immediate, deep, flush, onTrack, onTrigger }: WatchOptions = EMPTY_OBJ): WatchStopHandle { // ...// 当前组件实例const instance = currentInstance// 副作用函数,在初始化effect时使用let getter: () => any// 强制触发侦听let forceTrigger = false// 是否为多数据源。let isMultiSource = false}

doWatch依然接受三个参数:source侦听源、cb回调函数、options侦听配置

这里着重对侦听源的源码进行分析(source标准化)

如果source是ref类型,getter是个返回source.value的函数,forceTrigger取决于source是否是浅层响应式。if (isRef(source)) { getter = () => source.value forceTrigger = isShallow(source)}如果source是reactive类型,getter是个返回source的函数,并将deep设置为true。 当直接侦听一个响应式对象时,侦听器会自动启用深层模式if (isReactive(source)) { getter = () => source deep = true}

例子

<template> <div class="container"> <h2>obj---{{ obj }}</h2> <button @click="changeName">修改名字</button> <button @click="changeAge">修改年龄</button> </div></template><script lang="ts" setup>import { reactive, watch } from "vue";const obj = reactive({ name: "张三", age: 18,});const changeName = () => { obj.name += "++";};const changeAge = () => { obj.age += 1;};// obj 中的任一属性变化了,都会被监听到watch(obj, () => { console.log("变化了");});</script>如果source是个数组,将isMultiSource设为true,forceTrigger取决于source是否有reactive类型的数据,getter函数中会遍历source,针对不同类型的source做不同处理。if (isArray(source)) { isMultiSource = true forceTrigger = source.some(isReactive) getter = () => source.map(s => { if (isRef(s)) { return s.value } else if (isReactive(s)) { return traverse(s) } else if (isFunction(s)) { return callWithErrorHandling(s, instance, ErrorCodes.WATCH_GETTER) } else { __DEV__ && warnInvalidSource(s) } })}如果source是个function。存在cb的情况下,getter函数中会执行source,这里source会通过callWithErrorHandling函数执行,在callWithErrorHandling中会处理source执行过程中出现的错误;不存在cb的话,在getter中,如果组件已经被卸载了,直接return,否则判断cleanup(cleanup是在watchEffect中通过onCleanup注册的清理函数),如果存在cleanup执行cleanup,接着执行source,并返回执行结果。source会被callWithAsyncErrorHandling包装,该函数作用会处理source执行过程中出现的错误,与callWithErrorHandling不同的是,callWithAsyncErrorHandling会处理异步错误。if (isFunction(source)) { if (cb) { getter = () => callWithErrorHandling(source, instance, ErrorCodes.WATCH_GETTER) } else { // watchEffect getter = () => { // 如果组件实例已经卸载,直接return if (instance && instance.isUnmounted) { return } // 如果清理函数,则执行清理函数 if (cleanup) { cleanup() } // 执行source,传入onCleanup,用来注册清理函数 return callWithAsyncErrorHandling( source, instance, ErrorCodes.WATCH_CALLBACK, [onCleanup] ) } }}其他情况getter会被赋值为一个空函数getter = NOOP__DEV__ && warnInvalidSource(source)5.总结

其实,source标准化主要是根据source的类型,将其变成 getter 函数

如果 source是ref对象,则创建一个访问 source.value 的getter函数如果source是一个reactive对象,则创建一个访问source的getter函数,并将deep设置为true如果source 是一个函数,则会进一步进行判断第二个参数cb是否存在。最后的getter就是一个简单的对source封装的函数如果source是一个数组,则会对数组中的每个元素进行判断并且返回相应的getter函数。最后返回一个各种getter函数封装成的一个数组

整个doWatch 方法中的逻辑主要分为一下几步:

通过getter函数来获取数据源的值通过job方法来调用传入watch中的cbjob中通过调用runner,runner调用getter获取数据源新值doWatch中闭包缓存了数据源的旧值将新旧值作为参数调用cb将job作为activeEffect的scheduler方法,在后续的数据修改导致的trigger中调用首次调用,传入了immediate调用job,未传入调用runner,以数据源为被观察者收集依赖实现响应式

侦听的第一步就是需要通过正确的getter函数去获取侦听源的值,所以在使用watch侦听数据时,务必保证侦听源的类型是符合官方规定的类型的

本文链接地址:https://www.jiuchutong.com/zhishi/297696.html 转载请保留说明!

上一篇:Javascript 模块导入导出(import export)(javascript导入包)

下一篇:学会在Vue项目中插入高德地图JS API与地图的相关设置,看这一篇就够了~(保姆级精简教学)(vue项目中技巧知识点)

  • 珍惜论坛发帖让它成为一种流行

    珍惜论坛发帖让它成为一种流行

  • qq设置三天可见怎么设置(qq设置三天可见,怎么让一个人看)

    qq设置三天可见怎么设置(qq设置三天可见,怎么让一个人看)

  • 快手100快币多少分(快手100个快币值多少钱)

    快手100快币多少分(快手100个快币值多少钱)

  • 小度能连接电视吗(乐华电视怎么连接wifi看电视)

    小度能连接电视吗(乐华电视怎么连接wifi看电视)

  • 抖音钻卡如何赠送(抖音卡怎么赠送)

    抖音钻卡如何赠送(抖音卡怎么赠送)

  • 对方忙线中是啥意思(对方忙线中是啥情况)

    对方忙线中是啥意思(对方忙线中是啥情况)

  • 把一个人拉黑了还能收到信息吗(把一个人拉黑了能看到朋友圈吗)

    把一个人拉黑了还能收到信息吗(把一个人拉黑了能看到朋友圈吗)

  • 微型计算机的性能主要取决于(微型计算机的性能指标有多种,而最主要的应该是)

    微型计算机的性能主要取决于(微型计算机的性能指标有多种,而最主要的应该是)

  • 0xa00f4292相机错误如何修复(0xa00f4292相机错误 黑屏)

    0xa00f4292相机错误如何修复(0xa00f4292相机错误 黑屏)

  • 苹果耳机怎么看电量是否充满(苹果耳机怎么看电池还有多少电量)

    苹果耳机怎么看电量是否充满(苹果耳机怎么看电池还有多少电量)

  • 抖音拍照怎么是黑白的(抖音拍照怎么是横屏,怎么变竖屏)

    抖音拍照怎么是黑白的(抖音拍照怎么是横屏,怎么变竖屏)

  • apple watch 5防水吗(applewatch series 5防水)

    apple watch 5防水吗(applewatch series 5防水)

  • jkm一aloob华为什么型号(华为jkm-al00b)

    jkm一aloob华为什么型号(华为jkm-al00b)

  • 沾沾卡能复制全家福吗(沾沾卡可以指定沾哪张吗)

    沾沾卡能复制全家福吗(沾沾卡可以指定沾哪张吗)

  • ps怎么改图片格式(ps怎么改图片格式为透明)

    ps怎么改图片格式(ps怎么改图片格式为透明)

  • 性能模式有什么用(性能模式有什么区别)

    性能模式有什么用(性能模式有什么区别)

  • qq音乐最多几个人登录(qq音乐最多几个人登录一个账号)

    qq音乐最多几个人登录(qq音乐最多几个人登录一个账号)

  • a1524的iphone 6 plus是什么版本(a1524的iphone 6 plus可以用电信卡吗)

    a1524的iphone 6 plus是什么版本(a1524的iphone 6 plus可以用电信卡吗)

  • 小米mix2s如何提高网速(小米mix2s提升流畅教程)

    小米mix2s如何提高网速(小米mix2s提升流畅教程)

  • iphonex和xs手机壳通用吗(iphonex和xs手机壳可以共用吗)

    iphonex和xs手机壳通用吗(iphonex和xs手机壳可以共用吗)

  • nbr.exe - nbr是什么进程 有什么用(nbr是什么意思中文翻译)

    nbr.exe - nbr是什么进程 有什么用(nbr是什么意思中文翻译)

  • 【前端客栈】基于HTML、CSS、JavaScript的羊了个羊静态仿写页面小游戏(前端yck)

    【前端客栈】基于HTML、CSS、JavaScript的羊了个羊静态仿写页面小游戏(前端yck)

  • js跳转(js跳转网页)(js 跳转网页)

    js跳转(js跳转网页)(js 跳转网页)

  • 费用的进项税额可以抵扣吗
  • 纳税申报操作视频
  • 住房公积金发票
  • 劳动合同和劳务合同有什么区别 举例
  • 个税受雇日期以哪个日期
  • 生产经营所得如何缴纳个人所得税
  • 拆除固定资产的补偿款
  • 食堂购买食材明细表
  • 跨地区预缴税款需缴纳哪些
  • 在途物资的入账价值
  • 公司发生的业务可以转让给子公司嘛?
  • 城市维护建设税属于什么税种
  • 500元以下不需要发票
  • 拍卖所得房产计税依据
  • 基本户转移到别的银行怎么转移
  • 租赁发票多少点
  • 专项应付款会计科目代码
  • 本月发票有红充这月成本怎么做账?
  • 公司账户里的钱有利息吗
  • 鸿蒙 功能
  • 人力资源管理师考试时间
  • 怎么设置宽带开关网络
  • 企业接受母公司代为缴纳税款会计分录
  • 残疾人就业保障金有什么好处
  • php 文件系统
  • 企业 土地增值税
  • 皮丘拉湖畔的乌代布尔城市宫殿,印度 (© Chaiyun Damkaew/Getty Images)
  • php如何创建文件
  • 税局 不负责任
  • 前端解决跨域问题的8种方案(最新最全)
  • java编程入门基础教程
  • vue的常见面试题
  • 特征提取原理
  • ssl查询网站
  • free命令看到的内存
  • 短期借款转为长期借款引起的会计要素变化
  • 帝国cms目录
  • 织梦设置的关键词看不到
  • 无形资产资产处置损益和营业外收入
  • 出口货物离岸价差异原因说明表在电子税务局的位置
  • 交强险必须要买驾乘险才能投保
  • 进口产品销售需要交税吗
  • 事故赔偿给谁
  • sqlserver如何使用
  • 母公司合并子公司报表
  • 计提城建税的会计分录怎么写
  • 残保金逾期申报了补报会有罚款和滞纳金吗?
  • 社保扣款上月没扣费
  • 回购注销库存股的会计处理
  • 房地产企业扣除土地价款如何申报
  • 基金赎回可以赎回部分吗
  • 房地产企业所得税税负率是多少
  • sqlserver性能优化5种方式
  • Win8系统Smartscreen筛选器界面变灰无法设置的解决方法
  • win10怎么设置为win7模式
  • bios各项参数的意义
  • win10系统休眠唤醒屏幕变大怎么办
  • 自动批处理文件的名字是什么
  • os x 10.10.5
  • win7系统怎么卸载显卡驱动
  • 手写输入界面
  • linux常用命令find
  • win7耳机和外放一起响
  • win10输入法怎么添加美式键盘
  • bootstrap内容
  • bat批处理命令大全
  • qt搭建opencv
  • shell脚本解压tar文件
  • vue怎么实现多页面
  • scp 将数据从一台linux服务器复制到另一台linux服务器
  • arp欺骗防范方法
  • python 钉钉打卡定位
  • python app爬虫教程
  • 安卓 centos
  • 个体经营所得申报密码怎样设置
  • 四川省一般纳税人资格证明
  • 小规模纳税人开专票
  • 地税的发票是什么样
  • 2022年房产税减免政策疫情
  • 药品定价的三种形式
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设