Vue 3's Paged.js does not respond to requests for page breaks

Currently, I'm working on implementing page breaks in Vue.js 3. Despite my efforts and utilization of the specified CSS code, I am facing challenges with the ".page-break" class parameter. While I can successfully modify other elements like titlePage for alignment adjustments, the execution of the page break feature remains elusive. Below are all the methods I've tried so far, without any external CSS imports except for the Vue-Showdown plugin that converts markdown to HTML.

Unfortunately, none of the attempted page break solutions showcased below have yielded positive results, leaving me perplexed as to why they are not functioning correctly.

*Please note that this functionality works perfectly fine if directly invoking a print function without involving PagedJS.

The specific requirement necessitates leveraging PagedJS to generate paginated content for updating a Table of Contents (TOC) with corresponding page numbers, which will be subsequently printed.

I have exhausted numerous attempts to troubleshoot the issue but to no avail, resulting in considerable frustration over the lack of success.

I have experimented with different styles and approaches to facilitate page breaks; however, the content does not seem to segment accordingly based on the provided specifications.

Answer №1

Utilizing Vue.js Variables within the DOM

If you're using Vue.js, you have the ability to display variable values enclosed within {{ and }} symbols. Additionally, if you wish to display HTML code alongside, make use of the v-html attribute.

You can also designate an existing DOM element as a reactive variable. By referring to my demonstration, observe how the copyableElement variable operates, allowing the transfer of content from the first div to the fourth one.

const { createApp, ref, reactive } = Vue;

const app = createApp({
  setup() {
    const titleContent = ref('My Title Content <br>and <strong>can\'t use</strong> HTML elements between {{ and }}');
    const restOfContent = reactive({
      innerHTML: `<strong>My</strong><br>HTML Content`
    });
    
    const copyableElement = ref(null);

    return {
      titleContent,
      restOfContent,
      copyableElement,
    };
  }
}).mount('#app');
div {
  margin: 10px 0;
}
<script src="https://unpkg.com/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="fc8a8999bccfd2cfd2c8">[email protected]</a>/dist/vue.global.prod.js"></script>

<div id="app">
  <div ref="copyableElement">Example Text What Can Copy<br>To Another Element</div>

  <div class="title-page">titleContent text: {{ titleContent }}</div>
  <div class="content-page" v-html="restOfContent.innerHTML"></div>
  <div class="content-page" v-html="copyableElement?.innerHTML ?? ''"></div>
</div>

Guidance on Applying Paged.js

The .pagedjs_pages represents the CSS class for styling the complete document. Within this structure, you have access to the .pagedjs_page class for individual page styling. To incorporate custom CSS stylings to content within these pages, consider adding your designated class such as .myPage to the relevant divs up for pagination.

Upon assigning the .myPage class as per necessity, Paged.js automatically identifies it and allocates the corresponding .pagedjs_page classes.

⚠️ Cautious Reminder
page-break-before, page-break-after, page-break-inside tend to be outdated

const { createApp, ref } = Vue;

const app = createApp({
  setup() {
    const pages = ref([]);

    // Generating content for pages
    function generateContent() {
      // Demonstrative simulated content
      const content = [
        "<h1>Page 1</h1><p>This is content for page 1.</p>",
        "<h1>Page 2</h1><p>This is content for page 2.</p>",
        "<h1>Page 3</h1><p>This is content for page 3.</p>"
      ];
      pages.value = content;
    }
    generateContent();

    return {
      pages,
    };
  }
});

app.mount('#app');
@page {
  size: A5;
  margin: 20mm;
  @bottom-right-corner {
    vertical-align: center;
    text-align: center;
    background: #fafafa;
    color: purple;
    content: "P. " counter(page);
  }
}

.pagedjs_page {
  border: 1px solid black;
  background-color: white;
}

