Newer
Older
smart-metering-front / src / components / QrDialog / index.vue
Stephanie on 27 Dec 2022 4 KB feat<views>: 新增二维码弹窗
<!-- 二维码弹窗 -->
<script lang="ts" setup name="QrDialog">
import QRCode from 'qrcode'
import html2canvas from 'html2canvas'
// 弹窗显示状态
const dialogFormVisible = ref(false)
const loading = ref(false)
// 弹窗初始化
const qrCanvas = ref()
const title = ref('')
const codeStr = ref('')
const imageUrl = ref('')
function generateQrCode() {
  var canvas = document.getElementById('canvas')
  loading.value = true
  // 调用函数去生成二维码,参数依次为:二维码的容器、要生成的内容、回调函数
  console.log(codeStr.value)
  // QRCode.toCanvas(canvas, codeStr.value, { width: 200, height: 200 }, (error: any, canvas) => {
  //   if (error) {
  //     console.error(error)
  //   }
  //   else {
  //     loading.value = false
  //   }
  // })
  QRCode.toDataURL(codeStr.value, (error: any, url: string) => {
    if (error) {
      console.error(error)
    }
    else {
      imageUrl.value = url
      loading.value = false
    }
  })
}
// 打印
const printObj = ref({
  id: 'canvasContainer', // 需要打印元素的id
  popTitle: title.value, // 打印配置页上方的标题
  extraHead: '', // 最上方的头部文字,附加在head标签上的额外标签,使用逗号分割
  preview: false, // 是否启动预览模式,默认是false
  previewBeforeOpenCallback() { console.log('正在加载预览窗口!') }, // 预览窗口打开之前的callback
  previewOpenCallback() { console.log('已经加载完预览窗口,预览打开了!') }, // 预览窗口打开时的callback
  beforeOpenCallback() { console.log('开始打印之前!') }, // 开始打印之前的callback
  openCallback() { console.log('执行打印了!') }, // 调用打印时的callback
  closeCallback() { console.log('关闭了打印工具!') }, // 关闭打印的callback(无法区分确认or取消)
  clickMounted() { console.log('点击v-print绑定的按钮了!') },
  standard: '',
  extarCss: '',
})
function print() {
// TODO: 打印
}
// 图片下载
const canvasContainer = ref()
function download() { // 等待loading,可不要,直接去掉
  nextTick(() => {
    html2canvas(canvasContainer.value).then((res) => {
      const imgUrl = res.toDataURL('image/png')
      const aLink = document.createElement('a')
      aLink.id = 'qrcodeimg'
      aLink.href = imgUrl
      aLink.download = `${title.value}.png`	// 导出文件名
      document.body.appendChild(aLink)
      // 模拟a标签点击事件
      aLink.click()
      // 事件已经执行,删除本次操作创建的a标签对象
      document.body.removeChild(aLink)
    })
  })
}
/**
 * 初始化二维码弹窗
 * @param code 二维码内容
 * @param name 二维码标题
 */
const initDialog = (code: string, name?: string) => {
  dialogFormVisible.value = true
  title.value = name || ''
  codeStr.value = code
  generateQrCode()
}

defineExpose({ initDialog })
</script>

<template>
  <el-dialog v-model="dialogFormVisible" title="二维码" width="350px" append-to-body>
    <div id="canvasContainer" ref="canvasContainer" class="canvas-container">
      <div v-if="title">
        {{ title }}
      </div>
      <!-- <canvas id="canvas" ref="qrCanvas" v-loading="loading" /> -->
      <el-image id="canvas" :src="imageUrl" class="canvas" />
    </div>
    <template #footer>
      <div class="dialog-footer">
        <el-button v-print="printObj" type="primary">
          打印
        </el-button>
        <el-button @click="download">
          下载
        </el-button>
      </div>
    </template>
  </el-dialog>
</template>

<style lang="scss" scoped>
.canvas-container {
  width: 100%;
  height: auto;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;

  .canvas {
    width: 200px;
    height: 200px;
  }
}

@media print {
  .canvas-container {
    position: relative;
    text-align: center;
    font-weight: bold;
    font-size: 30px;
    margin-top: 60px;

    .canvas {
      width: 50vw;
      height: 50vw;
      margin-top: 100px;
    }
  }
}

.footer {
  display: flex;
  justify-content: flex-end;
}
</style>