当前位置: 首页 > news >正文

QRCode 核心知识汇总

在 CRM 系统中,二维码(QRCode)常用于客户名片、订单二维码、支付链接、物料溯源等场景。Vue3 中实现二维码生成首选qrcode库(轻量、灵活、支持自定义样式),下面从「核心用法→Vue3 组件封装→CRM 实战场景」全维度讲解。

一、核心准备

1. 安装依赖

bash

运行

# 安装核心库(支持浏览器/Node.js) npm install qrcode # TypeScript 类型(可选,库自带类型)

2. 核心 API 说明

qrcode库提供 3 种生成二维码的方式,适配不同场景:

表格

API 类型

用法

适用场景

toCanvas

直接渲染到 Canvas 元素

页面内展示二维码(性能最优)

toDataURL

生成 Base64 图片地址

保存二维码、打印、跨组件使用

toString

生成 ASCII 码字符串

终端展示(CRM 中几乎不用)

二、Vue3 通用二维码组件封装(CRM 首选)

封装一个可复用的二维码组件,支持自定义尺寸、颜色、内容,适配 CRM 所有二维码场景:

完整组件:src/components/QrcodeGenerator.vue

vue

<template> <!-- 容器:用于自适应二维码尺寸 --> <div class="qrcode-container" :style="{ width: `${size}px`, height: `${size}px` }"> <!-- Canvas 渲染(性能最优) --> <canvas ref="qrcodeCanvas" :width="size" :height="size"></canvas> <!-- 可选:Base64 图片备用(如需保存/打印) --> <img v-if="showImg" ref="qrcodeImg" class="qrcode-img" :src="qrcodeUrl" alt="二维码" style="display: none" /> </div> </template> <script setup lang="ts"> import { ref, watch, onMounted, defineProps, defineEmits } from 'vue'; import QRCode, { QRCodeToCanvasOptions, QRCodeToDataURLOptions } from 'qrcode'; // 定义组件属性 const props = defineProps({ // 二维码内容(必填:如订单链接、客户ID、支付地址) content: { type: String, required: true, default: '' }, // 二维码尺寸(默认 200px) size: { type: Number, default: 200 }, // 前景色(二维码颜色) color: { type: Object, default: () => ({ dark: '#000000', // 深色(二维码) light: '#ffffff' // 浅色(背景) }) }, // 纠错级别(L/M/Q/H,H 容错最高) errorCorrectionLevel: { type: String, default: 'H', validator: (val: string) => ['L', 'M', 'Q', 'H'].includes(val) }, // 是否生成 Base64 图片(用于保存/打印) needBase64: { type: Boolean, default: false } }); // 定义事件 const emit = defineEmits(['success', 'error']); // 模板引用 const qrcodeCanvas = ref<HTMLCanvasElement | null>(null); const qrcodeImg = ref<HTMLImageElement | null>(null); const qrcodeUrl = ref(''); // Base64 地址 const showImg = ref(props.needBase64); // 二维码配置 const getQrConfig = (): QRCodeToCanvasOptions => ({ width: props.size, color: props.color, errorCorrectionLevel: props.errorCorrectionLevel }); // 生成二维码核心方法 const generateQrcode = async () => { if (!props.content) { emit('error', new Error('二维码内容不能为空')); return; } if (!qrcodeCanvas.value) return; try { // 1. 渲染到 Canvas await QRCode.toCanvas(qrcodeCanvas.value, props.content, getQrConfig()); emit('success', '二维码生成成功'); // 2. 如需 Base64,额外生成 if (props.needBase64) { const base64 = await QRCode.toDataURL(props.content, getQrConfig() as QRCodeToDataURLOptions); qrcodeUrl.value = base64; } } catch (err) { emit('error', err as Error); console.error('二维码生成失败:', err); } }; // 监听内容变化,重新生成 watch( () => [props.content, props.size, props.color], () => generateQrcode(), { immediate: true, deep: true } ); // 组件挂载时生成 onMounted(() => generateQrcode()); // 暴露方法:手动生成/获取 Base64 defineExpose({ generateQrcode, getQrcodeUrl: () => qrcodeUrl.value }); </script> <style scoped> .qrcode-container { display: inline-block; border: 1px solid #eee; border-radius: 4px; overflow: hidden; } .qrcode-img { width: 100%; height: 100%; object-fit: contain; } </style>

三、CRM 高频实战场景

场景 1:订单二维码(展示 + 保存)

CRM 订单详情页生成订单二维码,包含订单 ID / 链接,支持保存到本地:

vue

