关于之前封装Sku组件异步获取数据的问题思考

2023-11-07

使用watchEffect来监听父组件传来的goods

为什么我会用watchEffect,起初我的想法是:我需要生成数据字典并且初始化数据这两个函数当中都会用到很多的goods中的数据,如果使用watch监听要设置岂不是很麻烦?但是其实后面发现watch要更好一点,这两个侦听器里的回调我们只需要调用一次就好(初始化数据),并不需要监听里面的各种数据。

场景

// 初始化状态,可否选中
const initDisabledState = (specs, pathMap) => {
  specs.forEach(spec => {
    spec.values.forEach(value => {
      if(pathMap[value.name]) { // 如果数据字典中有该字段
        value.disabled = false
      } else { // 数据字典中没有该字段
        value.disabled = true
      }
    })
  })
}
watchEffect(() => {
  pathMap = props.goods.specs && generatedPathDictionary(); // 生成一个数据字典
  props.goods.specs && initDisabledState(props.goods.specs, pathMap) // 初始化disabled
})

以上代码是对我项目中关键性代码的提前。

因为第一次执行的时候还未拿取到数据,所以我在调用这两个函数的时候加了一个判断,避免报错;

上面中的 initDisabledState 函数里面会使用到 props.goods.specs 中的数据,并且会给其中里面的属性添加 disabled 属性并赋值。经过我的测试发现:watchEffect 只会执行两次:第一次是该侦听器的立即执行,第二次是接收到了父组件传来的值出发了 侦听器的回调。此后我们改变 disabled 的值并不会触发侦听器中的回调,这是由于什么原因呢?

为什么不会持续触发监听的原因及论证代码

起初我是考虑了是因为我们给对象中添加了一个新的属性的缘故,以下是我的测试代码来验证是否属实:

// 先定义一个变量,设置了一个arr属性的原因是尽可能模拟上面代码中的场景(详情见源码,此处未列举完毕)
let testObj = reactive({arr: [
  {name: 'a'},
  {name: 'a'},
  {name: 'a'},
]})
watchEffect(() => {
  testObj.arr.forEach(item => {
	// 原对象中没有该属性
    item.age = 12
  })
  console.log('执行了'); // 控制台中只会打印一次,证明后续改变age的值并没有被监听到
})
setTimeout(() => {
  // 更改元素的属性值
  testObj.arr[0].age = 111111
}, 2000)

结论:以上代码证明并不是新添加一个属性的缘故

那是否是因为我们对该属性直接进行了一个赋值的行为呢?测试代码如下:

let testObj = reactive({arr: [
  {name: 'a'},
  {name: 'a'},
  {name: 'a'},
]})
watchEffect(() => {
  testObj.arr.forEach(item => {
    console.log(item.age);
  })
  console.log('执行了'); // 执行2次,说明:监听到了age的改变
})
setTimeout(() => {
  testObj.arr[0].age = 111111
}, 2000)

结论:经过测试发现确实是因为赋值行为,该行为并不会引起监听器(watchEffect,watch)的监听。

但是以上的测试还有点不严谨:是否是因为我们给对象添加了一个新的属性的缘故,所以我有进行了下面的测试:

let testObj = reactive({arr: [
  {name: 'a'},
  {name: 'a'},
  {name: 'a'},
]})
watchEffect(() => {
  testObj.arr.forEach(item => {
    item.name = 'b'
  })
  console.log('执行了'); // 依旧值打印一次,说明没有监测name的改变
})
setTimeout(() => {
  testObj.arr[0].name = 111
}, 2000)

证明上面的结论确实是正确的。

使用watch来监听父组件传来的goods

watch(() => props.goods.specs, () => {
  pathMap = generatedPathDictionary();
  initDisabledState(props.goods.specs, pathMap)
})

只在初始化的时候执行一次,就已经ok了。

回顾

刚开始就是因为对项目中的需求没有理解(只需要初始化一次数据就可以)好,并且对watch和watchEffect没有理解好,并且代码中使用watch会有错误,可能是因为我自己使用了深度监听(导致disabled每次改变都要触发侦听器,所以页面每次都要初始化,导致渲染不是预期的那样)的缘故,从而误以为是因为watch不可用。哎,这么简单的事情搞了半天,好歹还是有收获。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

关于之前封装Sku组件异步获取数据的问题思考 的相关文章

