踩坑实录(First Day)

2023 年一整年感觉我的进步都很小,所以自 2024 年起,我将专门开设专栏记录自己在工作期间踩过的所有坑,一来是为了有个记录,自己不会再踩,而来也是为了跟大家做一个分享,与大家进行讨论,提升自己的能力。

此为第一篇(2024 年 02 月 04 日)

问题一

问题背景:输入框输入数据后,关闭页签再次打开保留了上一次的数据。

问题描述:在 js 文件中定义了一个对象,以便对数据进行初始化,引入到需要使用的 vue 文件中,然后在 data 中定义一下。

下面是一个 demo 演示:

// index.js
exports const obj = {name: ''age: '',hobbies: ''
}
// 因为不确定后端会返回什么数据,所以此时我们都用空字符串进行初始化。// 补充:js 是弱类型语言,即使定义为空字符串,后期将其他类型的值赋值过去,都是可以的,但是这会导致数据类型不安全,最好是避免这种写法。
<!-- index.vue --><template><div><input v-model="obj.name" /><input v-model="obj.age" /><input v-model="obj.hobbies" /></div>
</template><script>import { obj } from './model/index.js'export default {name: 'index',data () {return {obj,}}}
</script>
  • 分析过程:

    1. 首先我们可以看到,在 js 中定义了一个 obj ,它是一个对象,也就是“引用数据类型”的数据,此时它在堆中开辟一部分空间存储这个对象,然后提供一个地址值,指向这个对象,然后在栈中生成一个变量 obj ,将这个地址值赋值给栈中的变量 obj 。

    2. 第二步我们看到是在 index.vue 文件中,通过 import 将这个变量引入进来。

    3. 第三步又将引入的这个变量在 data 中定义了一下,将他变成一个响应式数据。

    到此,我们的思路就已经很清晰了,在 data 中存储的是一个地址值,指向的永远是在 index.js 文件中定义的那个对象,我们通过双向绑定,输入框输入赋值等操作,操作的永远是那一个 obj 对象,而根据 js 的垃圾回收机制,我们可以得出,js 在内存中生成的全局变量,只要不刷新浏览器,那么他不会被销毁,好的,问题到这里就分析完成了。

    结论:是因为 引用数据类型存储的是地址值,导致操作的始终是同一个变量。

  • 解决思路:

    既然是因为引用数据类型指向的是同一个对象引起的,那我们是不是可以在 data 中定义的时候,深拷贝一下这个 obj 对象去解决呢?答案是:当然可以!

    <!-- index.vue --><template><div><input v-model="obj.name" /><input v-model="obj.age" /><input v-model="obj.hobbies" /></div>
    </template><script>import { obj } from './model/index.js'export default {name: 'index',data () {return {obj: JSON.parse(JSON.stringify(obj)),}}}
    </script>
    

    这样,我们就可以确保,每一次组件创建的时候,生成一份新的 obj 数据,而在组件销毁的时候,data 中的数据也会被销毁,问题就迎刃而解了~~~

问题二

问题背景:组长让解决控制台报错,于是在控制台看到了很多个 Invalid prop: custom validator check failed for prop "XXX" 的报错。大致看一眼就是说,XXX 变量没有通过校验。

问题描述:在子组件的 props 写了一个参数 XXX ,将他的 type 定义为了 String ,下面紧接着又写了一个 validate 自定义校验,然后在父组件中引用了子组件。

下面是一个 demo 演示:

