Vue3 二维码生成器实现方案(本项目实战拆解)
本文基于本项目的「二维码生成器」工具,拆解一套在 Vue3 / Nuxt3 项目中实现可视化二维码生成器的完整方案,重点放在页面结构与功能 JavaScript 的协作方式上,代码均来源于实际线上工具。
在线工具网址:https://see-tool.com/qr-code-generator
工具截图:
一、整体架构设计
本工具采用「Vue 负责结构和状态容器、独立 JS 负责绘制与交互」的分层思路:
- Vue 页面组件:
pages/qr-code-generator.vue,负责:- 渲染所有表单控件(文本/URL/邮箱/电话/SMS/WiFi/vCard 等类型)
- 输出带有
data-*标记的 DOM 结构,作为 JS 工具层的「挂载点」 - 提供预览区域、下载按钮区域,以及文档说明和相关工具组件
- 功能脚本一:
public/js/qr-code-generator-ui.js,只处理:- 类型卡片的选中态切换(
.qr-type-card) - 不同类型表单块的显隐(
.qr-input-form) - 监听
render-event/ 路由变化重新绑定
- 类型卡片的选中态切换(
- 功能脚本二:
public/js/qr-code-generator-tool.js,负责核心能力:- 动态加载第三方
qrcode-generator库 - 解析不同类型表单内容并组装成最终字符串
- 根据参数(尺寸、容错等级、前景色/背景色、点样式、定位角样式、中心 Logo)绘制二维码
- 生成 Canvas,并支持导出 PNG / SVG
- 监听输入变化,已生成过一次后自动「实时预览重绘」
- 动态加载第三方
这种拆分的好处是:Vue 只关心「结构和语义」,复杂的 Canvas 绘制逻辑完全放在独立 JS 中,通过data-qr-generator这一属性完成耦合。
二、Vue 页面:用>三、UI 交互层:类型切换与表单显隐
public/js/qr-code-generator-ui.js是一个自执行函数,仅做 UI 层交互:
setActiveType(root, type):- 遍历所有
.qr-type-card,给当前类型加上active,其它移除 - 遍历
.qr-input-form,data-form === type的移除hidden,其余加上hidden
- 遍历所有
bind(root):- 找到默认
active的卡片,或回退到text类型 - 给每张卡片绑定
click事件,切换类型
- 找到默认
init():- 通过
document.querySelectorAll('[data-qr-generator]')找到所有实例并绑定 - 监听
DOMContentLoaded、render-event、hashchange、popstate,确保在 SSR 渲染完成、前端路由切换后都能重新扫描并绑定
- 通过
这一层刻意不碰任何二维码算法或 Canvas,只负责「用户点哪里,看到哪个表单」。
四、核心工具层:从表单到二维码的完整流水线
public/js/qr-code-generator-tool.js是真正的核心,实现步骤可以拆成几块。
1. 环境准备与工具函数
loadScriptOnce(src):按 src 检查是否已经插入<script>,避免重复加载;如果脚本标签存在但库尚未就绪,则监听load/error。hexToRgba/isValidHexColor:处理颜色合法性与转换。normalizeUrl(url):为 URL 类型做 https 默认补全。getActiveType / getActiveDotStyle / getActiveEyeStyle:根据当前 DOM 选中态读出类型和样式。
2. 按类型组装内容字符串
getContentByType(root, type)是「业务协议」的核心,它根据类型从表单里取值,并组装不同的目标格式:
text:直接取纯文本;url:调用normalizeUrl,自动补https://;email:拼接为mailto:协议,支持 subject / body 参数;phone:tel:协议;sms:sms:号码?body=内容;wifi:按照标准 WiFi QR 协议拼出WIFI:T:WPA;S:SSID;P:PASSWORD;H:true;;;vcard:生成一个BEGIN:VCARD/END:VCARD的多行 vCard 文本,包含姓名、公司、电话、邮箱、网址等。
如果必填字段为空(如邮箱地址、WiFi SSID、vCard 姓名),函数会返回空字符串,后续生成逻辑会弹出「请填写必填字段」的通知而不是生成无效二维码。
3. Canvas 绘制:点阵 + 定位角 + Logo
生成二维码视觉效果的关键在buildQrCanvas:
- 通过第三方库
window.qrcode(0, errorLevel)生成二维码矩阵:addData(text)/make()得到qr.getModuleCount()和qr.isDark(row, col)。
- 创建 Canvas 并先用背景色铺底。
- 遍历矩阵:
- 通过
isInEyeFrame(row, col, moduleCount)判断当前 cell 是否属于三个位于角落的定位图形; - 非定位区域调用
drawDots(ctx, x, y, cellSize, dotStyle):square:纯方块;rounded:通过roundRect或手写 path 实现圆角矩形;dots:圆点样式。
- 通过
- 三个定位角通过
drawEyeFrame单独绘制,支持多种样式:- 通过 path / arc / 手写 roundRect 实现 diamond / leaf / dot / circle / extra-rounded / classy 等;
- 外框、内框、中心块用深浅色组合绘制。
- 如果用户上传了中心 Logo:
- 把图片读成 DataURL,
img.onload后在中心开一块浅底矩形,再绘制缩放后的 logo 图片。
- 把图片读成 DataURL,
最终返回一个 Promise,resolve 出完整绘制好的 Canvas。
4. 从 Canvas 导出 SVG
canvasToSvg(canvas, colorLight, colorDark)负责把渲染结果转成矢量 SVG:
- 读取整张 Canvas 的
imageData; - 先输出一个背景
rect,用浅色填充; - 再按像素遍历,凡是足够「黑」的像素,就在 path 中追加
M x,y h1 v1 h-1 z这种 1×1 小方块; - 最终得到一个单 path 的 SVG,方便下载和后续放大使用。
5. 绑定页面:生成、实时重绘与下载
bindQrTool(root)负责把整条流水线串起来:
- 先通过各种
data-field、.pattern-selector、.eye-frame-selector把 DOM 节点引用缓存下来; - 同步尺寸滑块与文字显示、同步颜色选择器与文本输入;
- 处理 Logo 上传、清除,以及文件名展示。
核心的生成逻辑在generate():
ensureLib():按需加载qrcode-generator.min.js,只加载一次;- 读取当前类型与内容,若为空则调用
window.showNotification提示并终止; - 读取尺寸、容错等级、颜色、点样式、定位角样式、Logo 等参数;
- 清空预览 DOM,调用
buildQrCanvas得到 Canvas; - 把 Canvas append 到预览容器中,并展示下载按钮;
- 记录
lastCanvas与hasGeneratedOnce标记,后续即可支持「改参数自动重绘」。
为了让体验更「所见即所得」,还提供了防抖重绘:
debounce(generate, 250)得到debouncedRegenerate;- 在尺寸滑块、容错等级选择、颜色输入、点样式/定位角样式、Logo 上传与清除、以及所有
.qr-input-form中的input/textarea/select/checkbox变动时触发; - 如果尚未生成过一次,则不会重绘,避免无意义计算。
最后是下载逻辑:
- PNG 下载:
lastCanvas.toDataURL('image/png')赋给临时<a>的href,设置download='qrcode.png'后触发点击; - SVG 下载:先用
canvasToSvg拿到字符串,再用 Blob +URL.createObjectURL生成临时链接,设置download='qrcode.svg'后点击并释放 URL。
五、在 Vue 项目中复用这套方案的要点
总结这套实现的关键点,其实就是一句话:Vue 负责结构和「可操作的标记」,具体的绘制逻辑用独立 JS 模块承载,通过>
Cogito-v1-preview-llama-3B效果验证:在CMMLU中文大模型评测中排名第一
Cogito-v1-preview-llama-3B效果验证:在CMMLU中文大模型评测中排名第一 1. 模型概述 Cogito v1 预览版是Deep Cogito推出的混合推理模型系列,在大多数标准基准测试中均超越了同等规模下最优的开源模型,包括来自LLaMA、DeepSeek和Qwen等模型…
春联生成模型-中文-base实战教程:两字祝福词一键生成高清春联
春联生成模型-中文-base实战教程:两字祝福词一键生成高清春联 1. 快速了解春联生成模型 春联生成模型是专门为春节场景设计的AI创作工具,只需要输入两个字的祝福词,就能自动生成与之相关的高质量春联。这个模型基于强大的中文生成技术&…
cv_unet_image-colorization多场景落地:博物馆档案修复企业应用案例
cv_unet_image-colorization多场景落地:博物馆档案修复企业应用案例 1. 引言:当黑白档案遇见AI色彩 走进任何一家博物馆的档案室,你都会看到成排的档案柜,里面珍藏着大量黑白照片、历史文献和珍贵影像。这些资料记录了时代的变迁…
中小企业安防升级方案:DAMO-YOLO手机检测镜像免配置实战手册
中小企业安防升级方案:DAMO-YOLO手机检测镜像免配置实战手册 1. 项目概述 1.1 系统简介 这是一个专为中小企业设计的实时手机检测系统,基于阿里巴巴达摩院的DAMO-YOLO和TinyNAS技术构建。系统采用"小、快、省"的设计理念,特别适…
政务热线语音分析:SenseVoice-Small ONNX模型识别市民诉求关键词+紧急程度分级
政务热线语音分析:SenseVoice-Small ONNX模型识别市民诉求关键词紧急程度分级 你有没有想过,每天成千上万的市民打进政务热线,那些接线员是怎么快速判断哪些事情最紧急、哪些问题最需要优先处理的? 过去,这全靠人工听…
TranslucentTB:5步打造个性化Windows任务栏体验
TranslucentTB:5步打造个性化Windows任务栏体验 【免费下载链接】TranslucentTB 项目地址: https://gitcode.com/gh_mirrors/tra/TranslucentTB TranslucentTB是一款专注于Windows任务栏透明化的实用工具,能够帮助用户实现任务栏透明、半透明效果…