te')); return $arr; } /* 遍历用户所有主题 * @param $uid 用户ID * @param int $page 页数 * @param int $pagesize 每页记录条数 * @param bool $desc 排序方式 TRUE降序 FALSE升序 * @param string $key 返回的数组用那一列的值作为 key * @param array $col 查询哪些列 */ function thread_tid_find_by_uid($uid, $page = 1, $pagesize = 1000, $desc = TRUE, $key = 'tid', $col = array()) { if (empty($uid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('uid' => $uid), array('tid' => $orderby), $page, $pagesize, $key, $col); return $arr; } // 遍历栏目下tid 支持数组 $fid = array(1,2,3) function thread_tid_find_by_fid($fid, $page = 1, $pagesize = 1000, $desc = TRUE) { if (empty($fid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('fid' => $fid), array('tid' => $orderby), $page, $pagesize, 'tid', array('tid', 'verify_date')); return $arr; } function thread_tid_delete($tid) { if (empty($tid)) return FALSE; $r = thread_tid__delete(array('tid' => $tid)); return $r; } function thread_tid_count() { $n = thread_tid__count(); return $n; } // 统计用户主题数 大数量下严谨使用非主键统计 function thread_uid_count($uid) { $n = thread_tid__count(array('uid' => $uid)); return $n; } // 统计栏目主题数 大数量下严谨使用非主键统计 function thread_fid_count($fid) { $n = thread_tid__count(array('fid' => $fid)); return $n; } ?>javascript - How to print a specific element in Vue 3? - Stack Overflow
最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to print a specific element in Vue 3? - Stack Overflow

programmeradmin3浏览0评论

I'm working on a project where I want the functionallity to print a specific element of my page. There is a mixin/plugin called VueHtmlToPaper that does exactly what I want but I have trouble importing it into my Vue 3 CLI project since it was created for VueJS2 and the global API is different. Any help is appreciated.

main.js

import { createApp } from 'vue'

import App from './App.vue'

 createApp(App).mount('#app')

Project structure :

I'm working on a project where I want the functionallity to print a specific element of my page. There is a mixin/plugin called VueHtmlToPaper that does exactly what I want but I have trouble importing it into my Vue 3 CLI project since it was created for VueJS2 and the global API is different. Any help is appreciated.

main.js

import { createApp } from 'vue'

import App from './App.vue'

 createApp(App).mount('#app')

Project structure :

Share Improve this question edited Nov 13, 2020 at 16:59 Boussadjra Brahim 1 asked Nov 13, 2020 at 16:07 PazulayPazulay 2272 gold badges4 silver badges13 bronze badges 7
  • please share how did you use it with vue 2 – Boussadjra Brahim Commented Nov 13, 2020 at 16:08
  • I haven't used it before but this is the documentation of the plugin link In vue 3 you create the vue instance with createApp so you don't have access to Vue.use – Pazulay Commented Nov 13, 2020 at 16:19
  • this plugin is not patible with vue 3, you should look for another plugin or wait until they release new version patible with vue 3 – Boussadjra Brahim Commented Nov 13, 2020 at 16:24
  • but i think that i'm able to provide a code based on their code that works for vue 3, give me some time to try it out – Boussadjra Brahim Commented Nov 13, 2020 at 16:31
  • Thank you so much! That would really help me out. I'm pretty sure all the code is in the src/index.js. I'm very bad at vanilla javascript so I had trouble understanding that code. – Pazulay Commented Nov 13, 2020 at 16:35
 |  Show 2 more ments

3 Answers 3

Reset to default 9

Since this plugin is not patible with vue 3, we could do our plugin based on vue-html-to-paper plugin :

  1. create a folder called plugins in project root then inside it add VueHtmlToPaper.js file with the following content :

