一、和jQuery的区别
- 数据和视图的分离,解耦(开放封闭原则,扩展开放,修改封闭)
- 以数据驱动视图,只关心数据的变化,DOM 操作被封装
二、MVC
- M:Model 数据
- V:View 视图
- C:Controller 控制器、逻辑处理
三、MVVM
- M:Model 数据
- V:View 视图,模板
- VM:ViewModel 负责连接 View 跟 Model,是两者之间的桥梁,View 通过事件绑定来操作 Model,Model 通过数据绑定来操作 View
<!-- view 视图,模板 -->
<div id="app">
<div>
<input v-model="title" type="text">
<button @click="add">提交</button>
</div>
<ul>
<li v-for="item in list" :key="item">{{item}}</li>
</ul>
</div>
<script>
// model 数据
var data = {
title: '',
list: [],
};
// viewModel (view 和 model 之间的桥梁)
var vm = new Vue({
el: '#app',
data,
methods: {
add() {
this.list.push(this.title);
this.title = '';
}
}
})
</script>
// 对应的 render 函数
with (this) {
return _c('div', {
attrs: {
"id": "app"
}
},
[_c('div', [
_c('input', {
directives: [{
name: "model",
rawName: "v-model",
value: (title),
expression: "title"
}],
attrs: {
"type": "text"
},
domProps: {
"value": (title)
},
on: {
"input": function ($event) {
if ($event.target.composing) return;
title = $event.target.value
}
}
}),
_v(" "),
_c('button', {
on: {
"click": add
}
}, [_v("提交")])]),
_v(" "),
_c('ul', _l((list),
function (item) {
return _c('li', {
key: item
},
[_v(_s(item))])
}))])
}
四、VUE三要素
- 响应式:vue 如何监听到 data 的每个属性变化
- 模板引擎:vue 的模板如何被解析,指令如何处理
- 渲染:vue 的模板如何被渲染成 html ?以及渲染过程
五、响应式
什么是响应式?
(1) 修改 data 属性后,vue 能立刻监听到
(2) data 属性被代理到 vm 上(vm.name可以访问)defineProperty
var obj = {};
var name = 'jack';
Object.defineProperty(obj, 'name', {
// 监听获取
get() {
console.log('get', name);
return name;
},
// 监听设置
set(newVal) {
console.log('set', newVal);
name = newVal;
}
})
console.log(obj.name); // 获取
obj.name = 'list'; // 设置
- 模拟实现 vue
let vm = {};
let data = {
price: 100,
name: 'jack'
};
for (var key in data) {
// 用var声明就要用闭包来保证 key 的独立作用域,不然值就全是 jack
(function (key) {
Object.defineProperty(vm, key, {
get() {
console.log('get', data[key]);
return data[key];
},
set(newVal) {
console.log('set', newVal);
data[key] = newVal;
}
})
})(key)
}
六、vue 中如何解析模板
- 模板是什么
(1) 本质就是字符串
(2) 有逻辑,如v-if v-for等
(3) 与 html 格式很像(标签),但有很大的区别(逻辑)
(4) 最终还要转换为 html 来显式
(5) 模板最终必须转换成 JS 代码,因为有逻辑,必须使用 JS 才能实现(css,html无法实现逻辑)
(6) 转换为 html 渲染页面,必须用 JS 才能实现
(7) 因此,模板最终转换成一个 JS 函数(render 渲染函数) - render 函数
(1) 模板中所以的信息都包含在 render 函数中
(2) this 即 vm
(3) price 即 this.price 即 vm.price,即 data 中的 price
(4) _c 即 this._c 即 vm._c
3.render 函数与 vdom
(1) vm._c其实就相当于 snabbdom 中的 h 函数
(2) render 函数执行之后,返回的是 vnode
(3) 使用 patch 函数来对比返回的 vnode 跟上一次的 vnode 对比
(4) updateComponent 中实现了 vdom 的 patch,页面首次渲染执行 updateComponent,data 中每次修改属性,执行 updateComponent
七、vue 的整个实现流程
- 第一步:解析模板成 render 函数
- 第二步:响应式开始监听
- 第三步:首次渲染,显示页面,且绑定依赖
- 第四步:data 属性变化,触发 rerender