English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Análisis de los principios de Vue.js y el módulo observer detallado

Introducción

El módulo observer es uno de los más importantes del núcleo de Vue (creo que es), capaz de implementar la actualización reactiva de la vista y los datos, apoyado por el observer en la capa inferior.

Atención:Este artículo es sobre [email protected] el análisis

La ubicación del código del módulo observer en el proyecto Vue es src/core/El módulo observer se divide en varias partes:

  1. Observer: El observador de datos, que permite que las operaciones de lectura y escritura del objeto de datos estén bajo su supervisión
  2. Watcher: El suscriptor de datos, cuando los datos cambian, se notificará a Watcher y luego Watcher realizará la operación correspondiente, como actualizar la vista
  3. Dep: El nudo entre Observer y Watcher, cuando los datos cambian, serán observados por Observer y luego notificados por Dep a Watcher

La ilustración es la siguiente:

Observer

La clase Observer se define en src/core/observer/En index.js, veamos primero el constructor de Observer

constructor (value: any) {
 this.value = value
 this.dep = new Dep()
 this.vmCount = 0
 def(value, '__ob__', this)
 if (Array.isArray(value)) {
 const augment = tieneProto
 ? protoAugment
 : copiarAugment
 augment(value, arrayMethods, arrayKeys)
 this.observeArray(value)
 }
 this.walk(value)
 }
}

value es el objeto de datos que necesita ser observado, en el constructor, se añadirá el atributo __ob__ a value como un marcador de que los datos ya han sido observados por Observer. Si value es un array, se utilizará observeArray para iterar value y llamar a observe para observar cada elemento de value por separado. Si value es un objeto, se utilizará walk para iterar cada clave de value, y para cada clave llamar a defineReactive para obtener el set de la clave correspondiente/controlar.

Explicaré la función de varios funciones utilizadas anteriormente:

  • observeArray: Itera el array, llamando a observe para cada elemento del array
  • observe: Verifica si el objeto tiene la propiedad __ob__; si existe, significa que el objeto ya está siendo observado por el Observer; si no existe, new Observer se utiliza para observar el objeto (de hecho, hay algunos lógicos de juicio, pero se omiten aquí para facilitar la comprensión)
  • walk: Recorre cada clave del objeto, y para cada clave del objeto, llama a defineReactive
  • defineReactive: Utiliza Object.defineProperty para configurar la propiedad key del objeto, lo que permite capturar el valor set de la propiedad/Acción get. Generalmente, es el objeto instancia de Watcher el que realiza la operación get, en este caso, el objeto instancia de Watcher se añade automáticamente al array de dependencias de la instancia de Dep. Cuando se desencadena una operación set desde el exterior, se notificará a todos los watchers dependientes mediante la notificación de la instancia de Dep.

Si no entiende bien la descripción de texto anterior, puede ver la imagen:

Dep

Dep es el lazo entre Observer y Watcher, también se puede considerar que Dep es un sistema de suscripción al servicio de Observer. Watcher se suscribe a la Dep del Observer, y cuando los datos observados por el Observer cambian, se notifica a todos los watchers ya suscritos a través de Dep.

Dep ofrece varias interfaces:

  • addSub: Recibe como parámetro una instancia de Watcher y la almacena en el array que registra las dependencias
  • removeSub: Es equivalente a addSub, y su función es quitar la instancia de Watcher del array que registra las dependencias
  • depend: En Dep.target se almacena la instancia de Watcher actual que necesita ser operada. Al llamar a depend, se invoca el método addDep del instancia de Watcher, y la función de addDep se puede ver en la siguiente introducción a Watcher
  • notify: Notifica a todos los watchers en el array de dependencias para que realicen operaciones de actualización

Watcher

Watcher se utiliza para suscribirse a los cambios en los datos y ejecutar las operaciones correspondientes (por ejemplo, actualizar la vista). La función constructora de Watcher se define como sigue:

constructor (vm, expOrFn, cb, options) {
 this.vm = vm
 vm._watchers.push(this)
 // options
 if (options) {
 this.deep = !!options.deep
 this.user = !!options.user
 this.lazy = !!options.lazy
 this.sync = !!options.sync
 }
 this.deep = this.user = this.lazy = this.sync = false
 }
 this.cb = cb
 this.id = ++uid // uid para agrupar
 this.active = true
 this.dirty = this.lazy // para observadores perezosos
 this.deps = []
 this.newDeps = []
 this.depIds = new Set()
 this.newDepIds = new Set()
 this.expression = process.env.NODE_ENV !== 'production'
 ? expOrFn.toString()
 : ''
 if (typeof expOrFn === 'function') {
 this.getter = expOrFn
 }
 this.getter = parsePath(expOrFn)
 if (!this.getter) {
 this.getter = function () {}
 process.env.NODE_ENV !== 'production' && warn(
 `Falló al observar la ruta: "${expOrFn}" ` +
 'Watcher solo acepta puntos simples- +
 'Para tener control total, utilice una función en su lugar.',
 vm
 )
 }
 }
 this.value = this.lazy
 ? undefined
 : this.get()
}

En los parámetros, vm representa la instancia del componente, expOrFn representa el campo de datos a suscribir (representado como una cadena, por ejemplo, a.b.c) o una función a ejecutar, cb representa la función de retroalimentación después de que el watcher se ejecute, options es el objeto de opciones, que contiene configuraciones como deep, user, lazy, etc.

El ejemplo de instancia de watcher tiene estos métodos:

  • get: Establece Dep.target como la instancia actual de watcher, llama internamente a this.getter, si en este momento se toma el valor de un objeto observado por Observer, la instancia actual de watcher se suscribirá automáticamente a la instancia Dep del objeto de datos
  • addDep: Recibe como parámetro dep (instancia de Dep), hace que el ejemplo watcher actual suscriba a dep
  • cleanupDeps: Eliminar la información de suscripción registrada en newDepIds y newDep para dep
  • update: Ejecutar inmediatamente el watcher o agregar el watcher a la cola para ejecutarla unificada
  • run: Ejecutar watcher, llamar a this.get() para obtener el valor y luego activar la devolución de llamada
  • evaluate: Llamar a this.get() para obtener el valor
  • depend: Recorrer this.deps, hacer que el ejemplo watcher actual suscriba a todos los dep
  • teardown: Eliminar todas las suscripciones del ejemplo watcher actual

Métodos de Array

en src/core/observer/En array.js, el framework Vue ha modificado métodos de arrays como push, pop, shift, unshift, sort, splice, reverse, que al llamar a estos métodos, activan automáticamente dep.notify(), resolviendo el problema de que al cambiar el array no se puede activar la actualización.

También hay explicaciones sobre esto en el documento oficial de Vue: http://cn.vuejs.org/v2/guía/list.html#métodos-de-mutación

Resumen

Esto es todo el contenido de este artículo, espero que el contenido de este artículo pueda ayudar a algunos de ustedes en su aprendizaje o trabajo. Si tienen alguna pregunta, pueden dejar comentarios para intercambiar.

Declaración: El contenido de este artículo se ha obtenido de la red, es propiedad del autor original, el contenido se ha contribuido y subido por los usuarios de Internet de manera autónoma. Este sitio no posee los derechos de propiedad, no ha sido editado por humanos y no asume ninguna responsabilidad legal relacionada. Si encuentra contenido sospechoso de infracción de derechos de autor, le invitamos a enviar un correo electrónico a: notice#oldtoolbag.com (al enviar un correo electrónico, reemplace # con @) para denunciar, y proporcione evidencia relevante. Una vez verificada, este sitio eliminará inmediatamente el contenido sospechoso de infracción.

Te gustará también