<!-- subComponent.vue --><script>export default {name: 'subComponent',props: {identifying: {type: String,validator: (val) => {return ['zhangsan'].includes(val)}}}}
</script>
<!-- parentComponent --><template><subComponent :identifying="lisi"></subComponent>
</template><script>import subComponent from './subComponent.vue'export default {name: 'parentComponent',components: {subComponent}}
</script>
  • 分析过程:

    1. 首先,在子组件的 props 中定义了一个参数,父组件在使用子组件的时候,需要将这个参数传递过来,但是我们看到这个参数没有写 required: true ,所以这个参数不是必传的。下面又写了一个 validator ,就是说,这个参数的校验是自己自定义的,好家伙,这么高级。

    2. 不难看出,这个自定义校验函数的意思是,只要你传递过来的 identifying 是 ‘zhangsan’ ,那么就返回 true ,否则返回 false 。

    3. 接下来我们看到父组件使用的时候,传进去了一个 identifying 是 ‘lisi’ ,并不是组件想要的 ‘zhangsan’ ,那么那个自定义校验返回的就是 false ,校验不通过。

    4. 再回过头看一下我们的报错信息:‘Invalid prop: custom validator check failed for prop “identifying”’ ,翻译一下的结果是:无效道具:道具“正在识别”的自定义验证程序检查失败。但是这只是一个警告,并不会阻塞页面渲染。

    到此,问题的思路就已经很清晰了,自定义校验没有通过,也就是说,我们只要传了 identifying 参数,就一定会对它进行校验,判断它是否是 ‘zhangsan’ ,这样是很不合理的,因为这个组件的背景是一个公共组件,此处有两种场景,需要 ‘zhangsan’ 和 ‘lisi’ 都成立。

  • 解决思路:

    在这里,我提供两种方案进行解决:

    1. 在不改变 validator 自定义校验的情况下,让组件兼容 ‘lisi’ 的情况,只需要在自定义校验方法体内的数组中,加入 ‘lisi’。
    <!-- subComponent.vue --><script>export default {name: 'subComponent',props: {identifying: {type: String,validator: (val) => {return ['zhangsan', 'lisi'].includes(val)}}}}
    </script>
    
    1. 使用 props 的枚举【enum】。
    <!-- subComponent.vue --><script>export default {name: 'subComponent',props: {identifying: {type: String,enum: ['zhangsan', 'lisi']}}}
    </script>
    

    这里我们就需要考虑一个问题,如果改为采用 enum 的话,需不需要让这个参数改成必填?那我们就要去看两个条件:1. 在使用 validator 自定义校验的时候是不是必填。2. 自己公司的业务场景需要我们做什么。但是在我们公司这里的业务场景是必填的,它只有两个场景,而且必须符合某一个场景,所以在这里我就不考虑第一种条件,直接改为必填了。

声明:

作者只记录自己在公司踩过的坑,以及提供自己的解决思路,如果有误请联系作者进行修改,不接受以任何形式的诋毁谩骂。如果有更好的方案也可以联系作者进行讨论,互相学习。

如需转载请注明文章来源。

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

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

相关文章

力扣宝石补给

欢迎各位勇者来到力扣新手村&#xff0c;在开始试炼之前&#xff0c;请各位勇者先进行「宝石补给」。 每位勇者初始都拥有一些能量宝石&#xff0c; gem[i] 表示第 i 位勇者的宝石数量。现在这些勇者们进行了一系列的赠送&#xff0c;operations[j] [x, y] 表示在第 j 次的赠送…

QT 范例阅读:系统托盘 The System Tray Icon example

main.cpp QApplication app(argc, argv);//判断系统是否支持 系统托盘功能if (!QSystemTrayIcon::isSystemTrayAvailable()) {QMessageBox::critical(0, QObject::tr("Systray"),QObject::tr("I couldnt detect any system tray ""on this system.&qu…

利用jmeter完成简单的压力测试

Jmeter是一个非常好用的压力测试工具。Jmeter用来做轻量级的压力测试&#xff0c;非常合适&#xff0c;只需要十几分钟&#xff0c;就能把压力测试需要的脚本写好。 1、什么是压力测试 顾名思义&#xff1a;压力测试&#xff0c;就是 被测试的系统&#xff0c;在一定的访问压…

下载、安装Jenkins

进入官网 下载Jenkins https://www.jenkins.io 直接点击Download 一般是下长期支持版 因为它是java写的&#xff0c;你要运行它&#xff08;Jenkins.war&#xff09;肯定要有java环境 有两种方式去运行它&#xff0c;一种是下载Tomcat&#xff08;是很经典的java容器或者jav…

代码随想录day16 Java版 二叉树部分

404.左叶子之和 感觉就是遍历&#xff0c;遇到叶子结点就累加&#xff0c;试了下居然过了 class Solution {int sum 0;public int sumOfLeftLeaves(TreeNode root) {add(root);return sum;}void add(TreeNode root){if (root null) return;if (root.left ! null &&…

linux编译ffmpeg动态库

1&#xff0c;获取源码&#xff1a;git clone https://git.ffmpeg.org/ffmpeg.git 2&#xff0c;创建编译目录&#xff0c;并编译、安装&#xff0c; cd ffmpeg mkdir build cd build ../configure --prefix~/ffmpeg --enable-shared --enable-debug1 //configure后需要使…

深入探索C++ Move语义:现代编程中的性能革命

1. 引言 介绍C中的Move语义 Move语义是C11中引入的一个重要特性&#xff0c;它为C编程语言带来了显著的性能改进。在这之前&#xff0c;C只支持拷贝语义&#xff0c;即通过拷贝构造函数和拷贝赋值操作符来复制对象。Move语义通过允许"移动"而非"拷贝"资源…

Git版本管理工具(基础):这一篇基本能满足Git基本的使用需求了!

文章目录 Git01-什么是Git作用 02-使用Git03-Git仓库创建 04-Git的三个区域三个区域 05-Git文件状态06-Git暂存区使用07-Git回退版本08-删除文件 Git 01-什么是Git 答&#xff1a;他是一个免费开源的&#xff0c;分布式代码版本控制系统&#xff0c;帮助开发团队维护代码 作用…

