本文将详细解答以下问题
如何理解mvvm
说一下使用jQuery和使用mvvm框架的区别
说一下对mvvm的理解
vue如何实现响应式
vue如何解析模板
vue的整个实现流程
- 数据和视图分离,解耦(开放封闭原则)
2.以数据驱动视图,只关心数据变化,DOM操作被封装
mvc(modal, view, controller)
mvvm(modal, view, viewModal)
viewModal: 连接modal和view的桥梁
mvvm是借鉴了后端的mvc发展而来的,把controller变成了viewModal
响应式就是:修改data属性之后,vue立即监听到。data属性被代理到vm上。使用Object.defineProperty来定义访问器属性。
let obj = {};
let name = 'tom';
Object.defineProperty(obj, 'name', {
get () {
console.log('get');
return name;
},
set (newVal) {
console.log('set');
name = newVal;
}
})
不能 , data中每个属性都会双向绑定,但不是每个属性都会在模板中渲染,
所以这里会有这样一个逻辑:当一个属性的get有用时才会走set,因为如果你没有get,说明你跟渲染无关,
此时set他也不用渲染。这样可以避免不必要的渲染,提高性能。
···
vue模板解析中使用了with语法,但是实际开发中不推荐使用with
// js中的with语法
const obj = {
name: 'tom',
age: 20,
getAddress () {
alert('beijing');
}
}
// 不用with
function fn() {
alert(obj.name);
alert(obj.age);
obj.getAddress();
}
// 使用wid
function fn() {
with(obj) {
alert(name);
alert(age);
getAddress();
}
}
先来个简单的模板转render函数的例子
<div id="app">
<p>{{price}}</p>
</div>
var vm = new Vue({
el: "#app",
data: {
price: 100
}meth
});
//模板对应的render函数片段
with(this) { // this就是vm
return _c(
'div',
{
attrs: {"id": "app"}
},
[
_c('p', [_v(_s(price))])
]
)
}
vue文件中的html模板部分最终都会被编译为render函数。同样的,React中的jsx模板也是通过编译之后变成js代码来使用的。
vue2.0开始支持预编译。预编译就是在打包的时候,就把我们写在.vue文件中的html模板编译成js的render函数。部署到线上的时候都是就已经都是js了
1. vm._c其实相当于snabbdom中的h函数,他们都是render函数
2. render函数执行之后,返回的是vnode
3. data中每次修改数据的时候,执行updateComponent
第一步:解析模板成render函数(因为预编译,这一步在打包的时候就发生了)
1. with的用法
2. 模板中所有信息都被render函数包含
3. 模板中用到的data中的属性都变成了js变量
4. 模板中的v-modal,v-for,v-on都变成js逻辑
5. render函数返回vnode
第二步:响应式开始监听(页面打开js开始执行的时候发生)
1. Object.defineProperty
2. 将data的属性代理到vm上
第三步:首次渲染,显示页面且绑定依赖
1.虚拟dom中的patch函数(第一种用法) patch(el, vnode)
第四步:data属性变化,触发re-render
1.虚拟dom中的patch函数(第二种用法) patch(preVnode, newVnode)