vue----- watch监听$attrs 的注意事项

目录

前言

原因分析 

解决方案

总结


前言

在 Vue 开发过程中,如遇到祖先组件需要传值到孙子组件时,需要在儿子组件接收 props ,然后再传递给孙子组件,通过使用 v-bind="$attrs" 则会带来极大的便利,但同时也会有一些隐患在其中。

可以看到,当我们在输入框输入值的时候,只有修改到 input 字段,从而更新父组件,而子组件的 props test 则是没有修改的,按照 谁更新,更新谁 的标准来看,子组件是不应该更新触发 updated 方法的, 

原因分析 

首先介绍一个前提,就是 Vue 在更新组件的时候是更新对应的 data 和 props 触发 Watcher 通知来更新渲染的。
每一个组件都有一个唯一对应的 Watcher ,所以在子组件上的 props 没有更新的时候,是不会触发子组件的更新的。当我们去掉子组件上的v-bind="$attrs"时可以发现, updated 钩子不会再执行,所以可以发现问题就出现在这里。


Vue 源码中搜索 $attrs ,找到 src/core/instance/render.js 文件:

export function initRender (vm: Component) {// ...defineReactive(vm, '$attrs', parentData && parentData.attrs || emptyObject, null, true)defineReactive(vm, '$listeners', options._parentListeners || emptyObject, null, true)
}

可以看到在 initRender 方法中,将 $attrs 属性绑定到了 this 上,并且设置成响应式对象

解决方案

方案一 判断值是否完全相等

<template><Child v-bind="attrsCopy" />
</template><script>
import _ from 'lodash';
import Child from './Child';export default {name: 'Child',components: {Child,},data() {return {attrsCopy: {},};},watch: {$attrs: {handler(newVal, value) {if (!_.isEqual(newVal, value)) {this.attrsCopy = _.cloneDeep(newVal);}},immediate: true,},},
};
</script>

2、通过props 接收info,并对info进行监听,就不存在这个问题

info:{handler(newV,old) {console.log('info改变了,触发')},deep: true,immediate: true,
}1、 基本数据类型
只有值改变时才触发watch
2、引用数据类型
同一个引用,内容改变,触发;
引用地址变化,触发;
watch内部的判断是:
不同的对象都不相等, 即使内部数据一样,对象(引用数据类型,如数组)只有引用地址一样才是相同的比如:对象浅拷贝,内部数据是同一个引用
var obj1 = {'a':{name: 123},'b':{name: 45}
}
var obj2 = {...obj1}
console.log(obj1.a === obj2.a)  // true

总结

在子组件有v-bind="$attrs",就会在 initRender 方法中,将 $attrs 属性绑定到了 this 上,并且设置成响应式对象。Vue 通过 Object.defineProperty 方法进行依赖收集, 我们在访问 $attrs 时,它( dep)会将 $attrs 所在的 Watcher 收集到 dep 的 subs 里面,从而在设置时进行派发更新notify(),通知视图渲染。

 Object.defineProperty(obj, key, {set: function reactiveSetter (newVal) {const value = getter ? getter.call(obj) : val/* eslint-disable no-self-compare */if (newVal === value || (newVal !== newVal && value !== value)) {return}/* eslint-enable no-self-compare */if (process.env.NODE_ENV !== 'production' && customSetter) {customSetter()}if (setter) {setter.call(obj, newVal)} else {val = newVal}childOb = !shallow && observe(newVal)dep.notify()}})

$attrs的依赖收集发生在v-bind中, 通过vue-template-compiler 编译源代码即可发现。
所以当 input 中 v-model 的值更新时,触发 set 通知更新,而在更新组件时调用的 updateChildComponent 方法中会对 $attrs 进行赋值。

