Vue3 使用qrcode实现 地址生成二维码,带logo

最近有做二维码的需求,于是看了下qrcode,通过画布来绘制二维码,实现如下

1. 先安装qrcode

npm install --save qrcode

2. template

<template>
    <div> 二维码 </div>
    <div class="code">
      <canvas v-if="record.channelCode" id="canvas" ref="canvas"></canvas>
    </div>
</template>

3. js

<script>
  import QRCode from 'qrcode';

  export default {
    name: 'Box',
    props: {
      record: {
        type: Object,
        default: () => ({}),
      },
    },
    data () {
      return {
        qrCodeUrl: process.env.VUE_APP_CODE + '?Code=', //自己的地址,我这边是用了env环境里的
        logoSrc: require('../../../images/logo.jpg'), //自己的图片
      };
    },
    watch: {  //做了个监测,我的父级是不同的单元格,点击事件就可以对应相应的code变化
      record: {
        async handler (val) {
          const { code } = val;
          if (channelCode) {
            try {
              this.spinning = true;
              this.generateQRCode(this.record.code);
            }
            catch (e) {
              console.warn(e);
            }
          }
        },
        deep: true,
        immediate: true,
      },
    },
    mounted () {
      this.generateQRCode(this.record.code);
    },
    methods: {
      async generateQRCode (code) {
        // console.log(code);
        if (!code) return;
        const canvas = this.$refs.canvas;
        if (!canvas) return; // 如果canvas不存在,则不执行后续操作
        const ctx = canvas.getContext('2d');
        const qrSize = 202;
        canvas.width = qrSize;
        canvas.height = qrSize;
        // 下面开始刷新我的二维码,对应父级点击事件
        // 清除canvas上的旧内容
        ctx.clearRect(0, 0, qrSize, qrSize);
        // 生成新的二维码
        await QRCode.toCanvas(canvas, this.qrCodeUrl + code, { width: qrSize });
        // 加载并绘制logo
        const logo = new Image();
        logo.src = this.logoSrc;
        logo.onload = () => {
          const logoSize = qrSize * 0.2;
          const logoX = (qrSize - logoSize) / 2;
          const logoY = (qrSize - logoSize) / 2;
          ctx.drawImage(logo, logoX, logoY, logoSize, logoSize);
        };
      },
    },
  };
</script>

4. css

<style lang="less" scoped>
// #canvas {
.code {
  width: 202px; /* 与二维码生成的宽度一致 */
  height: 202px; /* 与二维码生成的高度一致 */
}
</style>

呈现效果(打码了)