<template> <div class="order-qrcode"> <h3>订单二维码</h3> <!-- 使用封装的二维码组件 --> <QrcodeGenerator :content="qrcodeContent" :size="200" :need-base64="true" @success="handleSuccess" @error="handleError" ref="qrcodeRef" /> <button @click="saveQrcode">保存二维码</button> </div> </template> <script setup lang="ts"> import { ref, computed } from 'vue'; import QrcodeGenerator from '@/components/QrcodeGenerator.vue'; import { ElMessage } from 'element-plus'; // 订单信息(从 Pinia/路由获取) const orderId = ref('CRM20260320001'); const baseUrl = import.meta.env.VITE_APP_BASE_URL; // 二维码内容:订单详情链接 const qrcodeContent = computed(() => { return `${baseUrl}/order/detail?id=${orderId.value}`; }); // 组件引用 const qrcodeRef = ref<InstanceType<typeof QrcodeGenerator> | null>(null); // 生成成功/失败回调 const handleSuccess = (msg: string) => ElMessage.success(msg); const handleError = (err: Error) => ElMessage.error(`生成失败:${err.message}`); // 保存二维码到本地 const saveQrcode = async () => { if (!qrcodeRef.value) return; const base64 = qrcodeRef.value.getQrcodeUrl(); if (!base64) { ElMessage.warning('请先生成二维码'); return; } // 创建下载链接 const link = document.createElement('a'); link.href = base64; link.download = `订单${orderId.value}二维码.png`; link.click(); ElMessage.success('二维码保存成功'); }; </script>

场景 2:客户名片二维码(自定义样式)

CRM 客户详情页生成客户名片二维码,包含姓名、电话、公司等信息,自定义颜色适配品牌:

vue

<template> <div class="customer-qrcode"> <QrcodeGenerator :content="customerQrContent" :size="250" :color="{ dark: '#1890ff', light: '#f5f5f5' }" // 蓝色二维码,浅灰背景 errorCorrectionLevel="H" /> </div> </template> <script setup lang="ts"> import { ref, computed } from 'vue'; import QrcodeGenerator from '@/components/QrcodeGenerator.vue'; import { useCustomerStore } from '@/stores/customer'; const customerStore = useCustomerStore(); const customer = customerStore.currentCustomer; // 二维码内容:客户信息JSON(后端可解析) const customerQrContent = computed(() => { return JSON.stringify({ name: customer.name, phone: customer.phone, company: customer.company, position: customer.position, source: 'CRM系统' }); }); </script>

场景 3:批量生成二维码(CRM 物料 / 合同)

批量生成多个二维码(如合同、物料标签),支持批量下载:

vue

<template> <div class="batch-qrcode"> <div v-for="item in batchList" :key="item.id" class="qrcode-item"> <p>{{ item.name }}</p> <QrcodeGenerator :content="item.content" :size="150" :need-base64="true" ref="batchQrRefs" /> </div> <button @click="batchDownload">批量下载二维码</button> </div> </template> <script setup lang="ts"> import { ref } from 'vue'; import QrcodeGenerator from '@/components/QrcodeGenerator.vue'; import { ElMessage } from 'element-plus'; import JSZip from 'jszip'; // 需安装:npm install jszip import FileSaver from 'file-saver'; // 需安装:npm install file-saver // 批量数据(模拟合同列表) const batchList = ref([ { id: 'CON001', name: '合同001', content: 'https://crm.com/contract/001' }, { id: 'CON002', name: '合同002', content: 'https://crm.com/contract/002' }, { id: 'CON003', name: '合同003', content: 'https://crm.com/contract/003' } ]); // 批量组件引用 const batchQrRefs = ref<InstanceType<typeof QrcodeGenerator>[]>([]); // 批量下载 const batchDownload = async () => { const zip = new JSZip(); const promises: Promise<void>[] = []; // 遍历生成zip包 batchQrRefs.value.forEach((ref, index) => { if (!ref) return; const base64 = ref.getQrcodeUrl(); if (base64) { // 去掉 Base64 前缀,转成 Blob const base64Data = base64.split(',')[1]; promises.push( zip.file(`${batchList.value[index].name}.png`, base64Data, { base64: true }).async('blob') ); } }); // 生成zip并下载 try { await Promise.all(promises); const zipContent = await zip.generateAsync({ type: 'blob' }); FileSaver.saveAs(zipContent, 'CRM批量二维码.zip'); ElMessage.success('批量二维码下载成功'); } catch (err) { ElMessage.error('批量下载失败:' + (err as Error).message); } }; </script>

四、核心避坑点

