javascript - [Vue 警告] : inject() can only be used inside setup() or functional components

标签 javascript vue.js vuejs3 primevue

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

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

我正在使用 Vue 3.2.25Vite.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)

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

这是我的 ma​​in.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')

这是我的 App.vue

<template>
    <Toast />

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

<script setup>
    import Toast from 'primevue/toast';
    import { showToast } from './services/toastService';
</script>

这是我的toastService.js:

import { useToast } from "primevue/usetoast";

const showToast = () => {
    const toast = useToast();

    toast.add({ severity: 'info', detail:'Hello' });
}

export { showToast }

最佳答案

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

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

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

import { useToast } from "primevue/usetoast";

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

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

  return { showToast };
};

像这样使用:

const { showToast } = useToastService();

PrimeVue Toast 实现实际上不需要使用 useToast 组合,它是一个方便的助手;见thisthis .由于在下一次主要库更新时重构 toast 服务存在一些风险,因此可以简化为使用:

import ToastEventBus from 'primevue/toasteventbus';

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

  return { showToast };
};

通过这种方式,可以在应用程序的任何位置谨慎使用该服务,例如在路由器中。

关于javascript - [Vue 警告] : inject() can only be used inside setup() or functional components,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72425297/

相关文章:

javascript - Vue.js 和 axios 页面刷新后数组为空

javascript - VueJS - 有条件地包裹在 div 内

javascript - 如何在不同月份的javascript中获取两个日期之间的差异

php - .htaccess 拒绝从脚本下载文件

vue-component - 如何动态导入组件

javascript - Data 中的属性在methods() 方法中未定义

vue.js - 该值未绑定(bind)在 PrimeVue/TreeSelect 中

javascript - 为什么 fetch() 使用 ReadableStream 作为响应正文?

javascript - 寻找一种算法来聚类 3d 点,围绕 2d 点

typescript - 使用异步等待获取数据加载