数据驱动
数据响应式
- 数据模型仅仅是普通的javascript对象,而当我们修改数据时,视图会进行更新,避免了繁琐的DOM操作,提高开发效率
双向绑定
- 数据改变,视图改变;视图改变,数据也随之改变
- 我们可以使用v-model在表单元素上创建双向数据数据
数据驱动是Vue最独特的特性之一
- 开发过程中仅需要关注数据本身,不需要关心数据是如何渲染到视图
数据响应式的核心原理
1. Vue 2.x
-
Vue 2.x深入响应式原理
-
Object.defineProperty
-
浏览器兼容IE8以上(不兼容IE8)
<!DOCTYPE html>
<html lang="cn">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>defineProperty</title>
</head>
<body>
<div id="app">
hello
</div>
<script>
// 模拟 Vue 中的 data 选项
let data = {
msg: 'hello'
}
// 模拟 Vue 的实例
let vm = {}
Object.defineProperty(vm, 'msg', {
// 可枚举(可遍历)
enumerable: true,
// 可配置(可以使用 delete 删除,可以通过 defineProperty 重新定义)
configurable: true,
// 当获取值的时候执行
get () {
console.log('get: ', data.msg)
return data.msg
},
// 当设置值的时候执行
set (newValue) {
console.log('set: ', newValue)
if (newValue === data.msg) {
return
}
data.msg = newValue
// 数据更改,更新 DOM 的值
document.querySelector('#app').textContent = data.msg
}
})
// 测试
vm.msg = 'Hello World'
console.log(vm.msg)
</script>
</body>
</html>
- 如果有一个对象中多个属性需要被转换getter、setter 如何处理?遍历这个对象的所有属性
2.Vue3.x
1. 发布订阅模式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>发布订阅模式</title>
</head>
<body>
<script>
// 时间触发器,自定义事件
class EventEmitter {
constructor () {
// { click: [fn1, fn2], 'change': [fn]}
this.subs = Object.create(null) // 创建空对象没有原型,提升性能
}
$on (eventType, handler) {
this.subs[eventType] = this.subs[eventType] || []
this.subs[eventType].push(handler)
}
$emit (eventType) {
if (this.subs[eventType]) {
this.subs[eventType].forEach(handler => {
handler()
})
}
}
}
let em = new EventEmitter()
em.$on('click', function() {
console.log('1111')
})
em.$on('click', function() {
console.log('2222')
})
em.$emit('change')
</script>
</body>
</html>
发布订阅模式包括:订阅者,发布者,信号中心
我们假定,存在一个”信号中心“,某个任务执行完成,就向信号中心”发布“(publish)一个信号,其他任务可以向信号中心”订阅“(subscribe)这个信号,从而知道什么时候自己开始执行,这就叫做”发布/订阅模式“(publish-subscribe pattern)
2. 观察者模式
观察者(订阅者)- Watcher
update(): 当事件发生时,具体要做的事情
目标(发布者) - Dep
- subs数组:存储所有的观察者
- addSub(): 添加观察者
- notify(): 当事件发生,调用所有观察者的update()方法
- 没有事件中心