Portal-Vue: How to use MountingPortal?

Viewed 600

I like to use MountingPortal to teleport an element (later a Component) to <body>. But the element is not moved to the target.

Setup

  1. Create a Vue app with vue create portal-test and choose Vue 2 and all defaults
  2. Add Vue-Portal: npm install --save portal-vue
  3. Edit main.js: add import PortalVue from 'portal-vue' and Vue.use(PortalVue)

In packages.json under "dependencies" I've found "portal-vue": "^2.1.7",

Add portal target in public/index.html

In the body I add a div with id target-id that should be treated as a portal target:

  <body>
    <noscript>
      <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
    </noscript>
    <hr />
    <div id="target-id">
      Hey
    </div>
    <hr />
    <div id="app"></div>

    <!-- built files will be auto injected -->
  </body>

Change App.vue

<template>
  <div id="app">
    <MountingPortal name="destination" mountTo="#target-id">
    </MountingPortal>

    <portal to="destination">
      <p>This should be rendered outside</p>
    </portal>
  </div>
</template>

Expected output

The <p>This should be rendered outside</p> should displayed between the two <hr />.

Actual output

The <p>...</p> is missing in the DOM. I've tested in Firefox and Edge, the DOM looks the same.

DOM

1 Answers

Ah, ok, a <portal-target> must be wrapped in <MountingPortal>.

This works:

<template>
  <div id="app">
    <MountingPortal mountTo="#target-id">
      <portal-target name="destination" />
    </MountingPortal>

    <portal to="destination">
      <p>This should be rendered outside</p>
    </portal>
  </div>
</template>
Related