Tips for conditionally mounting a child vue js component after the parent has fully mounted - I am utilizing $refs

Utilizing Laravel 8 and InertiaJS (Vue js)

In order to generate PDF, I am using the html2pdf.js library and have created a component specifically for this purpose: ExportPdf.vue

Below is the code for the ExportPdf.vue component :

<template>
  <div>
      <button class="px-6 py-3 rounded bg-gray-600 hover:bg-gray-900 text-white text-sm font-bold whitespace-no-wrap" 
        @click="exportToPDF">Export to PDF
    </button>
  </div>
</template>

<script>
import html2pdf from 'html2pdf.js'

export default {
props:{
    area: HTMLDivElement,
    name : String,
    orientation : {
      type: String,
      default(){
        return 'landscape'
      }
    }
},
methods:{
     exportToPDF () {
          html2pdf(this.area, {
            margin: [1.5, 1],
            filename: this.name + '.pdf',
            image: { type: 'jpeg', quality: 0.98 },
            html2canvas: {scale: 2},
            jsPDF: { unit: 'cm', format: 'a4', orientation: this.orientation ,  floatPrecision: 16 }
        })
    }
}
}
</script>

To utilize this component, simply include it within any other component where you want to extract content into a PDF file like so:

<export-pdf  name="file name" :area="$refs.content" />

Make sure to reference the specific Div you wish to extract using ref, as shown below:

<div ref="content">
 <!-- Content to Extract into PDF -->
</div>

The issue arises when switching between components, causing the component to no longer function properly unless the page is refreshed.

After further investigation, I discovered that the prop (this.area which receives the $refs.content from the parent) inside the ExportPdf component was undefined. This could be due to the component being mounted before the $refs.content is initialized in the parent component.

A temporary solution I found was to add a conditional check (v-if) to the ExportPdf component in each parent component, setting a boolean value to true in the parent component's mounted method. This resolves the issue of the prop being undefined without requiring a page refresh. However, this approach can be cumbersome to implement in every parent component.

For example: Parent template :

<export-pdf v-if="isMounted" name="Liste des consommables des équipements" :area="$refs.content" />
data(){
    return {
      isMounted : false,
    }
 }, 
mounted(){
        this.isMounted = true
}

Are there any suggestions on how to improve this process?

Thank you.

Answer â„–1

Due to the child component being mounted before the parent.

  • $refs is not reactive, so it is best to refrain from accessing $refs within templates or computed properties.

Potential Fix 1:

    <div ref="content">
     <!-- Content to be Exported into PDF -->
    </div>
    <export-pdf  name="List of Equipment Consumables" :area="refElement" />
<script>
export default {
    data(){
        return {
          refElement: {},
        }
     }, 
    mounted(){
        this.refElement = this.$refs.content
    }
}
</script>

Potential Fix 2:

For the parent component:

 <div ref="content">
 <!-- Content to be Exported into PDF -->
 </div>
 <export-pdf  name="List of Equipment Consumables" areaRefName="content" />

For the children components:

