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

问题描述 投票:0回答:4

我只是想打电话

{{ globalThing(0) }}

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

我已经尝试了各种插件配置(或混合?不确定 Nuxt 是否使用该术语。),但都无济于事。似乎无论我做什么,

globalThing
this.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>

并且...结果:

类型错误 _vm.globalFunction 不是函数


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

商店/index.js:

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

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

.vue 文件脚本:

import { mapActions } from 'vuex';

export default {

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

aaaaaaaaa 结果是......

测试结果:[对象 Promise]

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

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


编辑

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

console.log('this', this); 

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

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

vue.js plugins mixins nuxt.js
4个回答
28
投票

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

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

您必须将全局方法注入到 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
}

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

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


19
投票
  1. 使用Nuxt的inject来获取随处可用的方法
export default ({ app }, inject) => {
  inject('myInjectedFunction', (string) => console.log('That was easy!', string))
}
  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);
}

这被称为

$analytics.setAnalyticsUsersData(...)

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


0
投票

在 Nuxt 3 中,回调返回有一个

provide
属性可以实现这一点,例如:

插件文件:pusher-js.client.ts

import Pusher from "pusher-js";

export default defineNuxtPlugin((nuxtApp) => {
  const pusher = new Pusher("api_key", {
    cluster: "mt1",
    forceTLS: false,
    httpHost: "127.0.0.1",
    wsPort: 6001,
  });

  return {
    provide: {
      pusher: pusher,
    },
  };
});

组件:pages/index.vue

<script setup lang="ts">
const { $pusher } = useNuxtApp();
console.log('🚀 ~ $pusher:', $pusher)

...
</script>

参考: https://nuxt.com/docs/guide/directory-struct/plugins#providing-helpers


-1
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.