欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

vue實現(xiàn)打印指定組件內(nèi)容的示例詳解

 更新時間:2024年03月11日 09:43:19   作者:不要止步于此  
這篇文章主要和大家分享一下vue中打印指定組件內(nèi)容,多頁打印自動適配紙張大小打印的方案,文中的示例代碼講解詳細,需要的可以參考一下

前言

大家好,最近在做vue項目時使用到了print-js打印指定組件內(nèi)容,并且還得切換紙張大小時做到自動適配布局的需求,其中遇到了一些問題及我的解題思路想給大家分享一下,希望日后能幫助到大家。

背景

大致需求是在頁面中提供一個多選框組,可以從中選擇打印哪些內(nèi)容,每個勾選項打印格式都是一樣的,不同的是每個勾選項獨占一頁,且響應(yīng)式適配紙張大小,大致效果如下圖所示:

了解需求后,我們開始做開發(fā)準(zhǔn)備工作!

引入print-js,并封裝打印函數(shù)

npm install print-js@1.3.1

usePrint.js

import printJS from 'print-js'

export const usePrint = () => {
  printJS({
    // 需要打印區(qū)域設(shè)置的Id
    printable: 'print-area',
    // 打印類型
    type: 'html',
    // 默認值為800,我們把把設(shè)置為100%
    maxWidth: '100%', 
    // *代表應(yīng)用所有樣式,默認值為null,如果不設(shè)置,打印窗口則會忽略所有樣式
    targetStyles: ['*'],
  });

上面主要注意點是注意點是修改maxWidth的默認值及設(shè)置targetStyles應(yīng)用組件所寫的樣式。想要了解更多可參考:print-js文檔

封裝打印選擇器及打印內(nèi)容組件

引入插件后,我們先把打印的組件結(jié)構(gòu)先寫好,下面先把打印內(nèi)容選擇器結(jié)構(gòu)寫好

PrintSelector.vue

<template>
  <div>
    <!-- 這里是我們封裝的打印組件 -->
    <PrintArea :data="printData" />
    <el-checkbox :value="checkAll" @change="onCheckAllChange">全選</el-checkbox>
    <div style="margin: 15px 0;"></div>
    <el-checkbox-group v-model="checkedItems" @change="onCheckedChange">
      <el-checkbox v-for="item in options" :label="item.id" :key="item.id">{{item.label}}</el-checkbox>
    </el-checkbox-group>
    <div style="margin: 15px 0;"></div>
    <el-button @click="onPrint">打印</el-button>
  </div>
</template>

<script>
import { usePrint } from './hooks/usePrint'
import PrintArea from './PrintArea.vue'
export default {
  components: {
    PrintArea
  },
  data() {
    return {
      checkedItems: [],
      options: [
        { id: 1, label: '項目1' },
        { id: 2, label: '項目2' },
        { id: 3, label: '項目3' },
      ]
    }
  },
  computed: {
    checkAll() {
      return this.checkedItems.length === this.options.length;
    },
    printData() {
      return this.options.filter(item => this.checkedItems.includes(item.id))
    }
  },
  methods: {
    onCheckAllChange() {
      if(this.checkAll) {
        this.checkedItems = []
      } else {
        this.checkedItems = this.options.map(item => item.id)
      }
    },
    onCheckedChange(val) {
      this.checkedItems = val
    },
    onPrint() {
      usePrint()
    }
  },
}
</script>

注意,上面我們把需要打印的組件PrintArea引入到了PrintSelector組件中,因為在調(diào)用printJS方法時需要通過id獲取頁面dom元素,所以需要組件的dom元素渲染到頁面中來,但是我們又不希望頁面中顯示打印的內(nèi)容,這里可以通過設(shè)置display: none把元素隱藏起來。但,隱藏后有一個需要注意的點,我們先把PrintArea組件寫出來,后面再進行講解。

PrintArea.vue

<template>
  <div id="print-area" v-show="false">
    <div class="item" v-for="item in data" :key="item.id">
      <div class="head">頭部</div>
      <div class="main">
        <span class="text">{{ item.label }}</span>
      </div>
      <div class="footer">底部</div>
    </div>
  </div>
</template>
<script>
export default {
  props: {
    data: Array
  }
}
</script>

這個組件就是我們需要打印的內(nèi)容,外部勾選需要打印的內(nèi)容后傳入當(dāng)前組件即可,每一個item代表著一頁。我們回到前文提到的設(shè)置display:none時的問題,我們給idprint-area打印內(nèi)容跟標(biāo)簽隱藏了起來,如果這時選擇項目點擊打印后,會發(fā)現(xiàn)打印預(yù)覽窗口為空白?。?!

其實問題就是出現(xiàn)給打印區(qū)域設(shè)置了display:none,所以打印預(yù)覽窗口也把內(nèi)容隱藏了,解決辦法也簡單,就是給打印區(qū)域再套一層div,把v-show="false"設(shè)置在外層div上即可。

<template>
  <div v-show="false">
    <div id="print-area">
      ...省略其中代碼
    </div>
  </div>
</template>

這樣子打印窗口就能正常顯示內(nèi)容了。

我們下面通過一個小例子模擬打印預(yù)覽講解一下這個問題出現(xiàn)的原因:

demo.html

<body>
  <div class="wrapper">
    <!-- 打印區(qū)域 -->
    <div id="print-area" style="display: none;">
      <div class="item">111</div>
      <div class="item">222</div>
    </div>
  </div>
  <!-- 模擬打印預(yù)覽窗口 -->
  <div id="print-window"></div>
  <script>
    window.onload = function() {
      const printArea = document.getElementById('print-area')
      const printWindow = document.getElementById('print-window')
      // 把打印內(nèi)容放入打印預(yù)覽窗口
      printWindow.appendChild(printArea)
    }
  </script>
</body>

上面我們實現(xiàn)了一個簡單的模擬打印流程,在打印區(qū)域的div上設(shè)置了display: none,所以調(diào)用appendChild放入模擬的打印窗口div下時,頁面并沒有內(nèi)容顯示,因為print-area樣式還是設(shè)置為隱藏。所以我們通過在外面增加一層用來設(shè)置隱藏樣式的div。這樣,我們獲取idprint-areadom元素后,當(dāng)前元素上沒有設(shè)置隱藏樣式,所以appendChild放到打印預(yù)覽窗口,就不會隱藏打印的內(nèi)容了!

頁面布局設(shè)計

我們在PrintArea.vue文件中先把樣式補上,看下效果

<style lang="scss" scoped>
#print-area {
  background-color: deeppink;
  .item {
    display: flex;
    flex-direction: column;
    background-color: bisque;
    .head {
      text-align: center;
      line-height: 100px;
      font-weight: bold;
      font-size: 36px;
      background-color: azure;
    }
    .main {
      flex: 1;
      display: flex;
      justify-content: center;
      align-items: center;
    }
    .footer {
      text-align: center;
      line-height: 100px;
      font-weight: bold;
      font-size: 20px;
      background-color: #eee;
    }
  }
}
</style>

