Tabla de contenido
prefacio
El modo de observador y el modo de publicación-suscripción se usan a menudo en el desarrollo diario, y no he podido hacer una buena distinción. Recientemente estuve mirando el código fuente de Vue. El modo observador estaba diseñado en él. Estaba más interesado, así que fui a aprenderlo. Hagamos un resumen aquí.
1. Modo de publicación y suscripción
¿Qué es el patrón de publicación-suscripción?
Según uno 事件中心
, el objeto que recibe la notificación es el suscriptor, que primero debe suscribirse a un evento, y el objeto que activa el evento es el publicador, y el publicador notifica a cada suscriptor activando el evento.
Por ejemplo: Por ejemplo, la cuenta oficial de WeChat a la que se suele suscribir, aquí implica dos roles: la cuenta oficial (centro de eventos) y el usuario (suscriptor) que se ha suscrito a la cuenta oficial. Cuando el autor de la cuenta oficial publica un artículo, los usuarios que se suscriban a la cuenta oficial recibirán la noticia, lo que implica otro rol: el autor (editor) de la cuenta oficial.
Escenario de aplicación
El bus de eventos en vue es el modo de publicación-suscripción utilizado; utiliza $emit
, $on
se comunica con componentes hermanos y pasa parámetros.
Implemente manualmente el modo de publicación-suscripción en vue:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue 中发布订阅模式</title>
</head>
<body>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
// Vue 的实例,创建事件总线
let bus = new Vue()
// 订阅事件
bus.$on('eventName1', val => {
console.log('eventName1---->', val)
})
bus.$on('eventName2', val => {
console.log('eventName2---->', val)
})
// 发布事件
bus.$emit('eventName1', 'eventName1')
bus.$emit('eventName2', 'eventName2')
}
</script>
</body>
</html>
Imprimir resultado:
En el código anterior, bus
eso es lo que creamos 事件总线
, es una instancia de Vue. Podemos introducir esta instancia en diferentes componentes y usar el método $on para escuchar eventos y usar el método $emit para desencadenar eventos. Al compartir la misma instancia de bus de eventos, diferentes componentes pueden comunicarse a través de eventos para lograr el desacoplamiento.
Cabe señalar que cuando utilice el modo de bus de eventos, asegúrese de que el bus de eventos se active en el momento adecuado 销毁
para evitar 内存泄漏
problemas. El bus de eventos se puede destruir en el enlace del ciclo de vida de un componente:
beforeDestroy() {
bus.$off();
}
2. Modo observador
1) ¿Qué es el patrón del observador?
El objeto objetivo y el objeto observador tienen una relación de interdependencia. El observador observa el estado de un objeto. Si el estado del objeto cambia, notificará a todos los observadores que dependen del objeto para realizar una operación de actualización.
El modo observador tiene uno menos que el modo publicar-suscribir 事件中心
.
- Objeto objetivo [Sujeto]: es el objeto observado, que mantiene un conjunto de observadores y proporciona
添加、删除和通知
métodos para los observadores. - Objeto observador [Observar]: Recibir y procesar notificaciones de cambios de estado del Sujeto.
- Cuando cambie el estado del objeto de destino [Sujeto], notifique a todos los objetos observadores [Observe] para realizar una operación de actualización.
2) Escenarios de aplicación
Escenario de aplicación del modo observador en Vue: cambio de respuesta a datos .
En el artículo anterior sobre aprendizaje del código fuente de Vue: principio de respuesta a datos , aprendimos que cada atributo de respuesta tiene una instancia de dep, y dep almacena un observador que depende de este atributo (el observador es una función que observa cambios en los datos). notifique a todos los observadores que dependen de él para llamar al método de actualización. Por lo tanto, el observador debe ser recogido por el objeto de destino para notificar a todos los observadores que dependen de él .
¿Por qué se debe almacenar dep en el observador? El motivo es que el observador que se está ejecutando actualmente necesita saber qué departamento se notificó a sí mismo en este momento .
3) Modo observador en vue
Observador (suscriptor) - Observador
update()
: Cuando ocurre el evento, lo específico que se debe hacer.
Targeter (Editor) - Dep
subs数组
: almacenar todos los observadores.addSub()
: Añadir observador.removeSub()
: Eliminar el observador.notify()
: Notificar a los observadores; llamar a update() de todos los observadores cuando ocurra el evento.
sin centro de eventos
Implementando el patrón de observador manualmente
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>观察者模式</title>
</head>
<body>
<script>
// 目标者(发布者)
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')
}
}
//创建实例化对象 测试一下
let dep = new Dep()
let watcher = new Watcher()
let watcher1 = new Watcher()
// 添加订阅者
dep.addSub(watcher)
dep.addSub(watcher1)
// 开启通知
dep.notify()
// 执行结果 update --->
</script>
</body>
</html>
Imprimir resultado: activar la notificación de actualización dos veces.
3. La diferencia entre el modo publicar-suscribir y el modo observador
1) Análisis a partir de la composición
- En el modo observador, solo hay dos roles:
观察者
y目标者
(también llamado observado). Entre ellos, la persona observada es el punto clave. - En el modelo de publicación-suscripción, no solo hay
发布者
y订阅者
, sino también uno事件中心
. Entre ellos, el centro de eventos es el foco.
Patrón de observador | modelo de publicación-suscripción |
---|---|
2 personajes | 3 personajes |
El foco está en lo observado (objetivo) | El foco está en el centro de eventos. |
2) Análisis desde la relación
- El observador y el objetivo están débilmente acoplados.
- Editores y suscriptores, no hay acoplamiento en absoluto.
3) Análisis desde la perspectiva del uso
- Modo de observador, utilizado principalmente dentro de una sola aplicación (el cambio de respuesta de datos en Vue es el modo de observador)
- Modo de publicación-suscripción, más para el modo de aplicación cruzada (como los que usamos comúnmente
消息中间件
)
Puede referirse a:
modo de suscripción de publicación y modo de observador