100行代码理解和分析vue2.0响应式架构
分享前啰嗦 我之前介绍过vue1.0如何实现
以前写的那篇 可以作为本次分享的参考。
不过不看也没关系,但是最好了解下 理解vue2.0的响应式架构,就是下面这张图 顺带介绍他比react快的其中一个原因 本分实现什么 {{text}}
render(h){
return h('div',{},[
h('span',[this.__toString__(this.text)])
])
}
})
setTimeout(function(){
demo.text = "after"
},3000)
对应的虚拟dom会从 before 变为after 好,开始吧!!! 第一步,讲data 下面所有属性变为observable来来来先看代码吧 function observer(value,cb){
Object.keys(value).forEach((key) => defineReactive(value,key,value[key],cb)) } function defineReactive(obj,val,cb) { var demo = new Vue({ setTimeout(function(){ 为了好演示我们只考虑最简单的情况,如果看了可能就会很好理解,不过没关系,我们三言两语再说说,这段代码要实现的功能就是将 中data 里面所有的属性置于 observer,然后data里面的属性,比如 text 以改变,就引起_update()函数调用进而重新渲染,是怎样做到的呢,我们知道其实就是赋值的时候就要改变对吧,当我给data下面的text 赋值的时候 set 函数就会触发,这个时候 调用 _update 就ok了,但是 demo._data.text没有demo.text用着爽,没关系,我们加一个代理 然后在Vue的constructor加上下面这句 this._proxy(key)) 第一步先说到这里,我们会发现一个问题,data中任何一个属性的值改变,都会引起 _update的触发进而重新渲染,属性这显然不够精准啊 第二步,详细阐述第一步为什么不够精准比如考虑下面代码 `,data: {
name: 'js',age: 24,height: 180
}
})
setTimeout(function(){
class Vue {
constructor(options) { this.$options = options const vdom = this._update() console.log(vdom) } _update() { return this._render.call(this) } _render() { const vnode = this.$options.render.call(this) return vnode } h(tag,attr,children) { return VNode(tag,children.map((child)=>{ if(typeof child === 'string'){ return VNode(undefined,undefined,child) }else{ return child } })) } toString(val) { return val == null ? '' : typeof val === 'object' ? JSON.stringify(val,null,2) : String(val); } } var demo = new Vue({ 我们运行一下,他会输出 这就是 虚拟最简单虚拟
回到开始的问题,也就是说,我得知道,
就像这段代码,render 函数里其实只依赖text,并没有依赖name和age,所以,我们只要text改变的时候,我们自动触发render 函数 让它生成一个虚拟DOM就ok了(剩下的就是这个虚拟DOM和上个虚拟DOM做比对,然后操作真实DOM,只能以后再说了),那么我们正式考虑一下怎么做 回到最上面那张图,我们知道
然后,当执行render 函数去'touch'依赖的时候,依赖到的变量get就会被执行,然后我们就可以把这个 render 函数加到 subs 里面去了。
当我们,set 的时候 我们就执行 notify 将所有的subs数组里的函数执行,其中就包含render 的执行。
至此就完成了整个图,好我们将所有的代码展示出来 <div class="jb51code"> class Vue { function observer(value,get: ()=>{ class Dep { var demo = new Vue({ setTimeout(function(){ 我们看一下运行结果 好我们解释一下 Dep.target 因为我们得区分是,普通的get,还是在查找依赖的时候的get,所有我们在查找依赖时候,我们将 Dep.target 赋值,相当于 flag 一下,然后 get 的时候 {
if (Dep.target) {
dep.add(Dep.target)
}
return val
},
判断一下,就好了。到现在为止,我们再看那张图是不是就清楚很多了? 总结我非常喜欢,vue2.0 以上代码为了好展示,都采用最简单的方式呈现。 不过整个代码执行过程,甚至是命名方式都和vue2.0一样。 对比react,vue2.0 自动帮你监测依赖,自动帮你重新渲染,而react 要实现性能最大化,要做大量工作,比如我以前分享的:
而vue2.0 天然帮你做到了最优,而且对于像万年不变的 如标签上静态的
本文已被整理到了《》,欢迎大家学习阅读。 关于vue.js组件的教程,请大家点击专题进行学习。 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程之家。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |