关于之前封装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组件异步获取数据的问题思考 的相关文章

  • Vuejs2 Modal 与 vue-router 中的路线

    我正在尝试使用模态创建一条路由 当您使用路由器链接访问此路由器路径时 会在当前页面上方显示一个模态 或者如果我直接从 url 访问 则会出现上面带有模态的索引 例如 我在http localhost 个人资料 1 http localhos
  • 每次页面重新启动时,Firebase.auth().currentUser 都会变为 null

    我正在使用 firebase 身份验证与 vue 应用程序 每次登录用户后重新启动页面时 currentUser 都会变为 null firebase auth signInWithEmailAndPassword this email t
  • 如何以编程方式添加 Vue 3 组件?

    Vue 3 没有 Vue extend 方法 因此这里的示例不起作用 https css tricks com creating vue js component instances programmatically https css t
  • VueJS - 验证表单文件上传中的文件大小要求

    我正在使用 Bootstrap Vue 表单制作一个简单的表单 用户可以在其中上传文件 有没有办法验证使用 Vue 表单选择的文件的大小 我想阻止用户上传此类文件 我见过this https stackoverflow com questi
  • Vuejs ssr 检查用户是否针对每个请求进行了身份验证

    我正在为我的应用程序使用这个 ssr 样板 https github com vuejs vue hackernews 2 0 https github com vuejs vue hackernews 2 0 我不知道如何实现逻辑来检查每
  • node.js、vue.js 和express.js 堆栈开发

    我正在尝试使用 Linux 上的 Visual Studio Code IDE 使用 vue js express js 和 node js 创建一个 Web 应用程序 根据网上的一些文档 我读到安装 vue js 后 可以创建一个vue
  • VueJS - 访问已安装的存储数据

    我无法理解以下内容 我有一个store其中包含应用程序所需的变量 特别地 有一个globalCompanies哪些商店 globalCompanies current all currentName 在另一个组件中 我想执行以下操作 mou
  • 在 ES6 中使用 import 和 require 的正确方法是什么?

    关于 import 和 require 及其差异有多个问题 像这些 JavaScript 中的 import 和 require 有什么区别 https stackoverflow com questions 51373933 what i
  • 如何在Vue中提交表单,重定向到新路由并传递参数?

    我正在使用 Nuxt 和 Vue 我正在尝试提交表单 将用户重定向到包含提交的参数的新路由 发送 API 请求以获取一些数据 然后渲染该数据 我通过简单地将表单操作设置为新路径并手动将所有 URL 参数添加到 API 请求来实现此目的 首先
  • Vue.js 更改 {{ }} 标签

    我想改变 something by 在 Vue js 中 我怎样才能实现这一点 这可能吗 我在 AngularJS 中寻找的等效项 var app angular module app function interpolateProvide
  • Vue js - 在同一级别的两个组件内传递数据

    我有需要从一个传递的数据component1到另一个component2 我不使用vuex or router 组件树 Parent Component1 Component2 从一开始component1我发出 ajax 请求 检索信息并
  • 如何同时模拟Pinia和vue-i18n?

    我正在使用 Vue 3 的 Composition API 如下所示 store ts import ref Ref from vue import defineStore from pinia export const useStore
  • 不使用Vue可以使用Vuex吗? (Vuex 服务器端?)

    Vuex 抱怨如果不调用 Vue use Vuex 就无法创建新的 store 实例 虽然这通常没问题 但我正在摆弄使用同一商店编写后端 前端的想法 有人知道答案吗 Thanks TL DR 你可以在 Node 中完美使用 Vuex 无需浏
  • vue如何检测页面是否刷新?

    我尝试这样 created window addEventListener beforeunload function event event returnValue Write something this router push 像这样
  • 如何以编程方式启动 Vuetify 对话框并等待响应

    我对 Vue js 和 Vuetify 相当陌生 使用 AngularJS 好几年了 但我们公司正在转向 Vue js 我想要完成的是 当用户单击 登录 按钮时 它会执行一些检查 即用户名不能为空 并启动 Vuetify 对话框来提醒用户
  • 用变量字符串设置槽的简单方法?

    有许多slot例子 但没有克莱尔和简单 因为我需要 我需要类似的东西 var x Hello slot x 这就是我需要的 在一个具体的例子中 https jsfiddle net 2qdh3x3v https jsfiddle net 2
  • 错误:[vuex] 期望 string 作为类型,但发现未定义

    学习Vuex 我写了一个简单的登录页面示例项目 https github com vuejs vuex tree dev examples shopping cart和document https vuex vuejs org zh gui
  • 左侧导航菜单上部隐藏

    当滚动到页面最底部时 左侧导航菜单的顶部将被隐藏 The image before scrolling is shown below 滚动后的效果如下图 我不确定此问题的确切原因 因此我将不胜感激任何有关识别和解决该问题的建议或帮助 为了确
  • 在重复内容区域添加

    我有一个菜单组件 简单地说 它接受一个带有一系列选项的道具 并为每个选项在菜单中呈现一个项目 我希望能够根据用例自定义每个菜单项内的标记 因此我在菜单项元素内使用了占位符 你可以在这个中看到一个例子fiddle https jsfiddle
  • 将 CKEditor 5 与 nuxtjs 结合使用

    我正在尝试在我的 Nuxtjs 项目中导入 CKEditor 5 的自定义版本 并且我已经尝试了所有可能的方法来正确导入它 但没有一个对我有用 这是其中之一 let ClassicEditor let CKEditor if process

随机推荐

  • 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监听要设置岂不是很麻烦 但是其实后