自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(58)
  • 收藏
  • 关注

原创 造了一个交易图表库的轮子

最近公司有个需求是写k线图,要求既能显示蜡烛图,又能显示分时图。然后本人就照着Binance的样式用canvas造了一个轮子,后来公司里用的也很方便,便拿出来开源了。安装已经上传了npm仓库,直接npm命令安装就行npm install bigo-chart -S如何使用使用起来非常简单,只需要一些小小的配置就可以直接显示图表了:import BigoChart from "bigo-chart"import "bigo-chart/dist/chart.css"const option

2021-05-31 10:14:07 179

原创 Vue-Router源码分析系列:目录

vue-router的注册

2021-03-04 21:53:05 514 1

原创 Vue源码分析系列:目录

数据驱动篇:源码分析:data的代理源码分析:$mount执行过程源码分析:render的执行过程源码分析:createElement的执行过程源码分析:patch的执行过程总结:new Vue的过程组件化:源码分析:createComponent的执行过程源码分析:组件的patch过程源码分析:合并配置源码分析:组件注册响应式原理:源码分析:构建响应式对象原理解析:理解Dep类和Watcher类源码分析:依赖收集...

2021-02-24 21:42:58 984

原创 GIS:矢量瓦片生成及部署

矢量瓦片生成及部署,使用mapbox的tippecanoe工具

2022-10-25 10:53:42 1682

原创 WebRTC应用问题记录(附项目demo源码)

WebRTC问题记录

2022-09-07 11:20:04 420

原创 最近在面试中遇到的题目

阿里巴巴如果要用dom渲染一个巨大的足球场,场上有非常多的人,全部用dom渲染,如何进行性能优化?参考答案:使用Fragment代码片段。HTTP 和 HTTP/2 的区别,为什么 HTTP/2 会响应更快?让div水平+垂直居中的多种方式?参考答案:定位+transform、flex、定位+上下左右都是0+margin:auto。为什么有时候使用transform时会出现字体模糊现象?参考答案:使用了奇数的宽高,换为偶数即可。左固定,右占满布局如何实现?参考答案:fl

2021-06-04 22:59:44 361

原创 从零开始搭建Vue服务端渲染项目(三):开发环境的搭建

写在前面之前已经将部署环境配置完毕了,但是如果我们在本地开发时,一旦有修改,就要重新构建的话。大大拖慢了我们的开发进度,这是万万不行的。还记得webpack有一个自带的服务器devServer吗?它就会做一些开发环境的构建,但是由于我们是SSR架构,所以并不能用webpack的devSever,我们需要手动实现一个devServer。实现dev-server创建文件build/dev-server.js,这里主要放的是我们实现devServer的源码。touch build/dev-server

2021-04-06 21:54:14 474

原创 从零开始搭建Vue服务端渲染项目(二):构建

构建流程同构应用的构建流程是比较复杂的,由于同构应用的原理,代码既会运行在服务端,也会运行在客户端,所以我们在构建时需要同时进行服务端构建和客户端构建。服务端渲染使用的是构建完毕的server bundle来进行。客户端渲染使用的是构建完毕的client bundle来进行。但是在服务端渲染页面时,需要提前在页面注入客户端所需的js脚本,所以需要一个客户端代码的映射文件,将client bundle的引用填入html中,故最终服务端渲染时需要三样东西server bundle、html模板文件、客户端

2021-04-04 23:30:14 532

原创 从零开始搭建Vue服务端渲染项目(一):BFF层搭建

写在前面由于公司业务需求,需要我搭建一个SSR(同构渲染)架构。之前CSR(客户端渲染)项目选择的技术栈是Vue.js,那为什么不用Vue社区的Nuxt.js搭建一个开箱即用的SSR环境呢?因为我们的前端项目还有一个BFF(BackEnd For FrontEnd)层,故不能使用Nuxt.js,我们需要将SSR糅合进公司之前搭建的BFF层,这又是一个全新的挑战了,所以这边要写一篇关于Vue SSR的文章来记录一下。由于我们接下来要用到的SSR项目需要运行在BFF层,所以这篇专栏会将BFF层和SSR一起搭

