Vue / Nuxt:如何定义所有组件均可访问的全局方法?

时间:2019-08-26 13:47:05

标签: vue.js plugins mixins nuxt

我只想能够打电话

{{ globalThing(0) }}

在模板中,无需在每个.vue文件中定义globalThing。

我已经尝试了所有形式的插件配置(或mixins?不确定Nuxt是否使用该术语。),但无济于事。看来无论我做什么,globalThingthis.globalThing都未定义。

在某些情况下,我什至可以在Chrome中调试并看到确实定义了this.globalThing……但是代码还是崩溃了,我觉得很难解释。

这是我尝试使用插件的众多尝试之一:

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

以及.vue文件中的模板中:

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

然后...结果:

TypeError _vm.globalFunction不是函数


这是使用Vuex商店的另一种想法。

store / index.js:

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

.vue文件模板:         测试结果:{{test('fafa')}}

.vue文件脚本:

import { mapActions } from 'vuex';

export default {

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

aaaaaaaa,结果是.........

测试结果:[对象承诺]

确定,因此至少这次存在该方法。我更希望不要被迫在每个组件中进行这种“导入mapActions”舞蹈等操作……但是,如果那确实是唯一的方法,那么无论如何。

但是,由于此调用是异步的,所以我得到的只是一个Promise。完成后,promise确实包含返回的值,但这在这里没有用,因为我需要从方法中返回它。


编辑

在客户端上,“ this”是未定义的,除了……不是。也就是说,

console.log('this', this); 

表示“未定义”,但是Chrome的调试器声称,在此控制台日志之后,“ this”正好是应该的(组件实例),this。$ store也是如此。

由于我什至不相信自己的眼睛,因此我在此处添加了屏幕截图作为证据。

just plain not possible

3 个答案:

答案 0 :(得分:8)

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

Nuxt在$ root和上下文中的“注入”部分对此进行了解释。

您必须将全局方法注入Vue实例和上下文。

例如,我们有一个hello.js文件。

在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
}

,然后将此文件添加到nuxt.config.js中:

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

答案 1 :(得分:2)

  1. 使用Nuxt的注入方法可在任何地方使用
export default ({ app }, inject) => {
  inject('myInjectedFunction', (string) => console.log('That was easy!', string))
}
  1. 确保您以$ myInjectedFunction(请注意 $ )访问该函数
  2. 确保已将其添加到nuxt.config.js插件部分

如果其他所有方法均失败,则将函数包装在一个对象中并注入对象,以便模板中包含$myWrapper.myFunction()之类的东西-我们使用从各处插入的插件注入的对象,并且可以正常工作(例如,在v中-如果在模板中,则非常确定它也可以从{{}}开始工作。)

例如,我们的analytics.js插件看起来要少得多:

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

随后被称为$analytics.setAnalyticsUsersData(...)

P.S。刚刚发现了一些东西。您的插件处于客户端模式。如果您在通用环境中运行,则必须确保在SSR期间未在任何地方使用此插件(和功能)。如果在模板中,则可能在SSR中实际使用了它,因此未定义。更改您的插件以同时在两种模式下运行。

答案 2 :(得分:0)

这就是Vuex和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 }}