Taro+vue3基于微信小程序字符串转化为二维码图片

48 阅读1分钟

安装核心库

npm install qrcode-generator --save

Taro Canvas支持(微信小程序必备)

npm install @tarojs/components @tarojs/taro

<template>
  <view class="qr-container">
    <canvas
      :canvas-id="canvasId"
      :style="{
        width: `${size}px`,
        height: `${size}px`,
        backgroundColor: background,
      }"
    />
  </view>
</template>

<script setup lang="ts">
import Taro from '@tarojs/taro'
import QRCode from 'qrcode-generator'

const props = withDefaults(defineProps<IProps>(), {
  content: '', // 编码内容
  size: 200, // 显示尺寸
  errorLevel: 'H', // 纠错等级(L/M/Q/H)
  background: '#fff', // 背景色
  canvasId: 'qrCanvas',
  margin: 20, // 边距
})
const generateQR = () => {
  // 初始化二维码实例
  const qr = QRCode(0, props.errorLevel)
  qr.addData(props.content)
  qr.make()

  // 获取Canvas上下文
  const ctx = Taro.createCanvasContext(props.canvasId)
  const moduleCount = qr.getModuleCount()
  // 设备像素比
  const deviceDpr = 1 //Taro.getSystemInfoSync().pixelRatio
  const realSize = props.size * deviceDpr
  console.log('deviceDpr', deviceDpr, window.devicePixelRatio)

  // 计算模块尺寸
  const cellSize = (realSize - props.margin * 2 * deviceDpr) / moduleCount

  // 绘制二维码矩阵
  for (let row = 0; row < moduleCount; row++) {
    for (let col = 0; col < moduleCount; col++) {
      ctx.fillStyle = qr.isDark(row, col) ? '#000' : props.background
      ctx.fillRect(
        props.margin + col * cellSize,
        props.margin + row * cellSize,
        cellSize,
        cellSize,
      )
    }
  }

  // 高清屏适配
  const dpr = Taro.getSystemInfoSync().pixelRatio
  ctx.scale(dpr, dpr)
  ctx.draw()
}

onMounted(() => {
  generateQR()
})

type ErrorLevel = 'L' | 'M' | 'Q' | 'H'
interface IProps {
  content: string
  size?: number
  errorLevel?: ErrorLevel
  background?: string
  canvasId?: string
  margin?: number
}
</script>

<style>
.qr-container {
  text-align: center;
}
</style>

高级扩展-动态Logo叠加

**动态Logo叠加**
// 在generateQR方法末尾添加 
ctx.drawImage('static/logo.png', 
    this.size/2 - 20, // x坐标居中 
    this.size/2 - 20, // y坐标居中 
    40, 40, // 宽高 
    () => ctx.draw() // 重绘 );
);

渐变颜色特效

// 替换fillStyle逻辑 
const gradient = ctx.createLinearGradient(0, 0, this.size, this.size); 
gradient.addColorStop(0, '#FF6B6B'); 
gradient.addColorStop(1, '#4ECDC4');
ctx.fillStyle = qr.isDark(row, col) ? gradient : this.background;