vue 底层原理 超简单的说明 大白话
原因:由于互联网风波,最近也在面试,途中遇到的相对多的问题,也是难点的就是vue底层原理,对于只会用但是不懂得小白来说真是太痛苦了,仅仅能说出来 一些 数据劫持,双向数据绑定,虚拟dom树的名词来说远远不够。成果:花费一天时间看了源码,文档,视频解析。最终得出以下的个人见解,框架高手就可走了,让我们这些拧螺丝的人互相慰藉吧!首先,你需要知道的是,vue实现过程...
原因:
由于互联网风波,最近也在面试,途中遇到的相对多的问题,也是难点的就是vue底层原理,对于只会用但是不懂得小白来说真是太痛苦了,仅仅能说出来 一些 数据劫持,双向数据绑定,虚拟dom树的名词来说远远不够。
成果:
花费一天时间看了源码,文档,视频解析。最终得出以下的个人见解,框架高手就可走了,让我们这些拧螺丝的人互相慰藉吧!
首先,你需要知道的是,vue实现过程是一个相当简单且很无脑的东西。它分为2个步骤
1、初始化页面与绑定数据
2、更新数据(单向or双向)
接下来具体说:
一、初始化数据
在这一部分你需要知道的是:Object.defineProperty 、 nodeType 、document.createDocumentFragment 这三个东西
Observe:
Object.defineProperty : 可以用这个方法可以定义一个对象假设obj的属性,如果写了get\set那么这个属性是不可以通过 obj.xxx 修改的
vue就是用了这个原理实现的数据劫持和数据代理,先说代理
this.msg = 'xxx' 在你的方法里这样写,和 vm=new Vue() ------> vm.msg='xxx' 一样的,这个无可厚非,但是其实它是被代理的,因为它用了get、set这两个方法,实现的过程其实是 this.msg = 'xxx' ----> this._data.msg = 'xxx' 其中这个引人注目的 _data就是罪魁祸首了,vue中操作的都是它。也就是说白了 : 你的data 都经过处理了 每一个都有其对应的_data
代理仅仅是让你的this.XXX = this._data.xxx 并不能实现数据绑定 也就说,想要绑定数据,还需要在对_data再一次的defineProperty
原因很简单,你触发的所有更改属性和更改值都在一个叫做 Compile方法中
Compile:
该方法,结合了nodeType 、document.createDocumentFragment ,一个是节点的类型、后面是文档流碎片,可以理解为虚拟的,不可见的 dom结构,当然这个东西需要创建。过程是这样的:
- 创建fragment
- 将dom(el:‘’#app”)里的所有内容放到里面去
- 遍历整个树,找到你的v- 标签 和{{}}这两种表达式 分别替换你设置的data
- 把整个结构,在一次替换到真实的dom中 用 appendchild
- nodeType:一个数字用来区分遍历的是个啥? document:0\element:1\attriubuite:3\text:4......等等然后做对应的操作
到这一步,初始化数据还差关键的一步 添加watcher和dep
watcher and Dep
- 这是一组很简单的 发布订阅模拟,你中有我,我中有你,是多对多的形式
- dep是用来沟通watcher 让他渲染的类其中: 一个属性就有一个dep,如果是 a.b 那么就是2个dep
- watcher 是对这个表达式的监听类 其中:一个watcher表示 在文档中 这个表达式出现的次数
- 这两个分别是在 初始化data和刚才遍历fragment时注册的
- 当页面刷新完成后,这些都做好了,也就实现了第一步,初始化页面并绑定数据与视图的关系
二、数据改变(数据驱动)
仅仅就是利用了watcher and Dep举个例子:
一个老师类 可以有多个学生类,那么老师类 里就有一个数组叫 mystudents [new student,new student,newtudent]
里面都是学生,然后 老师有一个方法叫做 “做作业!”那么就会遍历所有学生,去实现 每个学生的 做作业方法
同理,Dep中 也就是属性的改变 会告诉所有 watcher,这几个watcher 是都一样的,只是在页面出现了多少次,去更改值吧!<div v-html="msg">
<p>{{msg}}</p>msg一旦变化,就会触发 最开始那个数据 _data.msg中的 set方法 ,然后就会让 所有 msg的watcher都会改变,但是,这个v-text 和 msg具体的 改变不同了,一个是innerHTML下面是 textContent都是替换而已
watcher是通过callback 实现了 解析 文档流时候的 update方法 其实不用管是怎么改变的,你只需要知道,是通过了
this.mgs = 'xxx'------>observe(先触发的set方法,在方法里有dep)----->Dep----->Wather----->update 的过程
双向数据绑定
v-model 在源码中与其他标签属性的解析一样,只是多了一个 监听事件 input,再次触发的时候,在一次的改变dep,watcher,最后在通过watcher 里的update方法 更新了视图
所以,vue其实是单向的,并没有什么双向的驱动
学习来源:https://github.com/DMQ/mvvm/tree/master/js
更多推荐
所有评论(0)