vue.jspluginsmixinsnuxt.js

Vue/Nuxt: How to define a global method accessible to all components?


I just want to be able to call

{{ globalThing(0) }}

in templates, without needing to define globalThing in each .vue file.

I've tried all manner of plugin configurations (or mixins? not sure if Nuxt uses that terminology.), all to no avail. It seems no matter what I do, globalThing and this.globalThing remain undefined.

In some cases, I can even debug in Chrome and see this this.globalThing is indeed defined... but the code crashes anyway, which I find very hard to explain.

Here is one of my many attempts, this time using a 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;
};

and in the template in the .vue file:

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

and... the result:

TypeError _vm.globalFunction is not a function


Here's a different idea, using Vuex store.

store/index.js:

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

.vue file template: test result: {{test('fafa')}}

.vue file script:

import { mapActions } from 'vuex';

export default {

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

aaaaaaaaand the result is.........

test result: [object Promise]

OK, so at least the method exists this time. I would much prefer not to be forced to do this "import mapActions" dance etc. in each component... but if that's really the only way, whatever.

However, all I get is a Promise, since this call is async. When it completes, the promise does indeed contain the returned value, but that is of no use here, since I need it to be returned from the method.


EDIT

On the client, "this" is undefined, except that..... it isn't! That is to say,

console.log('this', this); 

says "undefined", but Chrome's debugger claims that, right after this console log, "this" is exactly what it is supposed to be (the component instance), and so is this.$store!

I'm adding a screenshot here as proof, since I don't even believe my own eyes.

just plain not possible


Solution

  • https://nuxtjs.org/guide/plugins/

    Nuxt explain this in Inject in $root & context section.

    you must inject your global methods to Vue instance and context.

    for example we have a hello.js file.

    in plugins/hello.js:

    export default (context, inject) => {
      const hello = (msg) => console.log(`Hello ${msg}!`)
      // Inject $hello(msg) in Vue, context and store.
      inject('hello', hello)
      // For Nuxt <= 2.12, also add 👇
      context.$hello = hello
    }

    and then add this file in nuxt.config.js:

    export default {
      plugins: ['~/plugins/hello.js']
    }