web-dev-qa-db-fra.com

VUE / NUXT: Comment définir une méthode globale accessible à tous les composants?

Je veux juste pouvoir appeler

{{ globalThing(0) }}

dans les modèles, sans avoir à définir de définir Libérer dans chaque fichier .vue.

J'ai essayé de toutes sortes de configurations de plug-in (ou de mixines? Je ne sais pas si NUXT utilise cette terminologie.), Tout en vain. Cela semble peu importe ce que je fais, globalThing et this.globalThing Reste indéfini.

Dans certains cas, je peux même déboguer dans Chrome et voir ceci this.globalThing Est effectivement défini ... mais le code se bloque de toute façon, que je trouve très difficile à expliquer.

Voici une de mes nombreuses tentatives, cette fois en utilisant un plugin:

nuxt.config.js:

plugins: [
    {
        src: '~/plugins/global.js',
        mode: 'client'
    },
],

global.js:

import Vue from 'vue';
Vue.prototype.globalFunction = arg => {
    console.log('arg', arg);
    return arg;
};

et dans le gabarit dans le fichier .vue:

        <div>gloabal test {{globalFunction('toto')}}</div>

et ... le résultat:

TypeError _vm.globalfunction n'est pas une fonction


Voici une idée différente, utilisant VUEX Store.

magasin/index.js:

export const actions = {
    globalThing(p) {
        return p + ' test';
    }
};

.vue Modèle de fichier: Résultat du test: {{test ('FAFA')}}

.Vue script de fichier:

import { mapActions } from 'vuex';

export default {

    methods: {
        ...mapActions({
            test: 'globalThing'
        }),
    }
};

aaaaaaaaand le résultat est .........

résultat du test: [promesse d'objet]

Ok, donc au moins la méthode existe cette fois-ci. Je préférerais de loin ne pas être obligé de faire cette "importation de mappages", etc. dans chaque composant ... mais si c'est vraiment le seul moyen, peu importe.

Cependant, tout ce que je reçois, c'est une promesse, puisque cet appel est async. Lorsqu'il se termine, la promesse contient en effet la valeur retournée, mais cela n'est pas utile ici, car j'en ai besoin pour être renvoyé de la méthode.


ÉDITER

Sur le client, "ceci" est indéfini, sauf que ..... ce n'est pas! C'est-à-dire,

console.log('this', this); 

dit "indéfini", mais le débogueur de Chrome affirme que, juste après le journal de ce console, "Ceci" est exactement ce qu'il est censé être (l'instance de composant), et c'est ainsi que c'est. $ magasin!

J'ajoute une capture d'écran ici comme preuve, car je ne crois même pas mes propres yeux.

just plain not possible

9
Marc
  1. Utilisez l'injection de NUXT pour obtenir la méthode disponible partout
export default ({ app }, inject) => {
  inject('myInjectedFunction', (string) => console.log('That was easy!', string))
}
  1. Assurez-vous d'accéder à cette fonction en tant que $ myInjectedfunction (note $)
  2. Assurez-vous de l'ajouter dans la section des plugins NUXT.CONFIG.JS

Si tout le reste échoue, enveloppez la fonction dans un objet et injecter un objet de sorte que vous auriez quelque chose comme $myWrapper.myFunction() dans vos modèles - nous utilisons des objets injectés à partir de plugins partout et cela fonctionne (par exemple, dans V- Si dans le modèle, alors sûr, cela fonctionnerait de {{}} aussi).

par exemple, notre plugin analytique.js semble plus en moins:

import Vue from 'vue';
const analytics = {
    setAnalyticsUsersData(store) {...}
    ...
}

//this is to help Webstorm with autocomplete
Vue.prototype.$analytics = analytics;

export default ({app}, inject) => {
    inject('analytics', analytics);
}

Qui est alors appelé comme $analytics.setAnalyticsUsersData(...)

P.s. Vient de remarquer quelque chose. Vous avez votre plugin en mode client. Si vous courez dans Universal, vous devez vous assurer que ce plugin (et la fonction) n'est utilisé nulle part en SSR. Si c'est dans le modèle, il est probable que cela soit réellement utilisé pendant la SSR et est donc indéfini. Changez votre plugin pour exécuter également dans les deux modes.

2
Lili