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

Mar*_*arc 11 plugins mixins vue.js nuxt.js

我只想能够打电话

{{ globalThing(0) }}
Run Code Online (Sandbox Code Playgroud)

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

我已经尝试了各种插件配置(或 mixins?不确定 Nuxt 是否使用该术语。),但都无济于事。看来不管我做什么,globalThing并且this.globalThing仍然不确定。

在某些情况下,我什至可以在 Chrome 中调试并看到这this.globalThing确实是定义的……但无论如何代码崩溃了,我发现这很难解释。

这是我多次尝试之一,这次使用插件:

nuxt.config.js:

plugins: [
    {
        src: '~/plugins/global.js',
        mode: 'client'
    },
],
Run Code Online (Sandbox Code Playgroud)

global.js:

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

并在 .vue 文件中的模板中:

        <div>gloabal test {{globalFunction('toto')}}</div>
Run Code Online (Sandbox Code Playgroud)

和...结果:

TypeError _vm.globalFunction 不是函数


这是一个不同的想法,使用 Vuex 商店。

商店/ index.js:

export const actions = {
    globalThing(p) {
        return p + ' test';
    }
};
Run Code Online (Sandbox Code Playgroud)

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

.vue 文件脚本:

import { mapActions } from 'vuex';

export default {

    methods: {
        ...mapActions({
            test: 'globalThing'
        }),
    }
};
Run Code Online (Sandbox Code Playgroud)

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

测试结果:[object Promise]

好的,所以至少这次方法存在。我更不想被迫在每个组件中执行这种“导入 mapActions”舞蹈等......但如果那真的是唯一的方法,无论如何。

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


编辑

在客户端,“this”是未定义的,除了......不是!也就是说,

console.log('this', this); 
Run Code Online (Sandbox Code Playgroud)

说“未定义”,但 Chrome 的调试器声称,在这个控制台日志之后,“this”正是它应该是的(组件实例), this.$store 也是如此!

我在这里添加截图作为证据,因为我什至不相信自己的眼睛。

简直不可能

Lil*_*ili 17

  1. 使用Nuxt的inject获取随处可用的方法
export default ({ app }, inject) => {
  inject('myInjectedFunction', (string) => console.log('That was easy!', string))
}
Run Code Online (Sandbox Code Playgroud)
  1. 确保您以 $myInjectedFunction 的身份访问该函数(注意$
  2. 确保你在 nuxt.config.js 插件部分添加了它

如果所有其他方法都失败了,请将函数包装在一个对象中并注入对象,这样你$myWrapper.myFunction()的模板中就会有类似的东西——我们使用从插件注入的对象到处都是,它可以工作(例如,在模板中的 v-if 中,所以很确定它也适用于 {{ }})。

例如,我们的 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);
}
Run Code Online (Sandbox Code Playgroud)

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

PS刚刚注意到一些事情。您的插件处于客户端模式。如果您在通用模式下运行,则必须确保在 SSR 期间未在任何地方使用此插件(和函数)。如果它在模板中,很可能它实际上是在 SSR 期间使用的,因此是未定义的。更改您的插件以在两种模式下运行。


小智 17

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

Nuxt 在 $root & context 部分的注入中解释了这一点。

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

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

在插件/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
}
Run Code Online (Sandbox Code Playgroud)

然后在 nuxt.config.js 中添加这个文件:

export default {
  plugins: ['~/plugins/hello.js']
}
Run Code Online (Sandbox Code Playgroud)