1.数据驱动
1.数据响应式
数据模型仅仅是普通的JavaScript对象,而当我们修改数据时,视图会自动进行更新,避免了繁琐的DOM操作,提高开发效率
2.双向绑定
数据改变,视图改变;视图改变,数据也随之改变
使用v-model在表单元素上创建双向数据绑定
3.数据驱动是Vue最独特的特性之一
开发过程中仅需要关注数据本身,不需要关心数据是如何渲染到视图
2.响应式的核心原理
Vue2.x:当你把一个普通的 JavaScript 对象传入 Vue 实例作为 data 选项,Vue 将遍历此对象所有的 property,并使用 Object.defineProperty 把这些 property 全部转为 getter/setter。Object.defineProperty 是 ES5 中一个无法 shim 的特性,这也就是 Vue 不支持 IE8 以及更低版本浏览器的原因。
function proxyData(data){
//遍历data对象的所有属性
Object.keys(data).forEach(key =>{
//把data中的属性,转换成vm的setter/getter
Object.defineProperty(vm,key,{
enumerable:true,
configurable:true,
get(){
return data[key]
},
set(newValue){
if(newValue === data[key]){
return
}
data[key] = newValue
//数据更改,更新DOM值
document.querySelector('#app').textContent = data[key]
}
})
})
}
Vue3.x: 通过Proxy实现,直接监听对象,而非属性(ES6中新增,IE无法使用)
let data ={
msg:'hello',
count:10
}
let vm = new Proxy(data,{
//执行代理行为的函数
//当访问vm的成员会执行
get(target,key){
return target[key]
},
//当设置vm的成员会执行
set(target,key,newValue){
if(target[key] === newValue){
return
}
target[key] = newValue
document.querySelector('#app').textContent = target[key]
}
})
3.发布订阅模式
存在订阅者、发布者、信号中心
我们假定,存在一个“信号中心”,某个任务执行完成,就向信号中心“发布”(publish)一个信号,其他任务可以向信号中心订阅(subscribe)这个信号,从而知道什么时候自己可以开始执行。这就叫做“发布订阅模式”
class EventEmitter{
constructor(){
this.subs = Object.create(null)
}
//注册事件
$on(eventType,handler){
this.subs[eventType] = thsi.subs[eventType] || []
this.subs[eventType].push(handler)
}
//触发事件
$emit(eventType){
if(this.subs[eventType]){
this.subs[eventType].forEach(handler => {
handler()
});
}
}
}
4.观察者模式 观察者(订阅者)--watcher
update:事件发生时,具体要做的事
目标(发布者)--Dep
subs数组:存储所有的观察者
addSub():添加观察者
notify():当事件发生,调用所有观察者的update()方法
class Dep{
//发布者-目标
constructor () {
//记录所有的订阅者
this.subs = []
}
//添加订阅者
addSub(sub){
if(sub & sub.update){
this.subs.push(sub)
}
}
//发布通知
notify(){
this.subs.forEach(sub =>{
sub.update()
})
}
}
class Watcher{
update(){
console.log('update')
}
}
5.模拟Vue响应式原理
1.整体结构
Vue:负责把data的成员注入到Vue实例,并且转换成getter/setter,Vue内部会调用Observer,Compiler
Observer:数据劫持,对data中的数据进行监听,如果数据发生变化会获取到最新的值并通知Dep
Compiler:解析每个元素中的指令与差值表达式,并替换成相应的数据
Dep:添加观察者,当数据发生变化时通知所有观察者
Watcher:通过update方法更新视图