.myPage {
  break-after: page;
}
<script src="https://unpkg.com/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="ec9a9989acdfc2dfc2d8">[email protected]</a>/dist/vue.global.prod.js"></script>
<script src="https://unpkg.com/pagedjs/dist/paged.polyfill.js"></script>

<div id="app">
  <div class="myPage" v-for="(pageContent, index) in pages" :key="index">
    <div v-html="pageContent"></div>
  </div>
</div>

Illustration Featuring Entirely HTML DOM

const { createApp, ref, reactive } = Vue;

const app = createApp({
  setup() {
    const content = ref('');
    
    const titleContent = ref('My Title Content');
    const restOfContent = reactive({
      innerHTML: `<strong>My</strong><br>HTML Content`
    });

    // Generating content
    function generateContent() {
      // Simulated content showcased for explanation
      content.value = `<html>
        <head>
          <title>Print Markdown</title>
          <style>
            /* shifted to component's style */
          </style>
        </head>
        <body>
          <div class="title-page">${titleContent.value}</div>
          <div class="content-page">${restOfContent.innerHTML}</div>
          <div class="footer"></div>
        </body>
        </html>
      `;
    }
    generateContent();

    return {
      content,
    };
  }
});

app.mount('#app');
/* refined layout */

.pagedjs_page {
  border: 1px solid black;
  background-color: white;
}

/* original settings */

@page {
  size: A5; /* revised from A4 */
  margin: 20mm;
  @bottom-right-corner {
    vertical-align: center;
    text-align: center;
    background: #fafafa;
    color: purple;
    content: "P. " counter(page);
  }
}

h1 {
  break-before: page;
  page-break-before: always;
}

.pagedjs_page {
  break-before: page;
  page-break-before: always;
}

@media print {
  h1, h2 {
    break-before: page;
    page-break-before: always;
  }
  .page-break {
    break-before: page;
    page-break-before: always;
  }
}

@media screen {
  h1, h2 {
    break-before: page;
    page-break-before: always;

  }
  .page-break {
    break-before: page;
    page-break-before: always;
  }
}

table, figure {
  page-break-inside: avoid; /* Preventing breaks across pages for these elements */
} 

.title-page {
  break-after: always;
  page-break-before: always;
  text-align: center;
  padding-top: 60mm;
}

.page-break {
  break-before: page;
  page-break-before: always;
}

.content-page {
  padding: 15mm 20mm;
}

img {
  max-width: 100%;
  height: auto;
  display: block;
  margin: 10mm auto;
} 
<script src="https://unpkg.com/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="1563607055263b263b21">[email protected]</a>/dist/vue.global.prod.js"></script>
<script src="https://unpkg.com/pagedjs/dist/paged.polyfill.js"></script>

<div id="app">
  <div v-html="content"></div>
</div>

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

Unable to retrieve the store's vuex state

Below is the main file path /main.js import Vue from 'vue'; import App from './App.vue'; import vuetify from './plugins/vuetify'; import router from './router'; import store from './store/index.js'; Vue.c ...

Error: Unable to locate the module: Vue-Picture-BD-Marker

After successfully building my Vue project on my personal MacBook and running npm build without any issues, I encountered a problem when trying to deploy it on my CentOS server using Jenkins. The build failed with the following log: ERROR in ./node_modules ...

Place a div at the bottom of a flexbox while adding some padding around it

Here's what I'm dealing with: .flex-container { display: flex; justify-content: center; padding: 5%; position: relative; } .box1 { position: absolute; bottom: 0; width: 100%; height: 100%; } <div class="flex-container"> ...

The readyState of Ajax is consistently anything but 4

I have encountered an issue with my JavaScript code. I am running these codes in order to display data based on user input. Despite there being no error connection and the connection happening properly, whenever I enter a name it always goes into the else ...

Troubleshooting Autocomplete User Interface Problems

I am currently working on a website user interface and I have encountered an issue specifically in IE7. When searching for a company, the display is not showing up correctly, as demonstrated in the image below. This problem only occurs in IE7, it works fi ...