三、消除分心的事物(Eliminating Distractions)

External Improvements 外部改进 1.Eliminating Distractions 一、消除分心的事物 Distractions are the most obvious problem when it comes to focus, and they are often the easiest to fix. In particular, you want to find an environment for focus that minimizes b…

爬虫工作量由小到大的思维转变---<第四十五章 Scrapyd 关于gerapy遇到问题>

前言: 本章主要是解决一些gerapy遇到的问题,会持续更新这篇! 正文: 问题1: 1400 - build.py - gerapy.server.core.build - 78 - build - error occurred (1, [E:\\项目文件名\\venv\\Scripts\\python.exe, setup.py, clean, -a, bdist_uberegg, -d, C:\\Users\\Administrat…

网络安全面试题收集

1 Web篇 1.1 什么是SQL注入攻击&#xff1f;如何防止SQL注入攻击&#xff1f; SQL注入攻击是指攻击者通过向Web应用程序的输入框中插入恶意SQL语句来执行未经授权的操作。防止SQL注入攻击的方法包括使用参数化查询和输入验证&#xff0c;以及避免使用动态SQL语句。 1.2 什么…

红队渗透靶机:TIKI: 1

目录 信息收集 1、arp 2、nmap 3、nikto 4、whatweb 目录探测 1、dirsearch 2、gobuster WEB web信息收集 searchsploit cms信息收集 ssh登录 提权 信息收集 1、arp ┌──(root㉿ru)-[~/kali] └─# arp-scan -l Interface: eth0, type: EN10MB, MAC: 00:0c:2…

数据结构-数组

1.容器 容器用于容纳元素集合&#xff0c;并对元素集合进行管理和维护&#xff0e; 传统意义上的管理和维护就是&#xff1a;增&#xff0c;删&#xff0c;改&#xff0c;查&#xff0e; 我们分析每种类型容器时&#xff0c;主要分析其增&#xff0c;删&#xff0c;改&#xf…

Matlab 移动最小二乘求解仿射变换

文章目录 一、简介二、实现代码三、实现效果参考文献一、简介 在现实生活中,我们常常应用一些刚性的变换来实现物体的旋转平移,对于非刚性的变换我们都没有在意,其实这种变换也是无处不在的,如我们经常看的动画就可以通过一些非刚性的变换达到一些非常夸张的效果。这里,我…

iMazing 3中文版双平台版本同步,iOS 设备在 Windows 上也能自动备份了

自从WWDC 2019 宣布 iTunes 退役后&#xff0c;也许很多小伙伴都对「上位者」iMazing 有所耳闻。 这款设计更加人性化、功能细致强大的 iOS 备份管理工具。 iMazing 支持在 Windows 及 Mac 上运行&#xff0c;而这个月 Windows 版本更新至 2.17. 之后&#xff0c;iMazing 的双…

Kubernetes基础(十一)-CNI网络插件用法和对比

1 CNI概述 1.1 什么是CNI&#xff1f; Kubernetes 本身并没有实现自己的容器网络&#xff0c;而是借助 CNI 标准&#xff0c;通过插件化的方式来集成各种网络插件&#xff0c;实现集群内部网络相互通信。 CNI&#xff08;Container Network Interface&#xff0c;容器网络的…

如何构建起自己的伦敦银交易系统?

投资者在市场这个江湖中行走&#xff0c;就需要有一技防身&#xff0c;不然很容易会被市场的风险所淹没&#xff0c;这个“一技”指的就是伦敦银交易系统。如果投资者要构建起自己的伦敦银交易系统&#xff0c;应该从哪几个方面着手呢&#xff1f;下面我们就来讨论一下。 分析方…

103 C++ 内存高级话题 重载全局new,delete,定位new以及重载等

一 重载全局 operator new 和 operator delete 操作符 前面是看到了 我们在某一个类中 重写了 operator new 和 operator delete。 实际上也可以 重载全局的 operator new 和 operator delete。 重载了全局的 operator new 和 operator delete 会对整个.cpp中的所有其作用&a…

Jenkins(本地Windows上搭建)上传 Pipeline构建前端项目并将生成dist文件夹上传至指定服务器

下载安装jdk https://www.oracle.com/cn/java/technologies/downloads/#jdk21-windows 下载jenkins window版 双击安装 https://www.jenkins.io/download/thank-you-downloading-windows-installer-stable/ 网页输入 http://localhost:8088/ 输入密码、设置账号、安装推…

2024-2-4-复习作业

源代码&#xff1a; #include <stdio.h> #include <stdlib.h> typedef int datatype; typedef struct Node {datatype data;struct Node *next;struct Node *prev; }*DoubleLinkList;DoubleLinkList create() {DoubleLinkList s(DoubleLinkList)malloc(sizeof(st…