1

I built a single-page app in Nuxt.js 2 and Vue2. This has a very heavy WebGL visualizer that displays a 3D scene in two separate pages: SectionDesign and SectionConfirm

<template>
    <SectionDesign v-if="currentPage === 1"></SectionDesign>
    <SectionPurchase v-if="currentPage === 2"></SectionPurchase>
    <SectionConfirm v-if="currentPage === 3"></SectionConfirm>
</template>

My problem is that when I navigate from page 1 to page 2, my <canvas> gets destroyed, I lose WebGL context, and all the loaded assets disappear. I have to re-initialize everything when I enter page 3. This is very resource-intensive and unoptimized. I'd like to create my <canvas> only once, then "move it" from one section to the next.

I can do this with vanilla Javascript by appending a child to a new parent.

const canvas = document.getElementByID("myCanvas");
page1.appendChild(canvas);

function enterPage3() {
    page3.appendChild(canvas);
}

This re-uses the same instance of the canvas, it just moves it to a new parent. Is there a way to achieve this with Vue2 and Nuxt.js?

2
  • Vanilla JS will still need to wire that to the DOM, so it's quite as resource intensive too. You could put it into a wrapper, like a layout or a page on top of the others, should be enough. Otherwise, you can always try to see if portal-vue is relevant in your case (this is basically this Teleport documentation page from Vue3). Commented Apr 21, 2022 at 1:28
  • Otherwise, you can also use either a dynamic component or even just a simple v-show. Depends on what you do prefer here. Commented Apr 21, 2022 at 1:29

2 Answers 2

1

Nuxt has build in components like KeepAlive that does not destroy your component / element

caches the inactive component instances without destroying them

Just wrap it

<KeepAlive>
   <component />
</KeepAlive>
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, but how would I append this <component> as a child of the first <section> and then move that same instance to the third <section>?
0

If you are not using layouts, create one as default.vue into /layouts dir.

Then use your WebGL viewer in the layout:

<template>
  <div>
    <!-- YourViewer component keeps visible in all pages using this layout -->
    <YourViewer />
    <!-- Every page is loaded inside nuxt tag -->
    <nuxt />
  </div>
</template>

3 Comments

Thanks, but I need the component to be a child of each section. What you're suggesting would simply place it higher up in the DOM hierarchy.
I do not know about your templates or sections but you can define a template into the layout that allows to place your viewer where you want. If this solution is not valid for your case, you can use the keep-alive attr in the <nuxt> component. Then you can define how many components must be destroyed every route change: nuxtjs.org/docs/features/nuxt-components#keep-alive
@Marquizzo as commented here.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.