1. 内容过长导致二维码密集

  • 问题:内容(如长链接、大段 JSON)过长,二维码像素密集,扫码困难;
  • 解决方案:
    1. 缩短内容(如用短链接服务转换长链接);
    2. 提高二维码尺寸(建议≥200px);
    3. 设置纠错级别为H(最高容错)。

2. Canvas 跨域 / 保存问题

  • 问题:直接保存 Canvas 可能触发跨域;
  • 解决方案:优先用toDataURL生成 Base64,再通过a标签下载(如场景 1 的保存逻辑)。

3. 动态内容不更新

  • 问题:修改二维码内容后,Canvas 不重新渲染;
  • 解决方案:组件内监听content属性变化,自动重新生成(封装组件已实现)。

4. 移动端适配

  • 问题:移动端二维码显示模糊;
  • 解决方案:
    1. 设置 Canvas 宽高为实际尺寸(避免 CSS 缩放);
    2. 适配移动端尺寸:size="100vw"(最大宽度)。

五、总结(CRM 开发最佳实践)

  1. 组件化封装:将二维码生成逻辑封装为通用组件,避免重复代码;
  2. 按需选择渲染方式
    • 仅展示:用toCanvas(性能最优);
    • 需保存 / 打印 / 批量下载:用toDataURL生成 Base64;
  1. 适配 CRM 场景
    • 订单 / 合同:内容用 “唯一链接 / ID”,支持保存;
    • 客户名片:内容用 JSON,自定义品牌颜色;
    • 批量生成:结合 JSZip 实现批量下载;
  1. 避坑核心:控制内容长度、设置高容错级别、适配移动端尺寸。
http://www.cnnetsun.cn/news/2191958.html

相关文章:

  • 告别盲配!用S32DS可视化工具高效搞定S32K3 MCAL时钟配置(以S32K312为例)
  • 八大网盘直链下载神器:告别限速烦恼的终极指南
  • VLingNav:视觉-语言-动作模型在智能导航中的应用与优化
  • 开源AI智能体编排平台Mission Control:从部署到生产级运维指南
  • RimSort:从模组下载失败到流畅管理的完整解决方案
  • 终极指南:三步轻松清理Windows驱动垃圾,释放数十GB空间
  • FanControl终极指南:免费开源Windows风扇控制软件,5分钟打造静音高效电脑
  • 从洗衣机到汽车:聊聊LIN总线这个‘经济适用型’协议在家电和车联网里的妙用
  • AKShare与Pandas完整整合指南:三步构建高效金融数据分析流程
  • 没人敢说的实话!《灵魂摆渡・浮生梦》怕了孤身闯局的海棠山铁哥和《第一大道》
  • 长期项目使用Taotoken在账单追溯与用量分析上的便利
  • 蓝桥杯单片机省赛拿分秘籍:第十一届这道‘电压阈值计数’题,我是这么啃下来的
  • 别再死记公式了!折叠共源共栅放大器设计中的5个关键权衡与选型思路
  • 分享一个微软开源的Python库用来扫盲转换 markdown格式 知识库
  • google搜索 cookie算法分析
  • CentOS 7/8远程桌面避坑指南:xrdp安装后黑屏、闪退?一次解决所有常见故障
  • 网盘下载太慢?这款开源工具让你免费解锁八大网盘直链下载
  • 抖音内容批量下载终极方案:告别手动录屏的智能工具指南
  • Go语言技能树实战:从并发模式到REST API的工程化演练
  • 强化学习在数学自动证明中的应用与优化
  • 1个侦探工具:3分钟解决Windows快捷键修复难题
  • 目标检测新思路:用Deformable DETR的多尺度注意力,让你的模型‘看清’小物体
  • Visual C++运行库依赖难题的系统级解决方案:VisualCppRedist AIO项目深度解析
  • 文件驱动架构:LemonAid极简问题追踪器的设计与部署实践
  • K8S集群突然失联?别慌,手把手教你排查并修复x509证书过期问题(附完整命令)
  • 别再死记硬背SV约束语法了!用这3个UVM实战案例,带你玩转SystemVerilog随机化验证
  • C语言函数级可验证性优化:用__attribute__((section)) + 静态断言实现FDA要求的100%路径覆盖证据链
  • 从标注到训练:手把手教你用Labelme搞定实例分割数据(附避坑指南)
  • DDrawCompat:让Windows 11也能完美重温DirectX经典游戏的神器
  • 卡梅德生物技术快报|慢病毒包装:大鼠 DOT1L 基因 Lentiviral Packaging 载体构建技术实现|生物实验代码化流程