const compiler = require('vue-template-compiler');const result = compiler.compile(// `//   <div :test="test">//     <p>测试内容</p>//   </div>// ``<div v-bind="$attrs"><p>测试内容</p></div>
`
);console.log(result.render);// with (this) {
//   return _c(
//     'div',
//      { attrs: { test: test } },
//      [
//        _c('p', [_v('测试内容')])
//       ]
//   );
// }// with (this) {
//   return _c(
//     'div',
//      _b({}, 'div', $attrs, false),
//      [
//        _c('p', [_v('测试内容')])
//       ]
//   );
// }

所以会触发 $attrs 的 set ,导致它所在的 Watcher 进行更新,也就会导致子组件更新了。而如果没有绑定 v-bind="$attrs" ,则虽然也会到这一步,但是没有依赖收集的过程,就无法去更新子组件了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/9939.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

设计模式 六大原则之单一职责原则

文章目录 概述代码例子小结 概述 先看下定义吧&#xff0c;如下&#xff1a; 单一职责原则的定义描述非常简单&#xff0c;也不难理解。一个类只负责完成一个职责或者功能。也就是说在类的设计中&#xff0c; 我们不要设计大而全的类,而是要设计粒度小、功能单一的类。 代码例…

灯珠CCD或CMOS成像RGB数据 光谱重建

1. 源由 本文主要为了通过摄像头CCD或者CMOS传感器对灯珠成像数据分析、重建灯珠可见光范围光谱数据的研究&#xff0c;从原理和方法上论证可行性。 随着照明技术迅猛发展&#xff0c;LED技术日渐成熟。LED产品由于具备经久耐用、节能且价格低等优势&#xff0c;已成为照明行…

传输层之 TCP 协议

TCP协议段格式 源/目的端口号&#xff1a;表示数据是从哪个进程来&#xff0c;到哪个进程去。 序号&#xff1a;发送数据的序号。 确认序号&#xff1a;应答报文的序号&#xff0c;用来回复发送方的。 4 位首部长度&#xff1a;一个 TCP 报头&#xff0c;长度是可变的&#xff…

2024年汉字小达人活动还有4个多月开赛:来做18道历年选择题备考吧

不出特殊情况的话&#xff0c;距离2024年第11届汉字小达人比赛还有4个多月的时间&#xff0c;如何利用这段时间有条不紊地备考呢&#xff1f;我的建议是两手准备&#xff1a;①把小学1-5年级的语文课本上的知识点熟悉&#xff0c;重点是字、词、成语、古诗。②把历年真题刷刷熟…

脆皮之“指针和数组的关系”

文章目录 1. 数组名的理解2. 使用指针访问数组3. 一维数组传参的本质4. 冒泡排序5. 二级指针6. 指针数组7. 指针数组模拟二维数组 hello&#xff0c;大家好呀&#xff0c;窝是脆皮炸鸡。这一期是关于数组和指针的&#xff0c;我觉得并不是很难&#xff0c;但是我觉着下一期可能…

自定义el-select下拉菜单的内容以及数据回显的内容

最终的效果 下拉选项的自定义内容好实现&#xff0c;因为他有默认插槽&#xff0c;所以直接在el-option标签里面写自定义内容就可以实现 <el-selectref"seriesBorderTypeRef"class"series-border-type"change"changeSeriesBorderType"v-model…

ESLint: Unexpected ‘debugger‘ statement.(no-debugger)(debugger报红)

ESLint: Unexpected debugger statement.(no-debugger) 解决办法&#xff1a; 找到.eslintrc.js文件中rules的no-debugger更改为0即可

gpustat 不能使用问题

突然间就不能用了&#xff0c;可能是环境出了问题&#xff0c;如果GPU没问题的话&#xff0c;那么换个环境重新安装试一下&#xff08;pip install gpustat&#xff09;&#xff0c;目前是换个环境就可以了&#xff08;做个笔记&#xff09;

信息系统项目管理师0101:项目建议与立项申请(7项目立项管理—7.1项目建议与立项申请)

点击查看专栏目录 文章目录 第七章 项目立项管理7.1项目建议与立项申请1.立项申请概念2.项目建议书内容记忆要点总结第七章 项目立项管理 项目立项管理是对拟规划和实施的项目技术上的先进性、适用性,经济上的合理性、效益性,实施上的可能性、风险性以及社会价值的有效性、可…

镜舟科技亮相2024中国移动算力网络大会、Qcon、DTC等多项活动

在刚刚过去的 4 月份&#xff0c;镜舟科技受邀参与一系列技术交流活动&#xff0c;与移动云、金科创新社、infoQ、墨天轮、开科唯识等媒体及合作伙伴展开积极交流&#xff0c;并分享其在数据技术、金融等垂直行业领域的创新实践&#xff0c;从产业侧、业务侧、技术侧洞察需求、…

idea-自我快捷键-2

1. 书签 创建书签&#xff1a; 创建书签&#xff1a;F11创建特色标记书签&#xff1a;Ctrl F11快速添加助记符书签&#xff1a;ctrl shift 数字键 查看书签&#xff1a; shift F11快速定位到助记符书签&#xff1a;Ctrl 数字键 删除书签&#xff1a; delete 2. 自动…

【最新点云数据增强综述】深度学习点云数据增强技术的进展

深度学习(DL)已成为点云分析任务(如检测、分割和分类)的主流和有效方法之一。为了减少深度学习模型训练过程中的过拟合,提高模型性能,尤其是在训练数据的数量和/或多样性有限的情况下,增强往往至关重要。虽然各种点云数据增强方法已被广泛应用于不同的点云处理任务中,但…

docker搭建mysql集群实现主从复制

前言 随着业务的增长&#xff0c;一台数据服务器已经满足不了需求了&#xff0c;负载过重。这个时候就需要减压了&#xff0c;实现负载均衡和读写分离&#xff0c;一主一丛或一主多从。 主服务器只负责写&#xff0c;而从服务器只负责读&#xff0c;从而提高了效率减轻压力。 …

融资融券概念和操纵流程,案例解析

融资融券是一种金融工具&#xff0c;它允许投资者在证券市场上进行杠杆交易。简单来说&#xff0c;融资就是借钱买股票&#xff0c;融券就是借股票卖出。这种交易方式可以帮助投资者在短期内获得更高的收益&#xff0c;但同时也伴随着较高的风险。 案例背景&#xff1a; 假设…

基于VOLOPV2的自动驾驶环境感知系统

基于VOLOPV2的自动驾驶环境感知系统是一个复杂的系统&#xff0c;它主要负责实时检测并识别周围环境中的各种物体和信息&#xff0c;为自动驾驶车辆提供必要的感知数据。以下是对该系统的一个简要介绍&#xff1a; 环境感知是自动驾驶系统中的一个关键部分&#xff0c;它依赖于…

静态分析-RIPS-源码解析记录-03

既然有源码可以debug&#xff0c;那么直接跑测试用例&#xff0c;来跟踪处理逻辑感觉比直接看代码理逻辑更快一些&#xff0c;尤其是涉及到了扫描阶段&#xff0c;不然不容易弄清某刻某个变量的取值。 对于所有漏洞而言&#xff0c;都是由sink点到source点检测是否有过滤函数&…

数据库管理-第187期 23ai:怎么用SQL创建图(20240510)

数据库管理187期 2024-05-10 数据库管理-第187期 23ai:怎么用SQL创建图&#xff08;20240510&#xff09;1 安装PGX1.1 数据库配置对应用户1.2 使用RPM包安装Graph Server1.3 安装Oracle Graph Client1.4 访问PGX页面 2 SQL Property Graph2.1 创建SQL属性图2.2 关于点和边图元…

副业兼职没那么难,视频号带货,1天稳定500,适合新手操作

向大家推荐一个项目&#xff1a;视频号书单号带货玩法。我已经实践了一段时间&#xff0c;并成功售出了1200多单&#xff0c;赚取了2万多元。这个项目表现相当出色&#xff0c;强烈推荐给大家&#xff01; 周周近财&#xff1a;让网络小白少花冤枉钱&#xff0c;赚取第一桶金 …

[机器学习-03] Scikit-Learn机器学习工具包学习指南:主要功能与用法解析

&#x1f3a9; 欢迎来到技术探索的奇幻世界&#x1f468;‍&#x1f4bb; &#x1f4dc; 个人主页&#xff1a;一伦明悦-CSDN博客 ✍&#x1f3fb; 作者简介&#xff1a; C软件开发、Python机器学习爱好者 &#x1f5e3;️ 互动与支持&#xff1a;&#x1f4ac;评论 &…

芋道系统springcloud模块启动报错,枚举类不能为空

问题描述&#xff1a; Error starting ApplicationContext. To display the conditions report re-run your application with debug enabled. 2024-05-10 15:50:15.756 | ERROR 9120 | main [TID: N/A] o.s.b.d.LoggingFailureAnalysisReporter | ************************…