function addStyles(win, styles) {
    styles.forEach((style) => {
      let link = win.document.createElement("link");
      link.setAttribute("rel", "stylesheet");
      link.setAttribute("type", "text/css");
      link.setAttribute("href", style);
      win.document.getElementsByTagName("head")[0].appendChild(link);
    });
  }
  
  const VueHtmlToPaper = {
    install(app, options = {}) {
      app.config.globalProperties.$htmlToPaper = (
        el,
        localOptions,
        cb = () => true
      ) => {
        let defaultName = "_blank",
          defaultSpecs = ["fullscreen=yes", "titlebar=yes", "scrollbars=yes"],
          defaultReplace = true,
          defaultStyles = [];
        let {
          name = defaultName,
          specs = defaultSpecs,
          replace = defaultReplace,
          styles = defaultStyles
        } = options;
  
        // If has localOptions
        // TODO: improve logic
        if (!!localOptions) {
          if (localOptions.name) name = localOptions.name;
          if (localOptions.specs) specs = localOptions.specs;
          if (localOptions.replace) replace = localOptions.replace;
          if (localOptions.styles) styles = localOptions.styles;
        }
  
        specs = !!specs.length ? specs.join(",") : "";
  
        const element = window.document.getElementById(el);
  
        if (!element) {
          alert(`Element to print #${el} not found!`);
          return;
        }
  
        const url = "";
        const win = window.open(url, name, specs, replace);
  
        win.document.write(`
          <html>
            <head>
              <title>${window.document.title}</title>
            </head>
            <body>
              ${element.innerHTML}
            </body>
          </html>
        `);
  
        addStyles(win, styles);
  
        setTimeout(() => {
          win.document.close();
          win.focus();
          win.print();
          win.close();
          cb();
        }, 1000);
  
        return true;
      };
    }
  };
  
  export default VueHtmlToPaper;
  

I just copied/pasted this code and I replaced Vue by app, then import it in main.js :

import { createApp } from 'vue'

import App from './App.vue'

 import  VueHtmlToPaper from './plugins/VueHtmlToPaper'

let app=createApp(App);

 app.use(VueHtmlToPaper)

 app.mount('#app')

then use it in any ponent like :

<template>
<div class="home">
    <img alt="Vue logo" src="../assets/logo.png">

    <!-- SOURCE -->
    <div id="printMe">
        <h1>Print me!</h1>
    </div>
    <!-- OUTPUT -->
    <button @click="print">print</button>

</div>
</template>

<script lang="ts">
import {
    defineComponent
} from 'vue';
import HelloWorld from '@/ponents/HelloWorld.vue'; /

export default defineComponent({
    name: 'Home',
    ponents: {
        HelloWorld,
    },
    methods: {
        print() {
            this.$htmlToPaper('printMe')
        }
    },
    mounted() {

    }
});
</script>

LIVE DEMO

To prevent additional window, I replace window with the iframe inside VueHtmlToPaper.js

function addStyles(win, styles) {
    styles.forEach((style) => {
      let link = win.document.createElement("link");
      link.setAttribute("rel", "stylesheet");
      link.setAttribute("type", "text/css");
      link.setAttribute("href", style);
      win.document.getElementsByTagName("head")[0].appendChild(link);
    });
  }
  
  const VueHtmlToPaper = {
    install(app, options = {}) {
      app.config.globalProperties.$htmlToPaper = (
        el,
        localOptions,
        cb = () => true
      ) => {
        let 
          defaultStyles = [];
        let {
          styles = defaultStyles
        } = options;
  
        // If has localOptions
        // TODO: improve logic
        if (localOptions) {
          if (localOptions.styles) styles = localOptions.styles;
        }
  
        const element = window.document.getElementById(el);
  
        if (!element) {
          alert(`Element to print #${el} not found!`);
          return;
        }
  
        var ifprint = document.createElement("iframe");
        document.body.appendChild(ifprint);
        ifprint.setAttribute("style","height:0;width:0;");

        const win = ifprint.contentWindow;
  
        win.document.write(`
          <html>
            <head>
              <title>${window.document.title}</title>
            </head>
            <body>
              ${element.innerHTML}
            </body>
          </html>
        `);
  
        addStyles(win, styles);
        
  
        setTimeout(() => {
          win.document.close();
          win.focus();
          win.print();
          win.close();
          document.body.removeChild(ifprint);
          cb();
        }, 1);
  
        return true;
      };
    }
  };
  
  export default VueHtmlToPaper;

I have developed a Vue 3 ponent vue-to-print for printing specified content. Perhaps you can give it a try.

  1. First, install it with npm install vue-to-print --save.
  2. Assume this is the content you want to print:
    <div ref="ponentRef">
      some printed content
    </div>
    
  3. Call the handlePrint function returned by useVueToPrint to print the content:
    import { useVueToPrint } from "vue-to-print";
    
    const { handlePrint } = useVueToPrint({
      content: () => ponentRef.value,
      documentTitle: "AwesomeFileName",
    });
    
    handlePrint();
    
发布评论

评论列表(0)

  1. 暂无评论