En la configuración creo algo como esto:
const abc = reactive(new AnotherClass()) return {abc}Más adelante en el componente, puedo llamar a un método de esta clase a través de abc.Func (), o acceder a algún campo, todo parece estar bien. Y aquí vamos a imaginar la situación: en el constructor de clases creamos eventListener, que escucha algo y luego establece verdadero o falso para uno de los campos de la clase. Y luego surge un problema: si muestra este campo en el componente que el controlador debe cambiar, puede ver que los campos de clase no son reactivos, es decir, cuando el controlador cambió sin ambigüedad el valor del campo, esto no es visible en el componente. Los campos son reactivos solo cuando también escribe reactivos para campos dentro de la clase. ¿Por qué? Hice que toda la clase fuera reactiva en la configuración. ¿Por qué también necesito escribir ref y reactivo dentro de la clase?
código en el componente:
<template> <div style="width: 200px; height: 200px">{{player.audioPlayer.isPlaying}}</div> </template> setup(props) { const player = reactive(new AnotherClass()) return {player} },clase:
private _onPlaying = this.onPlaying.bind(this) constructor() { this.audioPlayer = { active: false, initialized: false, element: new Audio(''), isPlaying: false, currentPlaying: { playlist: [], index: 0 } } this.audioPlayer = reactive(this.audioPlayer) // if comment this, we don't see any changes in component after onPlaying set this to true this.init() } private init(){ this.audioPlayer.element.addEventListener('playing', this._onPlaying) this.audioPlayer.initialized = true } private onPlaying() { this.audioPlayer.isPlaying = true }reactive crea un proxy para la instancia original, por lo que cuando se llama a los métodos en el objeto de proxy reactivo, lo reciben como this .
Cuando los oyentes se configuran en un constructor, están codificados para usar this original no reactivo.
Para que una clase desconozca los ayudantes reactivos de Vue, debe diseñarse de una manera que permita usar this en un constructor solo para configurar datos iniciales, no efectos secundarios. Las devoluciones de llamada no deben vincularse a this en el constructor, esto incluye campos de clase porque son azúcar sintáctico para el cuerpo del constructor.
Necesita ser:
constructor() { this.audioPlayer = {...}; // this.init() } init(){ this.audioPlayer.element.addEventListener('playing', () => this.onPlaying()) this.audioPlayer.initialized = true }Y usado como:
const player = reactive(new AnotherClass()) player.init();