vue 实现电脑打印功能 -- 实际使用问题(数据内容清空)

前言

  • 在实际开发中,我们经常有打印功能,我们只需要借助插件vue-print-nb 封装一层就可以实现了。

  • 这个功能我们只需要分页获取数据,枚举处理数据,用原生标签构建表格,传值调用电脑打印。

  • 因为打印组件是识别不了第三方库,所以要写原生标签和原生样式。注意

  • 如果是黑白打印就没事,彩色打印要给每一列或者每一个输入地方加上一个字体颜色为黑色,不加的话,彩印打出来的字体颜色不是黑色(有输入框输入的值时候)

注意:会发现会出现一个bug,下一次打印内容还是上一次的,刷新一次就可以重置数据。那我们就可以通过路由的静默刷新解决。如果有状态要保持就用浏览器存储。

BUG解决

在src/App.vue下复制这段代码,可以直接复制(没有其他操作的话可以直接复制),触发方法在下面的实现过程中打印预览有代码注释。

<template>
  <div id="app">
    <router-view v-if="isRouterAlive" />
  </div>
</template>

<script>
export default {
  name: "App",
  provide() {
    return {
      reload: this.reload,
    };
  },
  data() {
    return {
      isRouterAlive: true,
    };
  },
  methods: {
    reload() {
      this.isRouterAlive = false;
      this.$nextTick(() => {
        this.isRouterAlive = true;
      });
    },
  },
};
</script>

实现过程

1.npm下包 区分vue2和vue3版本

vue2

npm install vue-print-nb --save

vue3

npm install vue3-print-nb --save

2.在main.js中引入挂载vue-print-nb包

// 打印组件
import Print from 'vue-print-nb'

// 挂载全局组件
Vue.use(Print)

3..在全局组件components中新建print文件夹新建index.vue 代码如下

打印预览

<template>
  <el-dialog
    class="bill-pring"
    :title="title"
    :visible.sync="dialogVisible"
    :before-close="closeDialog"
    :close-on-click-modal="false"
    :append-to-body="true"
    top="2vh"
    width="70%"
  >
    <div id="printBill">
      <slot></slot>
    </div>
    <div slot="footer" class="footer">
      <el-button size="small" @click="closeDialog">取 消</el-button>
      <el-button size="small" type="primary" v-print="printBill"
        >打 印</el-button
      >
    </div>
  </el-dialog>
</template>
<script>
export default {
  name: "printinde",
  //vue-router 静默刷新。
  inject: ["reload"],
  props: {
    // 显示隐藏
    dialogVisible: {
      type: Boolean,
      required: false,
    },
    // 标题
    title: {
      type: String,
      default: "数据打印",
    },
  },
  data() {
    // data是作用域问题访问不到methods中方法
    // 申明一个that取代this访问methods方法
    let that = this;
    return {
      addressList: [],
      printBill: {
        id: "printBill",
        popTitle: this.title, // 打印配置页上方标题
        extraHead: "", //最上方的头部文字,附加在head标签上的额外标签,使用逗号分隔
        preview: "", // 是否启动预览模式,默认是false(开启预览模式,可以先预览后打印)
        previewTitle: "", // 打印预览的标题(开启预览模式后出现),
        previewPrintBtnLabel: "", // 打印预览的标题的下方按钮文本,点击可进入打印(开启预览模式后出现)
        zIndex: "", // 预览的窗口的z-index,默认是 20002(此值要高一些,这涉及到预览模式是否显示在最上面)
        clickMounted() {},
        previewBeforeOpenCallback() {}, //预览窗口打开之前的callback(开启预览模式调用)
        previewOpenCallback() {}, // 预览窗口打开之后的callback(开启预览模式调用)
        // 开启打印前的回调事件
        beforeOpenCallback() {
          console.log("打印前");
        },
        // 调用打印之后的回调事件
        openCallback() {
          console.log("打印完了");
          // 调用下面的取消关闭方法
          that.closeDialog();
        },
        //关闭打印的回调事件(无法确定点击的是确认还是取消)
        closeCallback() {
          //打印关闭之前调用静默刷新方法,解决上一次打印内容在下一次打印出现
          that.reload();
        },
      },
    };
  },
  created() {},
  methods: {
    // 关闭弹窗
    closeDialog() {
      this.$emit("update:dialogVisible", false);
    },
    async getAddressList() {
      this.addressList = await this.$request("getAddressList");
    },
  },
  watch: {},
};
</script>
<style lang="scss" scoped>
::v-deep .el-dialog__body {
  padding: 20px;
}
</style>

