数据驱动
1.数据响应式
数据模型是普通的JS对象,而当我们修改数据时,视图会进行更新,避免DOM操作
2.双向绑定
数据改变,视图改变;视图改变,数据也随之改变(玩过Angular的不会陌生)
3.数据驱动
Vue最独特的特性之一,开发过程中仅需关注数据本身,不需要关心数据是如何渲染到视图
响应式核心原理
Vue 2.X
基于Object.defineProperty
把一个普通的 JavaScript 对象传入 Vue 实例作为 data 选项,Vue 将遍历此对象所有的 property,并使用 Object.defineProperty 把这些 property 全部转为 getter/setter.
每个组件实例都对应一个 watcher 实例,它会在组件渲染的过程中把“接触”过的数据 property 记录为依赖.之后当依赖项的 setter 触发时,会通知 watcher,从而使它关联的组件重新渲染.
(大坑) 对于已经创建的实例,Vue 不允许动态添加根级别的响应式 property.但是,可以使用 Vue.set(object, propertyName, value) 或者 this.$set(object, propertyName, value) 方法向嵌套对象添加响应式 property.
Vue 3.X
基于Proxy
直接监听对象,而非属性
把一个普通的 JavaScript 对象作为 data 选项传给应用或组件实例的时候,Vue 会使用带有 getter 和 setter 的处理程序遍历其所有 property 并将其转换为 Proxy.因为Proxy的特性,所以在响应式时不需要检测值变化,直接在getter和setter里面操作.
发布订阅模式
称为发布者的消息发送者不会将消息直接发送给订阅者,这意味着发布者和订阅者不知道彼此的存在.在发布者和订阅者之间存在第三个组件,称为消息代理或调度中心或中间件,它维持着发布者和订阅者之间的联系,过滤所有发布者传入的消息并相应地分发它们给订阅者.
模拟自定义事件
1.兄弟组件的通信过程
//eventBus.js
//事件中心
let eventBus = new Vue();
//ComponentA.vue
//发布者
addTodo:function() {
//发布消息(事件)
eventBus.$emit('add-todo',{
text : this.newTodoText });
this.newTodoText = '';
}
//ComponentB.vue
//订阅者
created: function () {
//订阅消息(事件)
eventBus.$on('add-todo',this.addTodo)
}
2.模拟自定义事件
// 事件触发器
class EventEmitter {
constructor () {
//存储注册的事件,属性为事件的名称,值为对应的函数,可能有多个函数,所以是个数组
//{ 'click': [fn1,fn2],'change': [fn]}
this.subs = Object.create(null);//因为只用于存储注册的事件,所以没有原型
}
//注册事件
$on (eventType,handler) {
this.subs[eventType] = this.subs[eventType] || [];
if(typeof handler === 'function'){
this.subs[eventType].push(handler);
}
}
//触发事件
$emit (eventType, ...args) {
this.subs[eventType].forEach(handler => {
handler(...args)
})
}
}
观察者模式
跟发布订阅模式类似,但是没有事件中心,所以发布者需要知道订阅者的存在
//发布者-目标
class Dep {
constructor () {
//记录所有的订阅者
this.subs = [];
}
addSub (sub) {
if (sub && sub.update) {
this.subs.