#vuecember2020 #vuejs #vue3

PortalVue and Teleport

Everyone who is on the Internet knows them: popups, modals, overlays,… in other words: elements that overlay the rest of the content of a web page.

From a UX and UI point of view, they are easily inserted into your concept. As a developer, you often face a challenge: the place where the modal should be inserted is usually deep within the HTML structure. If you have, say, a sticky page header or other elements that are above your modal element through CSS styles, there is often no easy way to get above that other element on a pure CSS and HTML basis.

Fortunately, there is a solution for this in Vue projects: PortalVue. This small Vue plugin is maintained by one of the Vue core members. The way it works is very simple: you insert a PortalTarget anywhere within the Vue app, preferably as high up the app structure as possible. This placeholder can then be filled by a Portal component. This avoids the problem of being dependent on the HTML structure of the entire app. Covering the rest of the app with a modal thus becomes almost trivial.

Here is an example, directly from the PortalVue doc:

<portal to="destination">
  <p>This slot content will be rendered wherever the
    <portal-target> with name 'destination'
    is located.
  </p>
</portal>

<portal-target name="destination">
  <!--
  This component can be located anywhere in your app
  (i.e. right before the &lt;/body&gt; tag, good for overlays).
  The slot content of the above portal component will be rendered here.
  -->
&lt;/portal-target&gt;

The content you put into the Portal can be displayed or not via v-if. This is a reliable way to control whether the modal is shown or not.

Another advantage that we also noticed compared to other solutions: The portal itself is directly placed within the code where it is used. The syntax is obvious and thus directly understandable for developers new to the project. This greatly simplifies maintenance, debugging and clarity in the code.

In Vue3, you can even do without the plugin altogether - there, the teleport component is provided, which works very similarly.