(1)什么是vdom?
可提高重绘性能(重绘是非常贵的操作,所以需要尽量减少重绘来提高前端性能)
(2)为什么要用js?
用js模拟的dom结构,dom变化的对比需要逻辑(前端唯有js是图灵完备语言,所以选择使用js)。
(3)用js简单模拟一下vdom
<div id='container'>
<p>part1</p>
<p>part2</p>
</div>
//模拟vdom
{
tag: 'div',
attr: { id: 'container'},
children:[
{
tag: 'p',
attr: {},
children : ['part1']
},{
tag: 'p',
attr: {},
children : ['part2']
}
]
}
(4)vdom构造
通过对snabbdom库的解析,了解到实现vdom的关键函数为h()函数
用法:
//例同上个
var vnode = h('div',{id:'container'},[
h('p', {}, 'part1'),
h('p', {}, 'part2')
])
(1)什么是mvvm
mvvm即model、view、viewmodel,mvvm是在mvc的基础上有些许改进。将数据与视图解耦,也就是视图 UI 和业务逻辑分开。
(2)vue三要素
响应式、模板引擎、渲染
响应式:
vue实现响应式的关键方法Obj.defineProperty(),通过此方法将data中的数据代理到vm中,同时设置set和get监听,在值被修改或被获取时即可触发事件(比如重绘视图),下面是简单的代码演示
data:{
name: 'zhangsan',
age: 20,
gender: 'male'
}
Object.keys(data).forEach(function(key){
Object.defineProperty(vm,key,{
//可否枚举
enumerable: true,
//可否重新定义
configurable: false,
get: function() {
console.log('get',data[key]);
},
set: function(newVal) {
console.log(`set successfully`);
data[key] = newVal
}
})
})
模板引擎
因为模板中解析之后的代码需要对dom进行操作,且具有一定逻辑,所以模板一定要解析成js代码。
模板解析通过render函数,解析后返回一个vnode,类型与上面的vdom中实现方法里的h函数实现的vdom类似
//同上例dom
//这里的this是vm,with函数使用建议查看文档
//_c即 vm._c _v即vm._v
with(this){
return _c('div',{attrs:{"id" : "container"}},[
_c('p',_v("part1")),
_c('p',_v("part2"))
])
}
除了_c(创建虚拟元素节点,同上h函数)和_v(创建虚拟文本节点)还有很多方法,如_l(实现遍历)等实现逻辑的方法
渲染
渲染的实现是利用了vdom渲染的patch函数(在vue中为__patch__),patch函数中使用了diff算法,通过diff函数可以找出新旧vdom的区别并只重新渲染有变化的部分,提高了效率。
例:
var container = document.getElementById('container')
//首次渲染参数为被渲染容器(container)和vnode(在vue中即render函数的返回值)
patch(container,vnode)
//首次渲染之后,通过其他方式(例如被set监听到数据有修改)再次调用渲染时,参数为新旧vnode
patch(vnode,NewVnode)
vnode = NewVnode
总结vue模板解析渲染整体流程:
首先通过render函数将模板解析成vnode,然后通过patch首次渲染,之后设置的事件监听触发时,会触发再次渲染。