初探Vue源码(一)
前言
这段时间因为忙着秋招,好像很久都没有更新过了,现在秋招也没个着落,花了几天的时间看了一下Vue的源码,当然是跟着视频教程走的,但是视频有几节没有,所以还是挺遗憾的,知识点还是比较多的,这里做个总结,希望能够帮助到后面的面试。
一上手就直接翻Vue源码的话,还是比较痛苦的,这里采用的是另一种方式,先对后面出现的相关知识点进行整理,最后再来看源代码部分,这样会好很多,视频也是按照这样的流程走的,还是比较易于理解的。(Vue版本:2.6.12)
第一部分 如何将模板与数据相结合
首先我们回顾一下Vue的使用方式
<!-- 1. 写模板 -->
<div id="root">
<p>{
{
name}}</p>
<p>{
{
message}}</p>
</div>
<script>
console.log(root);
// 2. 创建实例
let app = new Vue({
el: '#root',
data: {
name: 'handsome',
message: 'call...'
}
})
// 3.挂载 :以上这种用法的挂载在vue.js中帮我们实现了
console.log(root);
</script>
那么Vue帮我们做了什么事呢?简单来说它做了4件事:拿到模板、拿到数据、将模板和数据结合、放到页面中,下面我们分别来实现一下这几个步骤
1. 找到模板
let template = document.querySelector('#root');
2. 拿到数据
这里我们模拟一下data的数据
let data = {
name: 'jyq',
message: 'missing you...'
}
3. 将模板和数据结合(难点)
这一部分是今天这部分的难点,我们如何将模板和数据进行结合呢?
首先要明白几个知识点,我们的dom节点是分为元素节点和文本节点的,像我们的被{
{}}包裹的就是在文本节点中,所以这里的思路是:
- 遍历页面上的节点
- 元素节点
- 元素节点下可能还有其它节点,所以我们进行递归
- 文本节点
- 利用正则判断是否有{ {}},有的话用数据进行替换
- 元素节点
// 一般都是使用递归
// 在现在这个案例中 template 是 DOM 元素
// 在真正的 Vue 源码中是 DOM -> 字符串模板 -> vNode -> 真正的DOM
function compiler(template, data) {
const reg = /\{\{(.+?)\}\}/g
// 获取模板元素下的子元素
let nodeList = template.childNodes;
// 遍历子元素 判断哪些是元素节点 哪些是文本节点
for (let i = 0; i < nodeList.length; i++) {
// 1: 代表元素节点
// 3: 代表文本节点
let type = nodeList[i].nodeType;
// 若为元素节点 则继续递归 这里只考虑在元素节点下的情况 没考虑在标签中的情况
if (type === 1) {
// 递归调用
compiler(nodeList[i], data)
} else if (type === 3) {