2021-04-04 20:16:25 1903

原创 函数式编程范式:函数的组合

目录如果有小伙伴想要回顾之前的知识的话,点击下面的链接查看之前所有的学习栏目????:《大前端学习专栏:目录》概念纯函数和柯里化函数非常容易写出洋葱代码:h(f(e(x))),一层套着一层就像一个洋葱一样。解决这种问题的思路是函数组合(compose),函数组合就是将许多细粒度的函数组合起来形成一个管道,数据通过管道一层一层加工后返回最终的结果。注意:函数组合的调用顺序是从右往左。示例以下是一个获取数组中最后一个元素的值的函数组合案例://组合函数function compose(f, g

2021-03-11 21:44:15 175

原创 函数式编程范式:纯函数与柯里化

概念纯函数:相同的输入永远会得到相同的输出,且没有任何可观察的副作用。如:数组的slice是一个纯函数,一个数组无论调用几次,都会返回相同的结果;但是splice是一个非纯函数,每次调用后都会改变原数组,导致下一次调用会得到不同的结果。纯函数的优点由于纯函数有传入相同参数会得到相同的输出的特点,我们可以对一些复杂函数的执行结果进行缓存,提升性能,以下是Vue2.0源码中对纯函数缓存的实现:/** * Create a cached version of a pure function. */

2021-03-11 20:24:05 179

原创 函数式编程范式:高阶函数和闭包

高阶函数函数套着函数的现象,我们称外层函数是一个高阶函数。React中的高阶组件,其本质就是一个高阶函数。函数作为参数函数可以作为另一个函数的参数。以下是两个将函数作为参数的实例,分别模拟了forEach和filter://forEachfunction forEach(list, fn) { for (let index = 0; index < list.length; index++) { const element = list[index]; fn(eleme

2021-03-11 14:07:51 158

原创 函数式编程范式:函数是一等公民

什么是函数式编程函数式编程(Functionnal Programming,FP)是一种编程范式。我们平时接触的最多的是面向对象式的编程范式,所以我们在学习JS或者是JAVA的时候最开始都是从面向对象的编程思维开始学习。面向对象编程的思维方式是:将现实中的事物抽象成类、对象,并且由封装、继承多态来演示事物之间的关系。然而函数式编程的思维方式正好就是面向对象思维方式反过来:将现实中的事物之间的关系抽象到程序世界,所以,函数式编程的函数,并不是程序中写的函数,而是数学中的函数,表示一种映射关系,如:y=f

2021-03-10 22:47:01 403

原创 Vue-Router源码解析:URL变化触发组件渲染

回顾如果有小伙伴想要回顾之前的知识的话,点击下面的链接查看之前所有的源码分析流程????《Vue-Router源码解析:目录》如何触发组件渲染?VueRouter源码学习到这里其实已经快到尾声了,然而我相信大家还有一个问题一直没有得到答案,那就是为什么URL变化之后会触发组件的渲染?响应式的this.$route在一开始我们介绍《vue-router的注册》的时候我们说到在install方法中,有这样一行://把_route变成响应式的Vue.util.defineReactive(this

2021-03-09 22:33:24 534

原创 Vue-Router源码解析:hashRouter

回顾如果有小伙伴想要回顾之前的知识的话,点击下面的链接查看之前所有的源码分析流程????《Vue-Router源码解析:目录》hashRouterVueRouter有两种模式可以选择(其实有3种,哈哈),hash和history。其实两者的实现原理都是差不多的,我们这里挑hash来讲解吧。在不使用路由系统的网页中,如果要跳转就必须要改变url并且刷新页面。但是我们在使用路由系统的网页中(React-Router-Dom也是一样),不难发现,虽然url变化了,但是页面却没有刷新,这是怎么做到的?在

2021-03-09 21:01:37 742 1

原创 Vue-Router源码解析:导航守卫

回顾如果有小伙伴想要回顾之前的知识的话,点击下面的链接查看之前所有的源码分析流程????《Vue-Router源码解析:目录》queue上一章节我们分析了transitionTo,在transitionTo中有这样的一段定义: const queue: Array<?NavigationGuard> = [].concat( // in-component leave guards //在失活组件中调用 beforeRouteLeave ext

2021-03-08 16:21:50 634 2

原创 Vue-Router源码解析:transitionTo

transitionTo在切换路由时,我们会调用push方法,这里以hash router为例,进入实例方法push: push (location: RawLocation, onComplete?: Function, onAbort?: Function) { const { current: fromRoute } = this this.transitionTo( location, route => { pushHash(rou

2021-03-08 15:08:49 820 4

原创 Vue-Router源码解析:createMatcher

createMatcher在上一章VueRouter构造器中会调用createMatcher创建一个matcher对象,我们这次来看看createMatcher具体做了些什么。 //添加静态路由 const { pathList, pathMap, nameMap } = createRouteMap(routes)先使用了createRouteMap创建了了三个对象pathList,pathMap,nameMap。进入createRouteMap查看。createRouteMapexp

2021-03-05 16:40:24 1072

原创 Vue-Router源码解析:class VueRouter

init在上一章中讲到install函数的时候,里面会调用vue-router实例上的init方法,这一节我们来看看init都做了些什么,init定义在class VueRouter,我们先不看其他部分,先分析init:init(app: any /* Vue component instance */) { process.env.NODE_ENV !== 'production' && assert( install.installed,

2021-03-05 15:24:26 453

原创 Vue-Router源码解析:vue-router的注册

vue-router的注册vue-router相信小伙伴已经使用的非常熟练了,在使用vue-router之前,我们需要对vue-router进行注册:Vue.use(VueRouter)const router = new VueRouter({ routes:[{ path:"/",component:App }]})const vm = new Vue({ template:'<div id="app">', components:{App}, router})其

2021-03-04 21:50:40 669 1

原创 Vue源码解析系列——模板编译篇:generate

准备vue版本号2.6.12,为方便分析,选择了runtime+compiler版本。回顾如果有感兴趣的同学可以看看我之前的源码分析文章,这里呈上链接:《Vue源码分析系列:目录》generate code经过前面对AST进行了优化之后,需要将整个AST变成一个可执行的代码块,也就是render函数。于是模板编译器使用了generate对AST进行了代码生成。generateexport function generate( ast: ASTElement | void, option

2021-03-04 21:03:06 539 2

原创 Vue源码解析系列——模板编译篇:optimize

准备vue版本号2.6.12,为方便分析,选择了runtime+compiler版本。回顾如果有感兴趣的同学可以看看我之前的源码分析文章,这里呈上链接:《Vue源码分析系列:目录》optimize上一篇介绍玩完parse之后,这一次要分析的是optimize方法,这个方法对parse解析后的AST进行了优化,标记了静态节点和静态根节点。当一个节点staticRoots(静态根节点)为true,并且不在v-for中,那么第一次render的时候会对以这个节点为根的子树进行缓存,等到下次再render

2021-03-03 21:48:41 295 1

原创 Vue源码解析系列——模板编译篇:parseHTML的各种hook

准备vue版本号2.6.12,为方便分析,选择了runtime+compiler版本。回顾如果有感兴趣的同学可以看看我之前的源码分析文章,这里呈上链接:《Vue源码分析系列:目录》parseHTML hooks上一篇我们分析了parse方法中的parseHTML,在parseHTML中会调用很多的hooks,这些hooks定义在:parseHTML(template, { warn, expectHTML: options.expectHTML, isUnaryTag:

2021-03-03 16:27:47 366 2

原创 Vue源码解析系列——模板编译篇:parse编译不同标签

准备vue版本号2.6.12,为方便分析,选择了runtime+compiler版本。模板编译的入口在runtime+compiler版本中,Vue再执行挂载操作时,会调用为runtime+compiler版本特别定制的$mount方法,这个方法主要是将模板template编译为可执行的render函数。所以,整个Vue的模板编译入口就在这个$mount中。$mountconst { render, staticRenderFns } = compileToFunctions(template,

2021-03-03 10:35:42 366

原创 Vue源码解析系列——diff算法篇:diff算法(一)

准备vue版本号2.6.12,为方便分析,选择了runtime+compiler版本。写在前面有了前面数据驱动、组件化、响应式原理篇的知识储备,(没看过的同学可以戳这:《Vue源码分析系列》)这时我们就有足够的的理论去支持我们研究Vue里面大名鼎鼎的diff算法了。_updatediff算法体现在页面的更新过程中,所以我们直接进入_update查看:const prevVnode = vm._vnode; if (!prevVnode) { // initial render

2021-03-01 22:52:19 529

原创 Vue源码解析系列——响应式原理篇:watch

准备vue版本号2.6.12,为方便分析,选择了runtime+compiler版本。写在前面相信记过前几章节对源码的学习,我们都对Dep、Watcher的运作有了深入的了解。特别是上一章节《源码解析:computed》,对这两个类的理解更加的深入了。这次我们要学习的是watch属性的运作过程,理解了computed属性的运作过程后,watch属性的运作原理理解起来就非常简单了。watch初始化watch初始化在_init中:initState(vm)。initState中又有这样一段代码:if

2021-03-01 15:29:29 276

原创 Vue源码解析系列——响应式原理篇:computed

准备vue版本号2.6.12,为方便分析,选择了runtime+compiler版本。写在前面computed的原理较为复杂,需要对Dep和Watcher类需要有较深的理解,如果还有同学不理解Dep和Watcher类可以去看我之前的文章:理解Dep类和Watcher类。这里我简单提两句。试想:一个data数据会不会被多个computed所依赖?那么一个computed会不会同时依赖多个data属性?对后台数据库表关系设计有了解的同学应该知道表与表之间有一种关系:多对多的关系。多对多的关系是数据库表

2021-03-01 13:29:52 717

原创 Vue源码解析系列——响应式原理篇:nextTick

准备vue版本号2.6.12,为方便分析,选择了runtime+compiler版本。要完全理解nextTick的实现需要有以下知识储备:JS的事件循环机制ES6中的Promise的使用方法及原理事件循环中的微任务与宏任务nextTick的两种使用方法在Vue中,nextTick有两种风格的使用方法,一种是回调函数风格:this.$nextTick(()=>console.log("nextTick"))另外一种是Promise风格的使用方法:this.$nextTick()

2021-02-26 21:35:37 372

原创 Vue源码解析系列——响应式原理篇:派发更新

准备vue版本号2.6.12,为方便分析,选择了runtime+compiler版本。派发更新前面一篇我们了解到Vue在data的get过程中收集了对应数据的Watcher实例,由这些watcher牵引着相关的依赖。这次我们要讲的是data的set过程中的逻辑,在get中收集了watcher之后,在set过程中就会通知这些watcher,由这些watcher去更新依赖,这就是今天要讲的派发更新的过程。defineReactive进入defineReactive查看set过程的操作://设置该值时

2021-02-26 20:06:22 212

原创 Vue源码解析系列——响应式原理篇:依赖收集

准备vue版本号2.6.12,为方便分析,选择了runtime+compiler版本。依赖收集所谓依赖收集,就是利用Vue定义的Dep类去收集当前正在执行中的watcher。依赖收集的操作在data的get过程中,所以我们进入defineReactive方法,去看看在get的过程中做了什么操作。defineReactiveconst dep = new Dep();...//访问该值时,依赖收集 get: function reactiveGetter() { //如果有

2021-02-24 21:34:55 657

原创 Vue源码解析系列——响应式原理篇:理解Dep类和Watcher类

写在前面这一篇我们先不着急阅读源码,因为接下来需要用到一个比较复杂的设计模式:观察者模式,而且还需要理解依赖收集才能继续向下阅读源码,所以这次我们先做一个铺垫。依赖收集通过之前阅读的源码我们了解到Vue2.x版本的响应式是依靠Object.defineProperty这个API来进行对象的劫持,当对象进行取值和赋值操作的时候,都可以进行一些另外的操作。在get过程中,也就是对象的取值,Vue做的操作是:依赖收集。那么什么是依赖?这里我们举一个例子:<template> <di

2021-02-23 21:38:50 1814

原创 Vue源码解析系列——响应式原理篇:响应式对象

准备vue版本号2.6.12,为方便分析,选择了runtime+compiler版本。学习响应式原理需要先了解JS的API:Object.defineProperty(obj,key,descript)initData之前我们介绍了data的代理[点击查看],在代理data逻辑之后还有一行observe(data, true),今天我们从这里开始。observeexport function observe(value: any, asRootData: ?boolean): Observe

2021-02-22 20:29:32 285

原创 Vue源码解析系列——组件篇:组件注册

准备vue版本号2.6.12,为方便分析,选择了runtime+compiler版本。组件注册Vue的组件祖册分为两部分,一部分为全局组件注册,也就是使用Vue.component(tag,options),另外一部分为局部组件注册,使用options.component = {App}。我们先来看全局组件注册。import HelloWorld from './components/HelloWorld';Vue.component('HelloWorld', HelloWorld);n

2021-02-22 19:21:48 211

原创 Vue源码解析系列——组件篇:合并配置

准备vue版本号2.6.12,为方便分析,选择了runtime+compiler版本。mergeOptions通过前面的学习我们了解到,Vue对于非组件和组件有着不同的合并options的策略,具体体现在_init中://对options进行合并 if (options && options._isComponent) { //对组件option的合并 // optimize internal component instantiation

2021-02-21 15:23:31 431

原创 Vue源码解析系列——组件篇:组件的patch过程

准备vue版本号2.6.12,为方便分析,选择了runtime+compiler版本。createElm在之前解析patch(点击查看)的时候,我们在createElm中我们已经见过了createComponent。在createElm中会先尝试着调用createComponent来确定是不是一个组件,如果是组件就进入createComponent的逻辑,如果不是组件就继续向下。所以我们这次要进入createComponent来看看具体的逻辑。createComponent(patch.js)f

2021-02-20 16:10:51 462

原创 Vue源码解析系列——组件篇:createComponent的执行过程

准备vue版本号2.6.12,为方便分析,选择了runtime+compiler版本。createComponent的定义createComponent定义在croe/vdom/create-component.js中:export function createComponent( Ctor: Class<Component> | Function | Object | void, data: ?VNodeData, context: Component, childr

2021-02-20 10:31:03 668

原创 Vue源码解析系列——数据驱动篇:patch的执行过程

准备vue版本号2.6.12,为方便分析,选择了runtime+compiler版本。__patch__的定义pathch定义在platforms/web/runtime/index中。由于Vue既可以运行在浏览器也可以运行在服务端,所以这里对patch做了一个兼容性处理:import { patch } from './patch'Vue.prototype.__patch__ = inBrowser ? patch : noop进入./patch:patch这里引入了一些不同平台的d

2021-02-07 16:55:53 705

原创 Vue源码解析系列——数据驱动篇:createElement的执行过程

准备vue版本号2.6.12,为方便分析,选择了runtime+compiler版本。createElement的定义createElement定义在core/vdom/create-element.js中。这边其实做了一个参数的重载的一个兼容性写法。如果data是个数组或者为基本类型(其实这两种类型是恰恰对应的children),就把data之后的参数都往前赋值一个位置,然后将data置空。export function createElement( context: Component,

2021-02-07 11:23:51 411

原创 Vue源码解析系列——数据驱动篇:render的执行过程

准备vue版本号2.6.12,为方便分析,选择了runtime+compiler版本。_render的定义Vue原型上_render定义在core/instance/render.js,这个文件随着core/instance/index.js中renderMixin(Vue)的调用而加载。以下是render.js文件。(剔除了非主线分代码,下同)/** core/instance/render.js **///在Vue原型上挂载私有的_render方法 Vue.prototype._ren

2021-02-06 23:06:03 403

原创 new Vue()的过程

vue 调用从new Vue()开始.'src/platforms/web/entry-runtime-with-compiler.js'从'src/platforms/web/runtime/index.js''src/core/instance/index.js',定义function Vue (options).initMixin(),定义_init()._init()initRender(),定义Vue.$createElement()生命周期beforeCreate()

2021-02-06 21:37:40 797

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除