4.全局组件注册 -- 导入注册组件

// 打印组件
import BillPrint from '@/components/print/index.vue'
export default {
  // install全局引入 vue中一个方法
  // 第1个参数是标签名称,第2个参数是一个选项对象
  install (Vue) {
    // 打印组件
    Vue.component('BillPrint', BillPrint)
  }
}

5.页面布局 -- 记得data中命名打印开关,全局枚举,主页文章有,利用分页查询表格数据,v-for遍历给table标签实现分页打印

打印插件是不认识第三方框架,使用原生table标签

<!-- 打印框 -->
    <billPrint :dialogVisible.sync="printDialog" title="员工数据打印">
      <template>
        <div class="print-flex">
          <!-- <legend>员工数据</legend> -->
          <caption align="top">
            <strong>员工数据</strong>
          </caption>
          <table border="1" cellspacing="0">
            <tr>
              <th style="40px">序号</th>
              <th style="width: 80px">工号</th>
              <th style="width: 80px">姓名</th>
              <th style="width: 80px">性别</th>
              <th style="width: 80px">国籍</th>
              <th style="width: 80px">民族</th>
              <th style="width: 100px">出生日期</th>
              <th style="width: 200px">家庭住址</th>
              <!-- <th style="width: 100px">证件类型</th> -->
              <th style="width: 250px">证件号码</th>
              <th style="width: 150px">电话</th>
              <th style="width: 120px">员工类型</th>
              <th style="width: 120px">学历</th>
            </tr>
            <tr
              v-for="(n, index) in tableData"
              :key="index"
              style="text-align: center"
            >
              <td>
                {{ (pageInfo.pageNo - 1) * pageInfo.pageSize + index + 1 }}
              </td>
              <td>{{ n.number }}</td>
              <td>{{ n.name }}</td>
              <td>{{ n.sex | personnelsex }}</td>
              <td>{{ n.nationalityCode }}</td>
              <td>{{ n.nationCode }}</td>
              <td>{{ n.birthdate | formData("YYYY-MM-DD") }}</td>
              <td>{{ n.homeAddress }}</td>
              <!-- <td>{{ n.papersType | personsNumber }}</td> -->
              <td>{{ n.papersNumber }}</td>
              <td>{{ n.phone }}</td>
              <td>{{ n.employeeType | personmployeeType }}</td>
              <td>{{ n.educationType | personducation }}</td>
            </tr>
          </table>
        </div>
      </template>
    </billPrint>

6.在页面中使用 -- 按钮触发把开关打开

<el-button size="small" type="warning" icon="el-icon-ship" @click="print"
​
   >打印</el-button
​
  >

7.打开开关触发,使用枚举处理数据,主页文章有。

// 打印
    print() {
      this.printDialog = true;
    },

注意:这样用打印一次可能没问题,但是打印多次就会出现下一次打印是上一次打印的内容,最根本解决方法,静默刷新页面。

细节

注意要在data中命名打印开关,数据处理全局枚举主页有,打印插件是不认识第三方框架,使用原生table标签


经过这一趟流程下来相信你也对 vue 实现电脑打印功能 有了初步的深刻印象,但在实际开发中我 们遇到的情况肯定是不一样的,所以我们要理解它的原理,万变不离其宗。加油,打工人!

什么不足的地方请大家指出谢谢 -- 風过无痕

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

-風过无痕

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值