Cette fois, je vais vous apporter une explication détaillée du cas d'utilisation de la fonction Vue Mixin. Quelles sont les précautions à prendre pour le cas d'utilisation de la fonction Vue Mixin ? Ce qui suit est un cas pratique, jetons un coup d'oeil.
Il existe un 'vue-class-component'
et un 'vue-property-decorator'
recommandé dans l'organisation officielle de vuejs, mais ils n'ont pas été mis en œuvre en conséquence. Après avoir examiné le premier problème, il existe une fonctionnalité qui est en attente depuis longtemps et est la prise en charge du mixin.
Ce n’est pas compliqué, écrivez-en un vous-même.
Dernière remarque : vue-class-component 6.2.0 commence à fournir la méthode mixins, qui est similaire à l'idée d'implémentation de cet article.
Impléments
import Vue, { VueConstructor } from 'vue' export type VClass<T> = { new(): T } & Pick<VueConstructor, keyof VueConstructor> /** * mixins for class style vue component */ function Mixins<A>(c: VClass<A>): VClass<A> function Mixins<A, B>(c: VClass<A>, c1: VClass<B>): VClass<A&B> function Mixins<A, B, C>(c: VClass<A>, c1: VClass<B>, c2: VClass<C>): VClass<A&B&C> function Mixins<T>(c: VClass<T>, ...traits: Array<VClass<T>>): VClass<T> { return c.extend({ mixins: traits }) }
Déclarez VClass
function Mixins<T>(c: VClass<T>, ...traits: Array<VClass<T>>): VClass<T> { return c.extend({ mixins: traits }) }
Quant à ABC, il s'agit d'un travail purement manuel de déclaration de type.
Utilisation
En utilisation réelle :
import { Component, Vue } from 'vue-property-decorator' import { Mixins } from '../../util/mixins' @Component class PageMixin extends Vue { title = 'Test Page' redirectTo(path: string) { console.log('calling reidrectTo', path) this.$router.push({ path }) } } interface IDisposable { dispose(...args: any[]): any } class DisposableMixin extends Vue { _disposables: IDisposable[] created() { console.log('disposable mixin created'); this._disposables = [] } beforeDestroy() { console.log('about to clear disposables') this._disposables.map((d) => { d.dispose() }) delete this._disposables } registerDisposable(d: IDisposable) { this._disposables.push(d) } } @Component({ template: ` <p> <h1>{{ title }}</h1> <p>Counted: {{ counter }}</p> </p> ` }) export default class TimerPage extends Mixins(PageMixin, DisposableMixin) { counter = 0 mounted() { const timer = setInterval(() => { if (this.counter++ >= 3) { return this.redirectTo('/otherpage') } console.log('count to', this.counter); }, 1000) this.registerDisposable({ dispose() { clearInterval(timer) } }) } } count to 1 count to 2 count to 3 calling reidrectTo /otherpage about to clear disposables
Notez que le DisposableMixin qui étend directement Vue n'est pas un composant Vue valide et ne peut pas être utilisé Utilisez-le directement dans l'option mixins. S'il doit être utilisé par un composant personnalisé étendu par Vue.extend, n'oubliez pas de l'envelopper avec Component.
const ExtendedComponent = Vue.extend({ name: 'ExtendedComponent', mixins: [Component(DisposableMixin)], })
Classe abstraite
Les mixins utilisés dans les systèmes d'entreprise sont en fait plus complexes dans la plupart des cas et fournissent certaines fonctions de base, mais certaines parties doivent être laissées aux successeurs pour qu'ils se mettent en œuvre eux-mêmes. temps, il convient d’utiliser des classes abstraites.
abstract class AbstractMusicPlayer extends Vue { abstract audioSrc: string playing = false togglePlay() { this.playing = !this.playing } } class MusicPlayerA extends AbstractMusicPlayer { audioSrc = '/audio-a.mp3' } class MusicPlayerB extends AbstractMusicPlayer { staticBase = '/statics' get audioSrc() { return `${this.staticBase}/audio-b.mp3` } }
Mais les classes abstraites ne peuvent pas être instanciées et ne répondent pas aux exigences { new(): T }
, elles ne peuvent donc qu'être héritées et ne peuvent pas être mélangées. Pour la même raison, les classes abstraites ne peuvent pas être 'vue-class-component'
🎜 > Décoration des fonctions des composants.
À ce stade, nous devons écrire les fonctions implémentées dans Mixin, mettre les fonctions à implémenter dans l'interface et laisser la classe spécifique les implémenter.
interface IMusicSourceProvider { audioSrc: string } /** * @implements IPlayerImplementation */ class PlayerMixin extends Vue { /** @abstract */ audioSrc: string logSrc() { console.log(this.audioSrc) } } interface IPlayerImplementation extends IMusicSourceProvider {} class RealPlayer extends Mixins(PlayerMixin) implements IPlayerImplementation { audioSrc = '/audio-c.mp3' }
Cette façon de tromper le compilateur est en fait assez maladroite. Si une classe spécifique hérite de PlayerMixin mais ne déclare pas explicitement implémenter IPlayerImplementation, le compilateur ne peut pas vous signaler cette erreur. Nous ne pouvons qu'écrire soigneusement des commentaires dans le code et espérer que les utilisateurs ne l'oublieront pas.
Je pense que vous maîtrisez la méthode après avoir lu le cas dans cet article. Pour des informations plus intéressantes, veuillez prêter attention aux autres articles connexes sur le site Web chinois de php !
Lecture recommandée :
Analyse de cas pratique du composant Progressbar
Mise en œuvre de la fonction de récupération des lettres initiales du carnet d'adresses
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!