我們的需求是根據(jù)每個item進行分頁打印,分頁實現(xiàn)可以直接在.item下設(shè)置page-break-after: always;樣式即可,但是還有一個需求是怎樣能夠讓item響應(yīng)式適應(yīng)紙張大小,占滿整個區(qū)域呢?第一想到的就是height: 100%,但,這樣就得保證每一層父組件的高度為頁面文檔的高度100%。好像不太理想,那設(shè)置每一頁item的高度為100vh呢?下圖可看出也并沒有達到想要的效果:

解決辦法是讓打印區(qū)域脫離文檔流,設(shè)置一個絕對定位

#print-area {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  .item {
    height: 100%;
  }
}

上面我們巧用絕對定位的上下左右距離都為0,使容器能撐滿整個紙張大小,最后給每一頁item繼承100%高度,這樣子布局就能夠適應(yīng)各種紙張大小了,即使切換紙張也能夠達到撐滿整個容器的效果。

總結(jié)

以上我們主要是通過在打印內(nèi)容區(qū)域外設(shè)置v-show="false"來隱藏元素,使打印內(nèi)容不受隱藏影響,并通過一個小demo演示了問題出現(xiàn)的原因;接著我們通過在每個item下設(shè)置page-break-after: always;實現(xiàn)分頁;最后通過絕對定位使容器撐滿整個紙張,以達到切換紙張大小時也能撐滿整個容器的效果。