<think>我们被要求使用Vue生成logo二维码。根据引用[1],我们可以使用ngx-qrcode库(尽管它是Angular的,但我们需要寻找Vue的类似库)。实际上,引用中提到了Vue相关的库,但引用[1]是Angular的,引用[2]提到了vue-authenticate等,但没有直接关于二维码的。引用[3]是关于Vue组件的加载,引用[4]是关于图片处理的。因此,我们需要寻找一个适用于Vue二维码生成库,并且支持添加logo。常见的Vue二维码库有`vue-qrcode`,但它可能不支持直接添加logo,所以我们需要结合其他方法。一个常见的做法是使用`qrcode`库生成二维码,然后使用canvas绘制logo。在Vue中,我们可以使用`vue-qrcode`生成二维码,然后使用一个img标签覆盖在二维码上,但这样可能不够灵活。另一种方法是使用`qrcode`库生成logo二维码(在Node.js环境中),但在浏览器中,我们可以使用JavaScript二维码库。我推荐使用`qrcode.vue`(一个Vue组件)结合自定义绘制logo。但是,更简单的方法是使用一个支持logo的库,比如`qrcodejs2`,然后自己添加logo。不过,`qrcodejs2`本身不直接支持logo,我们需要在生成二维码后,用canvas绘制logo。步骤:1.安装一个二维码库,例如`qrcode`(这个库可以在浏览器中使用,并且支持canvas)。2.在Vue组件中,使用canvas生成二维码,然后在canvas上绘制logo。具体步骤:###1.安装qrcode库```bashnpminstallqrcode```###2.在Vue组件中-创建一个canvas元素-使用qrcode库将文本生成二维码到canvas-加载logo图片,并在二维码中心绘制logo注意:由于图片加载是异步的,我们需要确保在二维码绘制完成后再绘制logo,并且要处理图片跨域问题(如果logo来自不同域)。###示例代码```vue<template><div><canvasref="canvas"></canvas></div></template><script>importQRCodefrom&#39;qrcode&#39;exportdefault{props:{text:{type:String,required:true},logoUrl:{type:String,default:&#39;&#39;}},mounted(){this.generateQRCode();},methods:{asyncgenerateQRCode(){constcanvas=this.$refs.canvas;try{//生成二维码到canvasawaitQRCode.toCanvas(canvas,this.text,{width:200,//二维码宽度margin:1//边距});//如果有logo,则绘制logoif(this.logoUrl){constctx=canvas.getContext(&#39;2d&#39;);constlogo=newImage();//处理跨域logo.crossOrigin="Anonymous";logo.src=this.logoUrl;logo.onload=()=>{//设置logo大小(这里设置为二维码的1/5)constlogoSize=canvas.width/5;constx=(canvas.width-logoSize)/2;consty=(canvas.height-logoSize)/2;//绘制白色背景(可选,避免二维码颜色干扰logo)ctx.fillStyle=&#39;white&#39;;ctx.fillRect(x,y,logoSize,logoSize);//绘制logoctx.drawImage(logo,x,y,logoSize,logoSize);};//处理图片加载错误logo.onerror=(err)=>{console.error(&#39;Logo加载失败&#39;,err);//可以尝试添加时间戳重新加载(如果允许)//lettimeStamp=newDate().getTime();//logo.src=`${this.logoUrl}?${timeStamp}`;};}}catch(err){console.error(err);}}}}</script>```###说明-我们使用`qrcode`库的`toCanvas`方法将文本生成二维码到canvas。-然后,我们创建一个Image对象加载logo图片。当图片加载完成后,我们在二维码的中心位置绘制一个白色的矩形(避免二维码的颜色干扰logo的显示),然后在矩形上绘制logo。-注意:如果logo图片来自不同的域,并且服务器不允许跨域,那么设置`crossOrigin`可能会导致错误。在这种情况下,你需要确保图片服务器设置了正确的CORS响应头,或者将图片托管在同域下。###替代方案:使用vue-qrcode组件如果你更倾向于使用一个Vue组件,可以安装`vue-qrcode`,然后通过插槽添加logo。但是,`vue-qrcode`默认不提供logo功能,所以我们可以通过CSS定位将logo放在二维码上。安装:```bashnpminstallvue-qrcode```组件使用:```vue<template><divstyle="position:relative;display:inline-block"><vue-qrcode:value="text":options="{width:200}"></vue-qrcode><imgv-if="logoUrl":src="logoUrl"style="position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:20%;height:auto;"/></div></template><script>importVueQrcodefrom&#39;@chenfengyuan/vue-qrcode&#39;;exportdefault{components:{VueQrcode},props:{text:String,logoUrl:String}}</script>```这种方法更简单,但需要注意的是,如果二维码是黑白的,而logo是透明的,可能会被二维码背景覆盖。因此,可以在logo图片后面加一个白色背景。###结论两种方法都可以实现,第一种方法使用canvas更灵活,可以控制细节;第二种方法简单快捷。根据用户需求,选择合适的方法。§§相关问题§§1.如何解决生成二维码logo图片跨域问题?2.如何调整二维码的容错率?3.在Vue中,除了qrcode库,还有哪些常用的二维码生成库?4.如何将生成的二维码保存为图片?</think>在Vue项目中生成Logo二维码,推荐使用`vue-qrcode`库结合Canvas绘制。以下是详细实现步骤: ### 1. 安装依赖 ```bash npm install @chenfengyuan/vue-qrcode qrcode ``` ### 2. 基础组件实现 ```vue <template> <div class="qr-container"> <vue-qrcode :value="qrText" :options="{ width: 200 }" ref="qrCanvas" tag="canvas" ></vue-qrcode> <img v-if="logoUrl" :src="logoUrl" class="qr-logo"/> </div> </template> <script> import VueQrcode from &#39;@chenfengyuan/vue-qrcode&#39;; export default { components: { VueQrcode }, props: { qrText: String, logoUrl: String } } </script> <style> .qr-container { position: relative; display: inline-block; } .qr-logo { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 20%; /* Logo大小为二维码的20% */ border-radius: 4px; background: white; /* 避免透明Logo二维码干扰 */ padding: 4px; } </style> ``` ### 3. 高级实现(Canvas绘制版) ```vue <template> <canvas ref="canvas" :width="size" :height="size"></canvas> </template> <script> import QRCode from &#39;qrcode&#39;; export default { props: { text: { type: String, required: true }, logo: { type: String, default: &#39;&#39; }, size: { type: Number, default: 200 } }, mounted() { this.generateQR(); }, methods: { async generateQR() { const canvas = this.$refs.canvas; try { // 生成基础二维码 await QRCode.toCanvas(canvas, this.text, { width: this.size, margin: 1, errorCorrectionLevel: &#39;H&#39; // 高容错率 }); // 添加Logo if (this.logo) { const ctx = canvas.getContext(&#39;2d&#39;); const logoSize = this.size / 5; // Logo大小 const logoX = (this.size - logoSize) / 2; const logoY = (this.size - logoSize) / 2; const img = new Image(); img.crossOrigin = "Anonymous"; // 解决跨域问题[^4] img.src = this.logo; img.onload = () => { // 绘制白色背景 ctx.fillStyle = &#39;white&#39;; ctx.fillRect(logoX-2, logoY-2, logoSize+4, logoSize+4); // 绘制Logo ctx.drawImage(img, logoX, logoY, logoSize, logoSize); }; // 错误处理 img.onerror = () => { console.error(&#39;Logo加载失败&#39;); // 可添加时间戳的重试逻辑[^4] }; } } catch (err) { console.error(&#39;生成二维码失败:&#39;, err); } } }, watch: { text() { this.generateQR(); }, logo() { this.generateQR(); } } } </script> ``` ### 关键配置说明 1. **容错率**:通过`errorCorrectionLevel`设置(L/M/Q/H),建议使用`&#39;H&#39;`(30%容错) 2. **Logo处理**: - 居中定位:通过绝对定位或Canvas坐标计算 - 尺寸比例:Logo宽度 ≈ 二维码宽度的1/5 - 背景垫层:避免二维码图案干扰Logo识别 3. **跨域问题**: - 设置`crossOrigin="Anonymous"`[^4] - 服务端需配置`Access-Control-Allow-Origin` ### 使用示例 ```vue <template> <div> <QrWithLogo text="https://example.com" logo="/path/to/logo.png" size="300" /> </div> </template> ``` ### 优化建议 1. **动态更新**:监听`text`和`logo`prop的变化自动重绘 2. **下载功能**:添加`canvas.toDataURL()`导出图片 3. **容错处理**:使用`try/catch`包裹二维码生成逻辑 4. **响应式**:通过CSS媒体查询调整二维码尺寸
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值