vue是为了让普通的数据和dom的显示进行一个双向驱动。
举个例子:
1.dom驱动数据
我们写了一个input元素 但我们多写了一个v-model属性,v-model指向了vue实例的一个data的值,当input的值发什么变化时,我们改变vue实例对应的data值。
var input = 获取input的dom;
input.oninput = function (e) {
myVue.data.某个值 = e.target.value
}
2.数据驱动dom
我们写了一个div元素,里面的文本节点按vue的编译规则写好。vue知道这个节点text标签绑定了vue实例的某个值。
<div>{{vue实例的某个值}}</div>
vue 通过一个render函数创建虚拟dom
render(vue原型中创建虚拟dom的函数h){
//不知道为什么要变成h,创建虚拟dom不就一个函数吗?
//Vue.prototype.createElm == h
return h('div',null,vue实例的某个值 或者 子节点)
//按照上述例子是vue实例的某个值
}
//Vue.prototype.createElement == h
Vue.prototype.createElement=function(tag,props,children){
return {
tag:tag,
children:children,
props:props,
}
}
我们现在通过模板编译有了虚拟dom。
有些虚拟dom绑定了vue实例的某个值
这个值的改变会引起dom的更新。
如何更新呢?
虚拟dom不是绑定了vue实例的data吗? 我们给这个data写一个数组来收集这些依赖我的dom
function defineReactive(obj,key,val){
Object.defineProperty(obj,key,{
get(){
return val
},
set(newVal){
val=newVal;
kvue.update();
}
})
return
}
麻痹,实在是写不下去了,vue的原理就是if else vue的源码一个函数还有多重逻辑为什么不分开定义函数,真是服了。不就是数据驱动视图吗,整那么复杂干嘛
class Dep {
constructor(val){
this.val = val;
this.subs = []
}
//虚拟dom有引用就要添加进去
addSub(sub){
this.subs.push(sub);
}
//虚拟dom不再引用,或不再存在就要调用这个 我觉得可以用weakmap
deleteSub(obj){
//找到然后删除
}
notify(){
this.subs.forEach((sub) =>{
sub.update()
})
}
}
//this.subs数组里面是一个vnode
var data={
title:'我是一个标题'
}
function defineReactive(obj,key,mydep){
Object.defineProperty(obj,key,{
get(){
return mydep.val;
},
set(newVal){
val=newVal;
mydep.notify();
}
})
return mydep;
}
var dep=new Dep(data.title);
defineReactive(data,title,dep);
//核心部分就是vnode的创建
//通过模板编译需要 找到引用,然后给每个有引用数据的添加一个update函数就行了,并在Dep实例添加这个vnode.
被引用的数据会多有一个update函数 给收集用
每个vnode想要删除都必须通过函数实现,然后层层遍历找到有引用的vnode 并调用update函数通知所收集器删除自己,当然用weakmap的话好像还可以省掉这一步。
按照我这个思路也可以完美实现响应式数据驱动视图。
不想了,别人都做了轮子还要我再做一遍真服了,人的想法又不是一致的,