导航:首页 > 源码编译 > vue源码解析github

vue源码解析github

发布时间:2023-12-22 22:36:04

1. 不依赖vue-cli脚手架创建vue项目

我们一般创建vue项目都是通过vue-cli脚手架去创建,这次我尝试了通过文档完成所有项目配置包括webpack、ant-design-vue、vue-router、vuex等
项目源码: https://github.com/wzp123321/myVueJSProByMySelf.git
1.新建项目

2.使用vscode打开项目

3.初始化

4.安装基本的 npm 包

5.创建文件夹以及文件

6.配置webpack.config.js
在这之前先安装一些依赖
模板解析依赖:

样式依赖:
css-loader: https://webpack.docschina.org/loaders/css-loader/

文件加载依赖

解析es6语法依赖: https://github.com/babel/babel-loader

这是一个webpack插件,可简化HTML文件的创建以服务您的webpack捆绑软件

现在就可以配置webpack.config.js,如果有什么不清楚的可以参考官网 https://webpack.docschina.org/configuration/

7.安装解析依赖 https://github.com/webpack/webpack-dev-server

8.修改package.json文件

9.配置babel,创建.babelrc文件
修改webpack.config.js

如果编译时报错的话可能是因为你没有安装依赖:

10.主要文件:
app.vue:

index.js:

html文件:

Vue项目文件夹大致参考

1.混入 (mixins) 是一种分发 Vue 组件中可复用功能的非常灵活的方式。混入对象可以包含任意组件选项。当组件使用混入对象时,所有混入对象的选项将被混入该组件本身的选项。
mixins文件夹下可以写各种调用ajax请求方法的方法,然后在需要调用这些方法请求数据的文件中:

这里的getCourseList文件中有请求需要的参数以及请求完成之后获取的数据 直接在文件类似this.getAllDemoClass();就能调用方法

2.components通用组件存放文件夹:
在这个文件夹下封装了项目需要的组件 然后在components下的index.js中向外暴露即可 然后在使用组件的文件中引用components即可

后续:
1.引入ant-design-vue:
具体引入操作可见官网 https://vue.ant.design/docs/vue/introce-cn/

2.引入Vue Router https://router.vuejs.org/zh/installation.html

路由配置文件:router/index.js

3.引入vuex

新建store/index.js

news/index.vue

4.页面顶部进度条插件Nprogress

使用:

2. 【面试题解析】从 Vue 源码分析 key 的作用

最近看了面试题中有一个这样的题, v-for 为什么要绑定 key?

Vue 中 key 很多人都弄不清楚有什么作用,甚至还有些人认为不绑定 key 就会报错。

其实没绑定 key 的话,Vue 还是可以正常运行的,报警告是因为没通过 Eslint 的检查。

接下来将通过源码一步步分析这个 key 的作用。

Virtual DOM 最主要保留了 DOM 元素的层级关系和一些基本属性,本质上就是一个 JS 对象。相对于真实的 DOM,Virtual DOM 更简单,操作起来速度更快。

如果需要改变 DOM,则会通过新旧 Virtual DOM 对比,找出需要修改的节点进行真实的 DOM 操作,从而减小性能消耗。

传统的 Diff 算法需要遍历一个树的每个节点,与另一棵树的每个节点对比,时间复杂度为 O(n²)。

Vue 采用的 Diff 算法则通过逐级对比,大大降低了复杂性,时间复杂度为 O(n)。

VNode 更新首先会经过 patch 函数, patch 函数源码如下:

vnode 表示更新后的节点,oldVnode 表示更新前的节点,通过对比新旧节点进行操作。

1、vnode 未定义,oldVnode 存在则触发 destroy 的钩子函数

2、oldVnode 未定义,则根据 vnode 创建新的元素

3、oldVnode 不为真实元素并且 oldVnode 与 vnode 为同一节点,则会调用 patchVnode 触发更新

4、oldVnode 为真实元素或者 oldVnode 与 vnode 不是同一节点,另做处理

接下来会进入 patchVnode 函数,源码如下:

1、vnode 的 text 不存在,则会比对 oldVnode 与 vnode 的 children 节点进行更新操作

2、vnode 的 text 存在,则会修改 DOM 节点的 text

接下来在 updateChildren 函数内就可以看到 key 的用处。

key 的作用主要是给 VNode 添加唯一标识,通过这个 key,可以更快找到新旧 VNode 的变化,从而进一步操作。

key 的作用主要表现在以下这段源码中。

updateChildren 过程为:

1、分别用两个指针(startIndex, endIndex)表示 oldCh 和 newCh 的头尾节点

2、对指针所对应的节点做一个两两比较,判断是否属于同一节点

3、如果4种比较都没有匹配,那么判断是否有 key,有 key 就会用 key 去做一个比较;无 key 则会通过遍历的形式进行比较

4、比较的过程中,指针往中间靠,当有一个 startIndex > endIndex,则表示有一个已经遍历完了,比较结束

从 VNode 的渲染过程可以得知,Vue 的 Diff 算法先进行的是同级比较,然后再比较子节点。

子节点比较会通过 startIndex、endIndex 两个指针进行两两比较,再通过 key 比对子节点。如果没设置 key,则会通过遍历的方式匹配节点,增加性能消耗。

所以不绑定 key 并不会有问题,绑定 key 之后在性能上有一定的提升。

综上,key 主要是应用在 Diff 算法中,作用是为了更快速定位出相同的新旧节点,尽量减少 DOM 的创建和销毁的操作。

希望以上内容能够对各位小伙伴有所帮助,祝大家面试顺利。

Vue 的文档中对 key 的说明如下:

关于就地修改,关键在于 sameVnode 的实现,源码如下:

可以看出,当 key 未绑定时,主要通过元素的标签等进行判断,在 updateChildren 内会将 oldStartVnode 与 newStartVnode 判断为同一节点。

如果 VNode 中只包含了文本节点,在 patchVnode 中可以直接替换文本节点,而不需要移动节点的位置,确实在不绑定 key 的情况下效率要高一丢丢。

某些情况下不绑定 key 的效率更高,那为什么大部分Eslint的规则还是要求绑定 key 呢?

因为在实际项目中,大多数情况下 v-for 的节点内并不只有文本节点,那么 VNode 的字节点就要进行销毁和创建的操作。

相比替换文本带来的一丢丢提升,这部分会消耗更多的性能,得不偿失。

了解了就地修改,那么我们在一些简单节点上可以选择不绑定 key,从而提高性能。

如果你喜欢我的文章,希望可以关注一下我的公众号【前端develop】

3. vue-lazyload 源码解析

/src/lazy.js

定义变量接收实例化参数。

lazy.js 默认导出一个函数,该函数返回一个 Lazy 类,形成闭包,保持对 Vue 的引用。

判断是否支持Webp图片

/src/listener.js

定义变量接收实例化参数。

filter 方法将配置的 filter 对象中的方法执行,接收两个参数,一个为 ReactiveListener 实例,一个为 options 参数对象。

initState 方法给元素添加 data-set 属性,值为图片地址 src,并且定义了图片状态对象 state 。在 Lazy 中已经根据像素比选择了最适配屏幕的图片,顾这里不需要考虑 srcset 属性。另外,我们自定义指令是 v-lazy,到目前为止,还没有给图片的 src 属性赋值。

render 方法,是在 Lazy 中实例化 ReactiveListener 时传递过来的参数。

回过头再来结合 lazy.js 中的 lazyLoadHandler 方法与 ReactiveListener 暴露的方法来看。

/src/lazy-container.js

LazyContainer 的核心是 container 下的选择器selector(默认 img 标签)遍历后调用 lazy 的 add 方法进行绑定,自定义指令 v-lazyload-container。

/src/lazy-component.js

上述实现元素绑定主要是通过自定义指令 v-lazy v-lazy-container 。那么 LazyComponent 则是通过注册的 lazy-component 组件,完成绑定,默认渲染成为 div 标签,作为 img 的容器。

/src/lazy-image.js

通 LazyComponent 组件,只不过 LazyImage 注册的 lazy-image 组件,渲染成的是 img 标签,多了 src 属性。

通过自定义指令 v-lazy 将设置背景图的元素或者 img元素,通过 _addListenerTarget 方法收集与数组 TargetQueue 中,并遍历触发懒加载的方法, addEventListener 绑定在该元素上,触发的事件为 lazyLoadHandler

在需要懒加载的元素上设置属性 data-src ,这是期望的图片地址(filter 配置项可以预先过滤赋值),元素上自定义 lazyLoad 表示图片状态(状态变更后,adapter 中触发回调);

ListenerQueue 数组中收集的是 ReactiveListener 类的实例,主要是用于懒加载不同状态下的图片加载,loading - loaded - error;

当触发 EventListener 了,执行 lazyLoadHandler 方法,根据算法,进入 viewport 后, ReactiveListener 元素如果与触发元素匹配,则进行图片的加载及渲染。

阅读全文

与vue源码解析github相关的资料

热点内容
猎人宝宝攻击命令 浏览:159
操作系统是编译原理吗 浏览:646
云服务器迁移后 浏览:260
excel格式转换pdf 浏览:987
登录器一般存在哪个文件夹 浏览:535
中兴光猫机器码算法 浏览:330
android响应时间测试 浏览:940
java编程思想第四版答案 浏览:888
如何对nbt编程 浏览:885
mscpdf 浏览:948
文件夹d盘突然0字节可用 浏览:272
吃火腿肠的解压场面 浏览:339
卫星锅加密教程 浏览:792
php7的特性是什么 浏览:469
编译类高级语言源代码运行过程 浏览:177
科普中国app怎么分享 浏览:87
51单片机与32单片机比较 浏览:422
SQL加密存储解密 浏览:507
电气工程师把程序加密 浏览:797
解压切东西动画版 浏览:965