到此這篇關(guān)于vue實現(xiàn)打印指定組件內(nèi)容的示例詳解的文章就介紹到這了,更多相關(guān)vue打印指定組件內(nèi)容內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • vue 國際化 vue-i18n 雙語言 語言包

    vue 國際化 vue-i18n 雙語言 語言包

    這篇文章主要介紹了vue 國際化 vue-i18n 雙語言 語言包的相關(guān)知識,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下
    2018-06-06
  • 詳解Vue爬坑之vuex初識

    詳解Vue爬坑之vuex初識

    本篇文章主要介紹了詳解Vue爬坑之vuex初識 ,Vue 的狀態(tài)管理工具 Vuex可以解決大型項目中子組件之間傳遞數(shù)據(jù),有興趣的可以了解下
    2017-06-06
  • 使用vue初用antd 用v-model來雙向綁定Form表單問題

    使用vue初用antd 用v-model來雙向綁定Form表單問題

    這篇文章主要介紹了使用vue初用antd 用v-model來雙向綁定Form表單問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • Vue filter介紹及詳細使用

    Vue filter介紹及詳細使用

    這篇文章主要介紹了Vue filter介紹及詳細使用,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2018-04-04
  • vue如何在引入的el-tree前添加圖標(biāo)

    vue如何在引入的el-tree前添加圖標(biāo)

    這篇文章主要介紹了vue如何在引入的el-tree前添加圖標(biāo)問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-03-03
  • 淺談vue中數(shù)據(jù)雙向綁定的實現(xiàn)原理

    淺談vue中數(shù)據(jù)雙向綁定的實現(xiàn)原理

    本篇文章主要介紹了淺談vue中數(shù)據(jù)雙向綁定的實現(xiàn)原理 ,主要使用v-model這個數(shù)據(jù)雙向綁定,有興趣的可以了解一下
    2017-09-09
  • vue中beforeRouteLeave實現(xiàn)頁面回退不刷新的示例代碼

    vue中beforeRouteLeave實現(xiàn)頁面回退不刷新的示例代碼

    這篇文章主要介紹了vue中beforeRouteLeave實現(xiàn)頁面回退不刷新的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-11-11
  • 解決找不到模塊“xxx.vue”或其相應(yīng)的類型聲明問題

    解決找不到模塊“xxx.vue”或其相應(yīng)的類型聲明問題

    這篇文章主要介紹了解決找不到模塊“xxx.vue”或其相應(yīng)的類型聲明問題,具有很好的參考價值,希望對大家有所幫助。
    2022-10-10
  • Vue3?實現(xiàn)驗證碼倒計時功能(刷新保持狀態(tài))

    Vue3?實現(xiàn)驗證碼倒計時功能(刷新保持狀態(tài))

    倒計時的運用場景是需要經(jīng)常用到的,但是根據(jù)業(yè)務(wù)的不同,好比手機驗證碼或者是郵箱驗證碼之類的,即使用戶跳轉(zhuǎn)到其它頁面或者刷新,再次回到登錄也,驗證碼的倒計時也得保持狀態(tài),下面通過本文給大家分享Vue3?驗證碼倒計時功能實現(xiàn),感興趣的朋友一起看看吧
    2022-08-08
  • 利用Nuxt.js做Vuex數(shù)據(jù)持久化

    利用Nuxt.js做Vuex數(shù)據(jù)持久化

    這篇文章主要介紹了利用Nuxt.js做Vuex數(shù)據(jù)持久化問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-10-10

最新評論