Deleting a tag from a Flask document

Styling my form has been a challenge with Flask, particularly in regards to the picture field. I'm struggling to remove the "No file chosen" text and style the upload button using CSS, despite incorporating Bootstrap into my file. When hovering over ...

Superior method to ensure the child element's border overlaps with that of the parent

I am currently working on a project that requires a unique CSS effect: Let me explain exactly what I am trying to achieve: The main element (referred to as the title) has padding and a 2px bottom border. Inside this, there is a child element (known as ti ...

Link the Sass variable to Vue props

When working on creating reusable components in Vue.js, I often utilize Sass variables for maintaining consistency in colors, sizes, and other styles. However, I recently encountered an issue with passing Sass variables using props in Vue.js. If I directly ...

The background image is failing to display, although other styles for the class or element are visible

Why won't the background image display, even though I have verified that the image path is correct and changing other properties like color or background color works just fine? Here is my CSS code snippet: .container { background-imag ...

When is the best time to utilize v-layout within Vuetify 3?

I'm confused about the purpose and usage of the v-layout component in Vuetify 3. When looking at the documentation for the app-bar component, I noticed an example utilizing v-layout (GitHub code), but its impact is unclear: by removing the v-layout t ...

What is the best way to prompt users to submit comments with a popup textarea box?

Within my project, I have incorporated a dropdown list: <div class="dropdown"> <button class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown">Select subject <span class="caret"></span> </but ...

Show spinner until the web page finishes loading completely

Could anyone guide me on how to display Ring.html for a brief moment until About.html finishes loading completely? I need the Ring.html page to vanish once About.html is fully loaded. As a beginner in web development, I would greatly appreciate your assist ...

Require an additional button to dynamically load more content and shift all existing elements further down the page

I am looking to implement a "load more" button for an Instagram feed on my website. My current approach involves increasing the height of a specific section while moving the rest of the page down. This is what I have tried: <script> $(document.ready ...

How does Vue.js guarantee that the DOM rendering is finished after a data change when using nextTick?

On the Vue.js documentation page about async update queues, it mentions using Vue.nextTick(callback) to perform actions after rendering is completed. However, there have been instances where this method did not work as expected, leading users to resort to ...

Vue randomly sets the prototype of props in its definition

When the same code with the identical data structure is passed to the prop, it randomly sets the prop as an array or an object. The following is the code fragment: const props = defineProps({ all: { type: Array, default: [], } }) ...

Navigate quickly to different sections using jump links and adjust the positioning with the style attribute, such as "padding-top

My website incorporates Jump Links to navigate between page elements as part of an interactive User Guide. Everything functions properly on Firefox, IE, and Edge, but Chrome and Opera seem to disregard the 'padding'. Due to a fixed menu bar on t ...

The jQuery pop-up fails to activate on the initial click

I have multiple "Buy Now" buttons for different products. If the button is labeled as "sold-out," it should not do anything, but if it's available, it should trigger a jQuery Magnific Popup. Currently, the popup only opens after the second click becau ...

Hovering over the Laravel Breeze dropdown will activate a dropdown feature

Recently, I've been working on a project with Laravel Breeze and have been utilizing some default components. The dropdown component used in the navigation bar caught my attention. By default, it requires a click for the menu to drop down below. Howev ...

Experimenting with Vue.js filters and QA testing techniques

Upon creating a sample project using vue-cli with the command vue init webpack my-test3, I decided to include both e2e and unit tests. Question 1: Following the documentation for template filters, I attempted to add a new filter in main.js: import Vue fro ...

Ways to select the initial 10 rows, final 3 rows, and middle 2 rows using Javascript

As a newcomer to Javascript, I have a couple of questions: 1) How can I retrieve the first 10 rows, the last 3 rows, and the 2 rows in the center using the code var firstTable = $('#aaa table').eq(0); 2) Is there a way to create and assign new ...