props:{
    areaRefName: String,
    name : String,
    orientation : {
      type: String,
      default(){
        return 'landscape'
      }
    }
},
methods:{
     exportToPDF () {
          let element = this.$parent.$refs[this.areaRefName]
          html2pdf(element , {
            margin: [1.5, 1],
            filename: this.name + '.pdf',
            image: { type: 'jpeg', quality: 0.98 },
            html2canvas: {scale: 2},
            jsPDF: { unit: 'cm', format: 'a4', orientation: this.orientation ,  floatPrecision: 16 }
        })
    }
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Tips for transferring contact information from a webpage to an Android or iPhone using an HTML button and integrating JavaScript or PHP

My current project involves adding a feature to a website that allows users to save contact details from the site to their phone (Android or iPhone) with the click of an HTML button. Here's what I have done so far <!DOCTYPE html> <html lang= ...

Obtaining documents through Mojolicious

Just a quick inquiry - I have successfully generated a .doc file using my mojolicious app with the help of the CPAN module MsOffice::Word::HTML::Writer. Now, the challenge I'm facing is figuring out how to make the browser initiate the download proces ...

There seems to be a problem with the output when trying to display the message "You said ${reply}"

In the following code snippet, vanilla.js is being used with ATOM as the text editor and running on nodejs via terminal: 'use strict'; const Readline = require('readline'); const rl = Readline.createInterface({ input:process.stdin, ...

Generating a dynamic model name within a Vue v-for loop

While working on my application using Vue and Laravel, I encountered an issue within a v-for loop. I needed to bind error.id in the loop to the v-model name of the elements. Here is the relevant code snippet: <tbody class="bodycol"> <tr v-for=" ...

What is causing this code to run immediately upon the addition of Promise logic?

The coding scenario written below was supposed to have two 4-second delays. However, when the code is run, it executes immediately. It seems that there might be a lack of understanding on my part regarding some basic concept, or perhaps there's a hidd ...

Changing the data type of a column in an Excel file from XLSX to

I am currently working with the XLSX npm package and attempting to download a sample Excel file, add some data to it, and then upload it back. The fields in the file include MOBILE NUMBER, DATE, TIME, and NAME. When I upload the file, the values for the DA ...

Is there a replacement for findIndex in Internet Explorer?

I am currently working on a code snippet for smooth navigation scroll to different sections. var lastId; var topMenu = $(".community-nav"); var topMenuHeight = topMenu.outerHeight() - 19; if(window.matchMedia("(max-width: 768px)").matches) ...

Retrieve the country code of an IP address using getJSON

I am currently facing an unusual issue. My goal is to extract the country code (like US for United States) from an IP address using free APIs. After some research, I came across ipify for retrieving the IP address (which works fine), and then attempted to ...

How to change a time in HH:mm format to a Date object using JavaScript

I am facing a challenge with converting two time strings to Date objects and subtracting their values. The times I have are: 14:10 and 19:02 To perform the subtraction, I attempted to parse them using the following code: var res = date1 - date2; Howev ...

Show webpage on Next.js server side

With Next.JS 14, I am aiming to display a page for clients who request access via a browser. If the request comes from an alternate source, I would like to redirect them to another website. While I have successfully implemented the redirect function in t ...

Unlocking keys of JavaScript class prior to class initialization

My constructor was becoming too large and difficult to maintain, so I came up with a solution to start refactoring it. However, even this new approach seemed bulky and prone to errors. constructor(data: Partial<BusinessConfiguration>) { if(!d ...

Tips for accessing the parent window from child windows after navigating to a new link

Starting from a main window, I open a pop-up window (the child) with the following code: onclick=window.open('child_windows.html','popup','width=600,height=300') The child window has a cool feature - it can update the parent ...

Compare the array against the keys to filter the object

Currently, I have an object with keys that have multiple values. Additionally, there is an array with a simple key check as follows: ["random", "three"]. My goal is to retrieve the mainData, but only with the object and the data that match the keys in th ...

Difficulty validating RSA signature on the server end originating from client-side Javascript

Utilizing the forge library on the client side for creating signatures looks like this: //Client Side var md = forge.md.sha256.create(); md.update(encryptedVote, 'utf8'); var pss = forge.pss.create({ md: forge ...

A guide on how to apply filtering to an array in Vue using another array

Currently, I have two arrays of objects: one is named submodules and it contains a children array within it. My goal is to filter these children arrays based on another array called accessed. new Vue({ data: { submodules: [ { type: ...

Angular is capable of transferring data from a form using the [POST] method

I need assistance with: var body = {username:"ali", password:"p"}; this.http.post('http://localhost:27017/user/auth', body).subscribe(data => {console.log(data);}); Is there a way to populate the 'body' variable using form dat ...

Animate jQuery Images - Transform and smoothly reveal element

Hey there! I've managed to create a color switcher that gives a sneak peek of different themes. Currently, it simply switches the image source and loads the new image. But I'm curious if it's possible to add a fadeIn effect to enhance the t ...

Encountering a "Module Not Found" error during a Docker build for a Vue

I have been attempting to create a docker image for a vue app, but I consistently encounter the following error: Module not found: Error: Can't resolve './src/main.js' in '/app' I am utilizing a multi-stage dockerfile for this p ...

Storing user input as an object key in typescript: A comprehensive guide

When delving into Firestore for the first time, I quickly learned that the recommended modeling approach looks something like this: check out the model here members { id: xyz { name: Jones; ...

What is the code to hide text once an HTML5 video has completed loading?

Is there a way to display "Video Loading" with a 75% opaque background over an HTML5 video, and then have both the text and background disappear once the video has finished loading? If so, how can I achieve this? Thank you for your time and effort! You ca ...