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

大城市里の小女人 提交于 2020-01-16 08:40:14

问题


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.


回答1:


  1. Use Nuxt's inject to get the method available everywhere
export default ({ app }, inject) => {
  inject('myInjectedFunction', (string) => console.log('That was easy!', string))
}
  1. Make sure you access that function as $myInjectedFunction (note $)
  2. Make sure you added it in nuxt.config.js plugins section

If all else fails, wrap the function in an object and inject object so you'd have something like $myWrapper.myFunction() in your templates - we use objects injected from plugins all over the place and it works (e.g. in v-if in template, so pretty sure it would work from {{ }} too).

for example, our analytics.js plugin looks more less:

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);
}

Which is then called as $analytics.setAnalyticsUsersData(...)

P.S. Just noticed something. You have your plugin in client mode. If you're running in universal, you have to make sure that this plugin (and the function) is not used anywhere during SSR. If it's in template, it's likely it actually is used during SSR and thus is undefined. Change your plugin to run in both modes as well.




回答2:


This would be the approach with Vuex and Nuxt:

// store/index.js

export const state = () => ({
    globalThing: ''
})

export const mutations = {
    setGlobalThing (state, value) {
        state.globalThing = value
    }
}


// .vue file script

export default {
    created() {
        this.$store.commit('setGlobalThing', 'hello')
    },
};



// .vue file template

{{ this.$store.state.globalThing }}


来源:https://stackoverflow.com/questions/57659169/vue-nuxt-how-to-define-a-global-method-accessible-to-all-components

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!