[Vue warn]:inject()只能在setup()或功能组件内部使用

Mar*_*tin 4 javascript vue.js primevue vuejs3

我想使用PrimeVue库中的 Toast 组件,并且还想为其创建一个很好的可重用服务,但我收到此错误。如果我不尝试为 Toast 通知提取单独的服务,这似乎不是问题。

但我确实想useToast()从自定义服务内部调用,而不是直接在组件的setup函数中调用。

我正在使用Vue 3.2.25最新Vite.js 2.9.9版本的PrimeVue

[Vue warn]: inject() can only be used inside setup() or functional components.
[Vue warn]: Unhandled error during execution of native event handler 
  at <App>

Uncaught Error: No PrimeVue Toast provided!
    at useToast (usetoast.esm.js:8:15)
    at Proxy.showToast (toastService.js:4:19)
    at _createElementVNode.onClick._cache.<computed>._cache.<computed> (App.vue:4:21)
    at callWithErrorHandling (runtime-core.esm-bundler.js:155:22)
    at callWithAsyncErrorHandling (runtime-core.esm-bundler.js:164:21)
    at HTMLButtonElement.invoker (runtime-dom.esm-bundler.js:369:13)
Run Code Online (Sandbox Code Playgroud)

这是CodeSandbox链接:https://codesandbox.io/s/prime-vue-toast-issue-owcio8?file=/src/ services/toastService.js

这是我的main.js

[Vue warn]: inject() can only be used inside setup() or functional components.
[Vue warn]: Unhandled error during execution of native event handler 
  at <App>

Uncaught Error: No PrimeVue Toast provided!
    at useToast (usetoast.esm.js:8:15)
    at Proxy.showToast (toastService.js:4:19)
    at _createElementVNode.onClick._cache.<computed>._cache.<computed> (App.vue:4:21)
    at callWithErrorHandling (runtime-core.esm-bundler.js:155:22)
    at callWithAsyncErrorHandling (runtime-core.esm-bundler.js:164:21)
    at HTMLButtonElement.invoker (runtime-dom.esm-bundler.js:369:13)
Run Code Online (Sandbox Code Playgroud)

这是我的App.vue

<template>
    <Toast />

    <button @click="showToast">Show toast!</button>
</template>

<script setup>
    import Toast from 'primevue/toast';
    import { showToast } from './services/toastService';
</script>
Run Code Online (Sandbox Code Playgroud)

这是我的toastService.js:

import App from './App.vue'
import { createApp } from 'vue'
import PrimeVue from 'primevue/config';
import 'primevue/resources/primevue.min.css';
import 'primevue/resources/themes/lara-dark-blue/theme.css';
import ToastService from 'primevue/toastservice';

const app = createApp(App);

app.use(PrimeVue);
app.use(ToastService);

app.mount('#app')
Run Code Online (Sandbox Code Playgroud)

Est*_*ask 13

Vue 可组合项主要应该在创建组件实例时直接在设置函数中使用。其中一些可以在其他地方使用,但这取决于可组合项的实现,并且应该另外确认。

该错误表明在内部useToast使用inject,这限制了该可组合项的使用。

对于可重用的服务,它可以是:

import { useToast } from "primevue/usetoast";

export const useToastService = () => {
  const toast = useToast();

  const showToast = () => {
    toast.add({ severity: 'info', detail:'Hello' });
  }

  return { showToast };
};
Run Code Online (Sandbox Code Playgroud)

并使用如下:

const { showToast } = useToastService();
Run Code Online (Sandbox Code Playgroud)

PrimeVueToast实现中实际上不需要使用useToast可组合项,它是一个方便的助手;看看这个这个。由于在下一个主要库更新时重构 toast 服务存在一定风险,因此可以简化为使用:

import ToastEventBus from 'primevue/toasteventbus';

export const useToastService = () => {
  const showToast = () => {
    ToastEventBus.emit('add', { severity: 'info', detail:'Hello' });
  }

  return { showToast };
};
Run Code Online (Sandbox Code Playgroud)

这样,可以在应用程序的任何位置(例如在路由器中)谨慎地使用该服务。