- 博客(96)
- 资源 (3)
- 收藏
- 关注
原创 React之Diff算法
对于Vue2的diff算法使用了双指针,React的diff算法没有使用双指针,是因为更新的jsx对象的newChildren为数组的形式,但是和newChildren中每个组件比较的是current fiber,对fiber的兄弟节点是通过silbing来相连的,我们通过下标来去获取下一个newChildren项,但是对于fiber只能通过fiber.silbing来获取对应的项,所以没有使用双指针法来进行diff。既然唯一的可能性已经不能复用,则剩下的fiber都没有机会了,所以都需要标记删除。
2023-02-02 01:02:59
1420
1
原创 React中commit阶段发生了什么
函数在执行过程中对外部造成的影响可以称之为副作用,副作用包含的类型很多,比如说标记值为Placement时,会叫Dom节点进行插入与移动,Passive代表useEffect进行回调执行,ChildDeletion指移除子Dom节点对于React的工作原理可以简单概括为触发更新render阶段:计算更新会造成的副作用commit阶段:执行副作用更新Dom变化主要就是Placement、ChildDeletion在起作用,在render阶段来进行保存副作用,在commit阶段来使用副作用。
2023-01-28 01:02:02
1419
原创 React源码之render过程中发生了什么?
递”:递阶段首先会从 rootFiber 开始向下深度优先遍历。遍历到的每个 Fiber 节点,会调用 beginWork 方法,并且该方法会为传入的 Fiber 节点创建它的子 Fiber 节点,并赋值给 workInProgress.child 进行连接,当遍历到叶子节点时就会进入归阶段这个过程也叫做调和“归”:就是向上归并的过程,会执行 completeWork 方法来处理 Fiber 节点,当某个 Fiber 节点执行完 completeWork,如果有兄弟 Fiber 节点,会。
2023-01-23 17:25:20
868
原创 React源码之Fiber架构
对于Fiber我们可以理解为存储在内存中的Dom对于React15在render阶段的reconcile是不可打断的,如果在操作大量的dom时,会存在卡顿,因为浏览器将所有的时间都交给了js引擎线程去执行,此时GUI渲染线程被阻塞,导致页面出现卡顿,无法响应用户对应的事件。
2022-12-07 00:26:38
1372
原创 React源码之概念篇
这是从ReactDom.render后触发的步骤首先在React中需要在浏览器刷新一次就需要执行如下的步骤:JS脚本执行->样式布局->样式绘制,如果js执行时间超过了16.6ms,那么就没有时间留给样式布局,此时就会出现掉帧现象。React的设计理念:快速响应制约瓶颈:CPU与IO解决办法:异步可中断更新的机制老架构的更新策略:假如我们将dom的数据改为了2,4,6那么会出现如下的更新事项如果对于老的架构是无法实现异步可中断更新的,因为是递归调用执行栈,如果想要实现可中断则会出现如下情况,
2022-12-07 00:23:29
326
原创 基于docker+jenkins+nginx实现一套CI/CD流程
代码的编写->提交代码到git->触发webHook->CI/CD流水线接收到webHook检测到代码发生变化->拉取新的代码->检测依赖/安装依赖->构建->单元测试/集成测试->交付部署(docker一键式搭建nginx等)代码的编写->单元测试/Eslint测试->提交到远程git仓库->手动打包构建->手动在服务器下载并配置Nginx->手动将构建包上传到Nginx对应的代理路径中(scp)->完成发布。通过cd ~/.ssh来获取生成的文件,将生成的秘钥id_rsa复制到jenkins的凭证中。
2022-11-11 20:19:27
2098
原创 Webpack中Loader与Plugin
Webpack的核心功能是通过抽离出很多插件来实现的,因此系统内功能的划分粒度很细,这样做到了完美解偶同时又分工明确,代码容易维护。所以说插件机制是也是Webpack的核心知识,那么下面我们就来写介绍一下Loader与Plugin,并写一些常用的Loader和Plugin。 对于Loader我们可以通过rules去匹配,哪些文件会被这个loader所处理。Loader本身就是一个函数,当webpack解析资源的时候,会调用相关的loader去处理,loader接收到文本内容作为参数,将处理完的内容进行返回
2022-07-13 17:21:20
2727
1
原创 Express与Koa源码分析
对于Express与Koa他们的Api很相似,但是其执行机制还是有所不同的,有时间的同学还是推荐去读一些源码,Express源码感觉比较复杂的,Koa的源码相对比较精简,那么下面我们主要从两个方面去来看一下。Express 是线性的,那么看一下下面的代码:输出结果:那么可以得出,Express 中间件实现是基于 Callback 回调函数同步的,它不会去等待异步(Promise)完成,这也解释了为什么加入了异步操作顺序就被改变了。初始化时的源码如下:对于Express中源码的执行是在proto.h
2022-07-08 15:49:19
194
原创 一文带你了解Vite原理
Vite号称是 下一代的前端开发和构建工具,它采用了全新的unbundle思想利用浏览器ESM特性导入组织代码,在服务器端进行按需编译返回,对于生产环境使用rollup打包。比起传统的webpack构建,在性能速度上都有了质的提高。 esbuild 使用go编写,cpu密集下更具性能优势,编译速度更快,相比较其他打包工具的速度提升10~100倍的差距。Vite通过esbuild带来的好处:: 现仍共存多种模块化标准代码,比如commonJs依赖,Vite在预构建阶段将依赖中各种其他模块化规范(Comm
2022-07-07 00:38:37
4489
原创 Vue源码学习之Computed与Watcher原理
computed与watch是我们在vue中常用的操作,computed是一个惰性求值观察者,具有缓存性,只有当依赖发生变化,第一次访问computed属性,才会计算新的值。而watch则是当数据发生变化便会调用回调函数。我们虽然知道vue是这么操作的,但是原理我们又知多少呢?接下来我们来分析一下两者的原理。 我们知道new Vue()的时候会调用_init方法,此时会调用initState方法,源码如下: 在initState方法中调用了initComputed,初始化了计算属性,那么我们看一下ini
2022-07-03 13:17:03
1553
3
原创 一文讲解Vuex实现原理
对于Vuex相信大家是常用,那么Vuex作为Vue生态中最重要的一部分,专为Vue.js应用的状态管理模式,每一个 Vuex 应用的核心就是 store(仓库)。“store” 基本上就是一个容器,它包含着你的应用中大部分的状态 ( state ),并且Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。这样可以方便地
2022-07-02 12:08:17
2122
1
原创 Vue源码学习之$set实现原理
在Vue2中当我们通过数组的下标去修改数组值,或者向对象添加添加属性时,对应的视图都无法进行更新,这是因为我们所添加的数据不是响应式的,无法响应视图的变化。那么此时我们可以通过$set来实现。对于数组可以通过this.$set(this.arr,0,‘xx’)来去修改数组下标对应的值,对于对象可以通过this.$set(this.obj,‘a’,‘xxx’)向对象新增属性a,接下来我们来根据源码来分析原理。 源码如下: 源码分析如下: 当$set所设置的目标对象为数组时,则调用目标对象的splice方
2022-07-01 11:37:16
2501
原创 Vue源码学习之双向数据绑定原理
对于Vue的双向数据绑定原理相信大家在面试时,一定是常考常问,那么我们今天就讲解一下Vue双向数据绑定的原理~ 那么接下来我们去模拟一下Vue初始化时的代码,来进行分析。 通过代码我们可以分析当初始化Vue的时候,我们使用observe来递归data属性,进行将data属性变为响应式的,其中在递归data属性时,会通过defineReactive来对每个属性都添加对应的数据劫持。接下来会进入Compile阶段,我们对Compile阶段进行分析。 代码如下: 通过这段代码进行分析,在compile阶段
2022-06-30 00:38:15
200
原创 一文讲解发布者订阅者模式与观察者模式
观察者模式:当对象之间存在一对多的依赖关系时,其中一个对象的状态发生改变,所有依赖它的对象都会收到通知,这就是观察者模式。 发布者订阅者模式:基于一个事件通道,希望接收通知的对象Subscriber 通过自定义事件订阅主题,被激活事件的对象 Publisher 通过发布主题事件的方式通知订阅者该主题的 Subscriber 对象。 观察者模式是,当被观察者的数据发生变化时,调用被观察者的notify方法,去通知所有观察者执行update方法进行更新。对于发布者订阅者模式,首先发布者与订阅者互相并不知道
2022-06-28 13:55:09
2799
1
原创 Vue源码学习之异步更新原理
首先我们了解到Vue的Dom更新是异步的,当我们更新数据后,立即获取Dom的内容,此时Dom的内容还是旧的内容,那么我们可以通过$nextTick在回调函数中去获取最新的Dom内容,那么这个时候就有所考虑了,为什么就有所考虑了,为什么我们不在Vue中所操作的Dom是同步的,在Vue中确是异步的呢?实际跟Vue的渲染机制有关,在Vue中当修改数据后,此时渲染是异步的,所以Dom的更新也是为异步的。 Vue中Dom的更新不仅仅是异步的而且还是批量的,这样做的好处是能够最大程度的优化性能,对于相同Dom的多次修
2022-06-27 15:15:11
1539
原创 Vue源码学习之响应式原理
响应式是指当数据发生变化后,Vue会通知到使用该数据的代码。当数据发生改变后也会通知视图进行改变,下面我们将简单的实现一下Vue中响应式原理的核心代码部分。 Observer类的目的是将一个正常的object转换为每个层级的属性都是响应式(可以被侦测)的object。实现部分: 1. 首先先对所传入Observer的对象设置一个属性为__ob__,这也就是我们平时在Vue打印输出变量对象时,可以看到其对象中是存在__ob__属性的,那么这个属性实际就是Observer实例。在代码中我们是通过def函数
2022-06-24 17:35:51
449
原创 Vue源码学习之nextTick
对于nextTick相信大家都并不陌生,那么nextTick的本质是对JS事件循环的一种应用。那么相信大家都遇到过这种情况,比如说我们对DOM1进行操作并改变DOM1中的数据,下面使用一个变量去获取DOM1中的数据,发现获取到的数据是DOM1变化之前的数据,这就是我们会产生疑惑的地方。 这是因为Vue对Dom的更新是异步的,异步是代表着当被处理数据是动态变化时,此时对应的Dom未能同步更新就会导致数据已经更新(Model层的数据已经更新),但是视图层并没有更新(Dom未进行更新)。此时我们可以通过使用ne
2022-06-23 16:34:43
1058
1
原创 浏览器原理篇之Service Worker
Service Worker的主要功能 在2014年的时候,标注居委会就提出了Service Worker的概念,它主要是在页面与网络之间增加拦截器,用来缓存和拦截请求,它也作为PWA来试着解决离线存储和消息推送的问题。对于Service Worker的主要功能也是去拦截请求和缓存资源,这样使得用户在离线环境中,也可以使用网络应用。或者直接在本地中去读取缓存资源,从而加快访问速度。Service Worker架构 为了避免JavaScript过多占用主线程时长的情况,浏览器实现了Web Worker
2022-05-08 23:53:30
1370
10
原创 一文讲解Typescript中工具类型
开篇 对于Ts的工具类型,在使用第三方工具时,会看到其源码库用到工具类型的频率会非常高,对于初入Ts的同学,真的会看的一脸懵,工具类型的使用会有利于我们所编写组件库中类型的封装,避免类型重复的进行声明定义,大大提高了我们的开发效率与规范性。下面我将为大家介绍Ts中以下工具类型的应用keyof、extends、typeof、Partial、Record、Exclude、Omit、Pick、Extract。工具类型keyof 官方定义中讲述了keyof可以用于获取某种类型的所有键,其返回值类型为联合类型
2022-05-03 21:27:56
1974
6
原创 一文带你了解Ts泛型的应用
泛型是Ts中最难的部分,对于其概念进行理解后,还需要理解如何使用泛型,去封装可复用高的组件,使用泛型可以很好的帮助组件的可复用性。通过使用泛型可以使得在定义函数,接口或类的时候,可以不预先指定其具体的类型,而在使用的时候再进行定义。那么接下来,我们会先从案例展示->基础概念讲解,向大家了解Ts中泛型的使用。使用泛型or不使用对比 下面我们来展示当不使用泛型时,带给我们的不便。泛型在类中的应用 当我们定义一个累加数的类,类中的所操作的数值都为number类型,不使用泛型时会导致我们对numbe
2022-05-02 20:53:15
3979
原创 一文带你了解中Typescript中type与interface的区别
在我们Ts使用的日常开发中,我们对于type(类型别名)与interface(接口)的使用可能傻傻分不清楚,因为他们的功能还是非常相似的,可以说在大多数情况下type与interface还是等价的,我们可以使用两种中的任意一种来对我们的项目进行类型定义,那么存在即合理,接下来我们将对type与interface有什么区别来进行讲解~type与interface的相同点定义对象或者函数的形状 首先两者都可以对基本数据类型与函数进行类型定义,比如: interface Test { a: s
2022-05-02 00:17:01
4121
原创 git reset中hard与soft区别
前言 对于我们日常开发中,我们常用的方法可能是git reset --hard,来强行回退commit所提交的信息,这是不友好的,也许我们希望对误操作提交的commit不进行删除而是重新修改并进行提交,这个时候就需要–soft操作了,下文将介绍hard模式与soft模式的差异~git reset中的hard与soft 对于git reset我们在日常主要是使用其两种模式,分别为hard与soft模式,对于git reset --hard的作用是代码强制回溯到某节点,对于当前节点->回溯节点中间已
2022-04-12 14:41:36
8151
2
原创 电商后台开发之商品规格组合算法
前言 最近接了私活,关于器械商城的项目,最后收尾阶段,发现发布商品还是存在着问题,对于多个相同/不同的商品规格输出成商品时,需要依据规格名对规格值进行排列组合,保证所有规格值都可以进行选择。核心代码部分数据结构 formState: { goods: { goodsSn: '', // 商品编号 ...xxx }, // 商品规格 specifications: [ {
2022-04-05 18:07:38
1160
原创 Nest.js实战开发(第一弹)-连接mysql
为什么选用nest.js开发? 之前也是使用过egg.js写过增删改查,对于egg.js的给我的体验感约束性很强,文档也很完善,但是对于Typescript的支持并不好,都2022年了,ts的应用也该很广泛了吧,所以此次开发选择了nest.js~安装依赖包npm install @nestjs/typeorm typeorm mysql2 -S建立配置 对于我们连接mysql的账密以及ip,我们将其存储在.env/.env.prod中。我们在根目录创建config文件夹,并创建env
2022-03-29 20:05:52
3278
2
原创 时间复杂度与空间复杂度(探索篇)
时间复杂度的种类(按照复杂度的增长趋势来进行排列)O(1)O(n)O(logn)O(nlogn)O(n2)O(n3)O(2n)O(n!) 时间复杂度增长图时间复杂度为O(1)的操作if语句中的判断 例如:if(i === 1)。赋值/加减乘除运算。例如:a=1,result = 3+4,result = n*2,result = 10000 * 10000。数组的push与pop操作。例如:array.push(‘a’),array.pop()。
2022-03-22 00:10:59
1505
原创 手写Promise中all、race、any方法
all方法// all: 传入的所有Promise最终都转化为fulfilled态时,则会执行resolve回调,并将返回值是的所有的Promise的resolve的回调的value的数组。// 其中一个任何Promise为reject状态时,则返回的Promise的状态更改为rejected。function all(arr) { //返回一个promise return new Promise((resolve, reject) => { let length
2021-11-24 14:42:23
703
原创 js实现数组与对象数组的去重
数组实现去重的方法filter + indexOf进行去重function deDeplicated(arr) { return arr.filter((item, index) => { console.log(index, arr.indexOf(item), index === arr.indexOf(item)) return index === arr.indexOf(item); })}双重for循环进行去重function di
2021-11-21 23:30:16
657
1
原创 前端面试之new操作符具体都干了什么?
new操作符具体都干了什么?(1) 首先创建了一个空对象。(2) 设置原型,将对象的原型设置为函数的prototype对象。(3) 让函数的this指向这个对象,执行构造函数中的代码(4) 判断函数的返回值类型,如果是值类型,则返回创建的对象,如果是引用类型,则返回这个引用类型的对象。实现一下?function objectFactory(){ let newObject = null, construct = Array.prototype.shift.call(angum
2021-10-17 20:11:19
737
原创 golang使用zookeeper进行增删改查
环境 连接zookeeper使用:samuel/go-zookeeper包代码部分package mainimport ( "fmt" "github.com/samuel/go-zookeeper/zk" "time")var ( host = []string{"127.0.0.1:2181"})func main() { conn, _, err := zk.Connect(host, 5*time.Second) if err != nil { panic(er
2021-09-06 00:18:31
356
原创 gin实现限流中间件
在Go编写web类型应用时,我们为了防止用户去非法狂刷接口,从而使得服务器资源被大量占用,在此我们可以对对应用户进行限流操作,当在一段时间内,只允许对应的数量的用户去访问我们对应的服务,代码
2021-09-02 01:10:28
2018
原创 MAC m1使用homebrew安装redis报错
报错信息tar: Error opening archive: Failed to open '/Users/peas/Library/Caches/Homebrew/downloads/df016fccee96887f4f24a989ec9b08c04eef867bfb15f67a6e5eee58f6ce3ff2--openssl@1.1-1.1.1k.arm64_big_sur.bottle.tar.gz'解决办法 在终端输入如下命令export HOMEBREW_BOTTLE_DOMAIN=''
2021-08-24 11:32:45
1322
3
原创 手写instanceof
instanceof的作用 instanceof的作用是判断一个构造函数的prototype属性所指向的对象是否在另一个被检测对象的原型链上。手写instanceof 代码部分: function myInstanceof(left,right){ // Object.getPrototypeOf(left) 返回left的原型 let proto = Object.getPrototypeOf(left) prototype = right.prototype while(
2021-06-06 21:29:16
126
原创 react使用require图片无法加载
踩坑记录 在react中使用require进行导入本地图片时,无法显示图片,仔细检查发现图片的base64编码是在default属性里面,如下: 顾在此进行require进行引入图片时,加入default即可,代码如下: <img src={require("./images/1.png").default} alt=""/> 加入.default后图片进行正常显示,踩坑结束。...
2021-04-29 00:21:02
1106
原创 Vue3+TypeScript封装axios并进行请求调用
不是吧,不是吧,原来真的有人都2021年了,连TypeScript都没听说过吧?在项目中使用TypeScript虽然短期内会增加一些开发成本,但是对于其需要长期维护的项目,TypeScript能够减少其维护成本,使用TypeScript增加了代码的可读性和可维护性,且拥有较为活跃的社区,当居为大前端的趋势所在,那就开始淦起来吧~使用TypeScript封装基础axios库代码如下:// http.tsimport axios, { AxiosRequestConfig, AxiosResponse
2021-04-11 17:59:27
5632
4
原创 meta标签http-equiv属性实现自动刷新页面和重定向
介绍 在meta标签的属性http-equiv属性中有refresh参数,refresh参数用于重定向和刷新页面,加入如下属性后,在content进行声明,如下: 刷新:使用该标签进行刷新页面,数字3代表若无其他操作则3秒后刷新< meta http-equiv=“refresh” content=“3”> 重定向:3秒后跳转对应链接地址< meta http-equiv=“refresh” content=“3;url=<%=redirectUrl%>”>
2021-04-05 14:00:27
1580
原创 MongoDB数据库进行导入导出操作
将数据库数据导出备份 将数据库数据进行导出备份操作: mongodump -h dbhost -d dbname -o dbdirectory 参数说明: -h: MongDB所在服务器地址,例如:127.0.0.1,当然也可以指定端口号:127.0.0.1:27017 -d: 需要备份的数据库实例,例如:test -o: 备份的数据存放位置,例如:/home/mongodump/,当然该目录需要提前建立,这个
2021-04-05 11:48:58
485
原创 Express框架中使用ejs模板引擎
Express中使用Ejs模板引擎引入 安装:npm install ejs --save 在app.js中引入express,设置ejs模板,并配置路由参数,代码如下: //引入express var express = require("express"); var app = express(); //配置模板引擎 app.set("view engine","ejs"); //配置路由参数 app.get("/",function(req,res){ //将数据渲染到news
2021-04-04 10:49:03
367
原创 Node.js报错之Cannot use a session that has ended
使用Node.js连接MongoDB时出现报错信息,报错信息的意思为无法使用已经结束的对话。查阅代码进行分析问题,代码如下://引入Mongodbconst {MongoClient} = require("mongodb")//定义数据库连接的地址const url = "mongodb://127.0.0.1:27017"//定义要操作的数据库const dbName = "peas"//实例化MongoClient 传入数据库连接地址,加入第二个参数防止后期不被支持const
2021-04-03 23:32:34
1404
原创 前端面试之手写call、apply、bind
Call的简易模拟实现 Function.prototype.myCall = function (context) { context = context || window //将当前被调用的方法定义在context.fn上(为了能以对象调用的形式绑定this) context.fn = this //获取实参,将伪数组转换,从数组第二个开始截取 let args = [...arguments].slice(1) //以对象调用的形式调用func,此时的this指
2021-04-01 15:14:59
89
原创 使用vue随机生成颜色数组,并设置盒子颜色
背景 写项目时,每个人的都需要有自己的技能标签,需要将技能标签的背景颜色每一次查看时都不相同,此时我们使用随机数范围未0~255,从而拼接rgb值,并将其设置到标签的背景颜色中。代码部分 话不多说直接上代码~<ul class="lable_list"> //添加style为item.color为随机生成的颜色 <li class="lable_item" v-for="(item,index) in skillTagArr" :style
2021-03-28 17:14:32
1469
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人