vue 项目中 自动生成 二维码

​ 最近在写一个vue项目,要求根据卡号可以自动生成一个二维码,并渲染在指定位置,因为第一次做类似业务,小编在网上找了找,发现了很多,具体起来主要用的就两种:

  1. QRcode
  2. vue-qr

vue-qr比QRcode功能多在可以在中间加logo,而且好像更方便一点,具体的 小编也没试,小编需要的二维码不需要那么 多骚操作,就选择了第一种,至于要写这篇博客的目的是为说一下,运用中遇到的问题及解决方法。

下面先介绍QRcode

vue里安装qrcodejs的npm包

npm install qrcodejs2  -save     -s  // 上线需要的包,打包的时候也会打包

页面引用

import QRCode from 'qrcodejs2'    //   直接在需要用的页面 写就行不需要注意路径问题

二维码展示的盒子

<div class="qrcode" ref="qrCodeUrl" id="qrcode"></div>
methods: {
  creatQrCode() {
    var qrcode = new QRCode(this.$refs.qrCodeUrl, {  // 这里选择器也可以直接写 'qrcode' 用的是id选择器   指示不需要带 # 而已
      text: 'xxxx',  //  生成二维码的 内容
      width: 100,    //  宽   单位 px
      height: 100,   //  高   单位 px 
      // render: 'canvas' // 设置渲染方式(有两种方式 table和canvas,默认是canvas)  
      // background: '#f0f'  
      // foreground: '#ff0'  
      correctLevel: QRCode.CorrectLevel.H   // 二维码容错 级别
     })
  }
},

mounted() {
	   this.creatQrCode(); // 这里会是一个重点,下面会解释
	  }

点击下载二维码:

	// 点击下载app二维码
    downloadAppCodeImg (name) {
      var canvasData = this.$refs.qrcode.getElementsByTagName('canvas')
      var a = document.createElement("a");
      var event = new MouseEvent("click"); // 创建一个单击事件
      a.href = canvasData[0].toDataURL("image/png");;
      a.download = "drcQrcode";
      a.dispatchEvent(event); // 触发a的单击事件
    },

好了,现在就可以了 简单吧? 当然这只是正常的情况,也是官网上介绍的用法,实际上 ,你会遇到一个错误例如:

### vue.runtime.esm.js?2b0e:619 [Vue warn]: Error in v-on handler: "TypeError: Cannot read property 'appendChild' of null"

### found in

### ---> <Home> at src/script/view/home.vue
    ###   <ScrollBar> at src/script/component/scroll_bar.vue
       ###  <Frame> at src/script/component/frame.vue
          ### <App> at src/script/App.vue
            ### <Root>
### warn @ vue.runtime.esm.js?2b0e:619
### logError @ vue.runtime.esm.js?2b0e:1884
### globalHandleError @ vue.runtime.esm.js?2b0e:1879
### handleError @ vue.runtime.esm.js?2b0e:1839
### invokeWithErrorHandling @ vue.runtime.esm.js?2b0e:1862
### invoker @ vue.runtime.esm.js?2b0e:2179
### original._wrapper @ vue.runtime.esm.js?2b0e:6911
### vue.runtime.esm.js?2b0e:1888 TypeError: Cannot read property 'appendChild' of null
    ### at new Drawing (qrcode.js?d044:370)
    ### at new QRCode (qrcode.js?d044:579)
    ### at VueComponent.creatQrCode (home.vue?afc8:120)
    ### at VueComponent.dianJiZhanShi (home.vue?afc8:175)
    ### at invokeWithErrorHandling (vue.runtime.esm.js?2b0e:1854)
    ### at HTMLAnchorElement.invoker (vue.runtime.esm.js?2b0e:2179)
    ### at HTMLAnchorElement.or

看到这个报错是不是第一印象 就是 appendChild 未定义就使用了? 所以我 全局搜索发现 没有这个字段;

接下来 你仔细 看 发现 它是定义在 qrcode.js 里面的 ,我怀疑是引入 js 造成 的 ,所以我又 手动引入一次 把它相对的路径都 写了进来,发现 还是报错; 思考之后又怀疑是生命周期函数的原因 ,因为 created 函数在 data 已有 DOM 还没有创建完成 ,可能会造成它找不到要插入的 DOM元素,所以我再次 把函数调用放在了 mounted

函数里面 ,mounted 生命周期函数中 页面已经渲染完成,DOM 节点也已经创建,应该是没问题的,结果还是报错; 后来我干脆把它放在了methods 一个 函数里面去调用,发现点击的时候还是报同样的错。 我就意识到,是我有一部分没意识到,或者说给忽略了。 我 仔细研究后发现

// this.$nextTick (function () {
        //   this.creatQrCode();   //  这个函数 要在 this.$nextTick 里面调用   才不会报错
        // })

当然 我这里还有点波折 ,我的HTML 元素 也就是上面的

是在 一个遮盖层的 组件只能存在的,点击的时候才显示这个遮盖层,所以在生命周期函数里面,调用这个函数哪怕配合使用 this.$nextTick 调用也是不合适的。

希望 我的经验能帮到你

nextTick 简单介绍

下面是我的代码关于二维码的这一部分

    <!-- 二维码遮盖层 -->
        <div class="homeStyle">
            <van-popup v-model="show">
              <div class="qrcode" ref="qrCodeUrl" id="qrcode"> </div>
            </van-popup>
        </div>
import {
    DropdownItem,
    DropdownMenu,
    Grid,
    GridItem,
    Icon,
    Popup,
    Radio,
    RadioGroup,
    Swipe,
    SwipeItem,
    Tabbar,
    TabbarItem
  } from 'vant'

 import store from 'store'
 import Vue from 'vue'
 import axios from 'axios'
 import QRCode from 'qrcodejs2'
 // 生成二维码函数

      creatQrCode() {
        let cardNo = store.get('__cardNo__')
        log.info(cardNo,'二维码生成')
        var qrcode = new QRCode('qrcode', {
            text: cardNo ,
            width: 150,
            height: 150,
            // background: '#f0f',   // 背景色
            // foreground: '#ff0'    // 前景色
           
        })
        //  log.info(qrcode,'qrcode66666666666666666666666666') 
      },
        
        
        
         dianJiZhanShi () {
            // this.creatQrCode();
            // 点击展示二维码
            this.show = !this.show
            this.$nextTick (function () {
              this.creatQrCode();
            })
      },

下面补充一点知识:

微信长按识别二维码,在 vue 项目中的实现

微信长按识别二维码是 QQ 浏览器的内置功能,该功能的基础一定要使用 img 标签引入图片,其他方式的二维码无法识别。

在 vue 中使用 QrcodeVue 插件

  • demo1 在 template 标签中直接使用
<qrcode-vue :value="codeUrl" :size="size" level="H"></qrcode-vue>

在微信中长按无法识别二维码

正确的做法

使用 qrcode 插件

  • 在 template 标签中是使用 img 标签引入
<template>
  <div>
    <p>长按识别二维码支付</p>
    <div id="code">
      <img class="code" :src="url" alt="">
    </div>
  </div>
</template>
  • 在 methods 方法里面生成二维码图片后加入 img 中即可
methods: {
            QRCode.toDataURL('自定义的内容,可传参')
              .then(url => {
                this.url = url
              })
              .catch(err => {
                console.error(err)
              })
}
Logo

前往低代码交流专区

更多推荐