随机推荐

  • npm常用命令

    查看npm版本 npm v 查看所有模块版本 npm version 搜索包 npm search 包名 安装包 i是install的缩写 npm i 包名 删除包 r是remove的缩写 npm r 包名 安装包并添加到依赖中 npm i
  • 计算机保护插件无法安装,电脑无法安装ActiveX控件怎么办

    ActiveX控件是网站常用的一款网页辅助工具 有时候我们可能需要安装它 但是却发现浏览器阻止了它安装 那么你知道电脑无法安装ActiveX控件怎么办吗 下面是学习啦小编整理的一些关于电脑无法安装ActiveX控件的相关资料 供你参考 电脑
  • flask中路由函数定义中遇到的问题

    flask的路由功能很强大 可以很清晰明了的定义出需要的路由函数 但是由于python语言的弱类型设计引来了一些不易发现的问题 app route task get methods GET def get tasks get the tas
  • python字符串转日期_使用Python将字符串转换为格式化的日期时间字符串

    我正在尝试将字符串 20091229050936 转换为 2009年12月29日 UTC gt gt gt import time gt gt gt s time strptime 20091229050936 Y m d H M S gt
  • python3 [爬虫入门实战]爬虫之scrapy爬取游天下南京短租房存mongodb

    总结 总的来说不是很难 只是提取的字段有些多 总共获取了一个120多个南京房租信息 1 爬取的item coding utf 8 Define here the models for your scraped items See docum
  • 《重构 - 改善既有代码的设计》总结

    1 重构 第一个示例 重构前 先检查自己是否有一套可靠的测试集 这些测试必须有自我验证能力 TDD 重构技术就是以微小的步伐修改程序 如果犯下错误 很容易便可发现它 傻瓜都能写出计算机可以理解的代码 唯有能写出人类容易理解的代码的 才是优秀
  • 元宇宙不是Web3

    个人对元宇宙的定义为 大规模 可互操作的网络 能够实时渲湘3D虚拟世界 借助大量连使性数据 如身份 历史 权利 对象 通信和支付等 可以让无限数量的用户体脸实时同步和持续有效的在场感 现在 你应该能理解我为何会给出这样的定义了 许多人可能会
  • 使用Junit进行单元测试超详细,这你还学不会?

    单元测试 从字面上来看就是对某一个功能单元进行测试 测试其功能是否正常 也就是说在给定的输入参数情况下 测试其结果的正确性 当这几天又重新温顾这一章节 我马上想起了前几天较劲脑静通过其测试用例的场景 一 介绍 1 Java中的最小功能单元是
  • react实现Modal弹窗

    一 Dialog js文件 import React useMemo useEffect useState from react import ReactDOM from react dom 需要把元素渲染到组件之外 用 createPor
  • git通过http的方式下载和提交代码

    之前一直用git的SSH方式下载代码 唯一的缺点可能就是需要建立SSH秘钥 需要额外生成一个密钥 然后在下载和提交代码的时候都需要输入秘钥 才能操作 时间长了可能就忘了密码 今天在做项目提交的时候就出现了这种情况 密码怎么试都不对 于是弃用
  • 理解不同加密币的要点(一)—— 共识机制

    一 加密货币分类 一 价值层面 与实体资产绑定的代币 为了因应市场需求而生 与实体资产做挂钩的代币 也就是我们说的稳定币 例如与美元做挂钩的USDT TUSD PAX与USDC等 仰赖网络共识的代币 代币价值仰赖网路上市场共识的代币 基本上
  • Java使用流去除集合中某个字段为空的对象

    文章目录 0 写在前面 1 情景复刻 2 解决方案 3 写在最后 0 写在前面 最近写了一些业务逻辑 调试的时候总会报空指针异常 Java中空指针异常是危险恐怖分子 最好不要碰见他 所以有些时候 处理集合中的数据时 特定情况下需要略过一些数
  • python在两行中分别输入一个字符串s和整数n,定义一个函数将字符串s循环向右移动n位

    解题思路 将字符串转为列表处理 123456 1 2 3 4 5 6 将列表重复两遍 1 2 3 4 5 6 1 2 3 4 5 6 删去前面和后面多余的数字即可 4 5 6 1 2 3 4 5 6 4 5 6 1 2 3 问题描述 在两行
  • MySQL修改和删除索引(DROP INDEX)

    在 MySQL 中修改索引可以通过删除原索引 再根据需要创建一个同名的索引 从而实现修改索引的操作 基本语法 当不再需要索引时 可以使用 DROP INDEX 语句或 ALTER TABLE 语句来对索引进行删除 1 使用 DROP IND
  • 小智AI chatgpt的功能是什么

    ChatGPT是一种基于GPT 3 5架构的大型语言模型 由OpenAI开发 它是一种聊天机器人 能够回答各种问题 提供有用的信息和娱乐 ChatGPT的工作原理非常简单 当用户输入问题或话题时 ChatGPT会自动根据语境和关键字生成响应
  • Idea SpringBoot多模块项目打包血泪史

    本文主要介绍基于Idea的SpringBoot多模块打包中遇到的各种问题以及解决方法 基本概况介绍 小弟之前是用的myeclipse进行的开发 但是在建立多模块的时候却错误的使用了web archtype 然后强转的SpringBoot 在
  • CentOS 6和Centos 7 虚拟机 关闭防火墙

    Centos 7 虚拟机 关闭防火墙 https blog csdn net preserveXing article details 127076756 CentOS 6 防火墙的关闭 关闭其服务即可 查看CentOS防火墙信息 etc
  • CDN的加速原理

    CDN的加速原理是什么 CDN Content Delivery Network 内容分发网络 是构建在现有互联网基础之上的一层智能虚拟网络 通过在网络各处部署节点服务器 实现将源站内容分发至所有CDN节点 使用户可以就近获得所需的内容 C
  • Centos8(7)安装tomcat9以及常见用法

    1 安装jdk tomcat9可以工作在jdk8以上的版本 所以可以安装jdk8或是jdk11 dnf install java 11 openjdk centos8 yum install java 11 openjdk centos7
  • 关于之前封装Sku组件异步获取数据的问题思考

    使用watchEffect来监听父组件传来的goods 为什么我会用watchEffect 起初我的想法是 我需要生成数据字典并且初始化数据这两个函数当中都会用到很多的goods中的数据 如果使用watch监听要设置岂不是很麻烦 但是其实后