Search code examples
vuejs3vue-componentprimevue

Message is added but isn't displayed


The toastmessages from PrimeVue ToastEventBus are added to the DOM but not displayed. Does anyone know why?

Based on this answer I have the following in page.

<!doctype html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <script type="text/javascript" src="https://unpkg.com/vue@3/dist/vue.global.prod.js" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
    <script type="text/javascript" src="https://unpkg.com/primevue/umd/primevue.min.js" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
    <script type="text/javascript" src="https://unpkg.com/@primevue/themes/umd/aura.min.js" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
  </head>
  <body>
    <div id="test-toastbutton"></div>
    <script type="module">
      import { createApp } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js'

      const app = createApp({
        setup() {
          const addToast = () => {
            PrimeVue.ToastEventBus.emit('add', { severity: 'info', summary: 'Info', detail: 'Message Content', life: 3000 })
          }

          return { addToast };
        },
        template: '<Toast /><button @click="addToast">Adding toast</button>'
      })
      app.use(PrimeVue.Config, {
        theme: {
            preset: PrimeVue.Themes.Aura
        }
      })
      app.component('Toast', PrimeVue.Toast)
      app.mount('#test-toastbutton')
    </script>
  </body>
</html>

In the console I see the warning:

[Vue warn]: Missing ref owner context. ref cannot be used on hoisted vnodes. A vnode with ref must be created inside the render function. 
  at <Toast> 
  at <App>

I would expect toasts to be displayed. Instead I only see them added to the DOM:

<body>
  <div id="test-toastbutton" data-v-app="">
    <portal>
      <div class="p-toast p-component p-toast-top-right" data-pc-name="toast" pc1="" data-pc-section="root" style="position: fixed; top: 20px; right: 20px;">
        <div>
          <toastmessage message="[object Object]" templates="[object Object]"></toastmessage>
          <toastmessage message="[object Object]" templates="[object Object]"></toastmessage>
          <toastmessage message="[object Object]" templates="[object Object]"></toastmessage>
          ...


Solution

  • You imported Vue twice, which is always a bad idea. The only thing you need to change is this:

    ...
        <script type="module">
            // no more import { createApp } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js'
            const { createApp } = Vue;
    ...
    

    You already have a global Vue object, so you should use its createApp. You can also go with Vue.createApp if you don't fancy the destructuring syntax.