前言
随着互联网行业的飞速发展,互联网所携带的产业也迎来了春天,尤其是前端行业更为突出,各种框架层出不穷,Vue
React
Angular
Solid
等优秀框架的出现,不仅使得前端行业发生了翻天覆地的变化,还大大减轻了开发者的学习成本,但是随着框架的不断优化和版本升级,我们不在只追逐如何去使用这些框架,而是把目光留在了框架本身,比如框架的设计思想、框架的实现方案、以及框架的设计模式等等
为什么介绍Vue2
Vue3
的组合式API,和hooks
设计已经成熟,可以说是对Vue2
进行了彻底的颠覆- 比如
Vue2
中,响应式拦截采用的是Object.defineProperty
而Vue3
中采用的是Proxy
- 对于小白是学习
Vue2
还是Vue3
,尤大在 Vue Toronto 的主题演讲中也回答了Vue3
是向下兼容的,可以直接学习Vue3
即可 那么为什么还要介绍Vue2
,我认为虽然Vue2
已经要新版本取代,但是Vue2
的设计思想和实现原理值得我们去深度刨析,框架的设计思想是不会过期的,这仍是值得我们学习的地方
观察者模式
Vue2
的响应式开发,采用的就是设计模式中的观察者模式,这个设计模式在开发过程中也是用的最多的一种,下面我们一起来看一下观察者模式的实现原理
观察者模式下有两个重要的角色,分别是发布者
与订阅者
,通常情况下,发布者只有一个,而订阅者有很多个, 当状态发生改变(发布者发布信息),会通知所有订阅者进行更新处理,那么这个过程就是观察者模式的实现
发布者类
class Publisher {constructor() {// 订阅者 依赖存储器 初始化this.observers = [];}// 增加订阅者add(observer) {this.observers.push(observer);}// 删除订阅者remove(observer) {const eq = this.observers.findIndex(observer);if (eq) {this.observers.splice(eq, 1);}}// 通知订阅者更新notify() {this.observers.forEach((item) => {item?.update(this);});}
}
我们看一下这段代码,这是一个发布者
类,主要的方法有,添加订阅者add
、删除订阅者remove
、通知订阅者notify
订阅者类
class Observer {constructor() {console.log("订阅者 创建了");}update() {console.log("更新");}
}
订阅者
类的解构很简单,只有一个 update
方法, 订阅者
通过调用 Publisher.add(订阅者)
当发布者
发布通知后,会逐个调用 notify
进行调用
现学现用
最近
华为mate50
和iphone14
发布会已经结束,大家都在挣钱恐后的抢购,导致服务器爆炸,特喵的我根本就挤不进去,跑偏了不好意思,哈哈哈。那么我们现在有个需求,有一个手机厂商(phoneFactory
),他会不定时的发布一款新的手机,而我们有A、B、C三位同学(studentObserver
)着急换手机,所以就一直在等待这个厂商的新品发布,那么我们如何实现一个当phoneFactory
工厂发布新手机时,通知studentObserver
购买
PhoneFactory
class PhoneFactory extends Publisher {constructor() {// 执行继承类的构造函数super();// 初始化手机 默认是没有this.phone = null;this.phonePrice = 0;// 订阅者列表 存起来用于通知this.observers = [];}// 获取当前的产品名称和价格getProduct() {return {phone: this.phone,phonePrice: this.phonePrice};}// 修改产品信息setPrd(phone, phonePrice) {this.phone = phone;this.phonePrice = phonePrice;// 通知订阅者可以购买了this.notify();}
}
studentObserver
class StudentObserver extends Observer {constructor(name, price) {super();// 订阅者姓名this.name = name// 资产this.price = price;// 当前手机型号this.phoneModel = 'HUAWEI nova5 pro';}// update 购买update(Publisher) {// 更新需求文档let foo, boo = falsefoo = Publisher.getProduct();if(foo.phonePrice < this.price) {// 买得起boo = true// 换新手机了,修改手机的参数this.price -= foo.phonePricethis.phoneModel = foo.phone} // 其他逻辑this.run(boo);}// 执行的逻辑run(boo) { console.log(`${this.name} ${boo ? "购买了新手机" : "存款买不起"}`,`存款剩余 ${this.price}`, `当前手机:${this.phoneModel}`);}
}
代码测试:
// 工厂
const Factory = new PhoneFactory()
// 学生A、B、C
// A同学有一万块钱
const A= new StudentObserver('A', 10000)
// B同学有四千块钱
const B= new StudentObserver('B', 4000)
// C同学有两千块钱
const C= new StudentObserver('C', 2000)
// 学生订阅到工厂
Factory.add(A)
Factory.add(B)
Factory.add(C)
// 工厂发布手机
Factory.setPrd('iphone14 pro max 远峰蓝',