news 2026/2/28 16:02:42

Vue3二维码生成器实现方案

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Vue3二维码生成器实现方案

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-formdata-form === type的移除hidden,其余加上hidden
  • bind(root)
    • 找到默认active的卡片,或回退到text类型
    • 给每张卡片绑定click事件,切换类型
  • init()
    • 通过document.querySelectorAll('[data-qr-generator]')找到所有实例并绑定
    • 监听DOMContentLoadedrender-eventhashchangepopstate,确保在 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 参数;
  • phonetel:协议;
  • smssms:号码?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

  1. 通过第三方库window.qrcode(0, errorLevel)生成二维码矩阵:
    • addData(text)/make()得到qr.getModuleCount()qr.isDark(row, col)
  2. 创建 Canvas 并先用背景色铺底。
  3. 遍历矩阵:
    • 通过isInEyeFrame(row, col, moduleCount)判断当前 cell 是否属于三个位于角落的定位图形;
    • 非定位区域调用drawDots(ctx, x, y, cellSize, dotStyle)
      • square:纯方块;
      • rounded:通过roundRect或手写 path 实现圆角矩形;
      • dots:圆点样式。
  4. 三个定位角通过drawEyeFrame单独绘制,支持多种样式:
    • 通过 path / arc / 手写 roundRect 实现 diamond / leaf / dot / circle / extra-rounded / classy 等;
    • 外框、内框、中心块用深浅色组合绘制。
  5. 如果用户上传了中心 Logo:
    • 把图片读成 DataURL,img.onload后在中心开一块浅底矩形,再绘制缩放后的 logo 图片。

最终返回一个 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()

  1. ensureLib():按需加载qrcode-generator.min.js,只加载一次;
  2. 读取当前类型与内容,若为空则调用window.showNotification提示并终止;
  3. 读取尺寸、容错等级、颜色、点样式、定位角样式、Logo 等参数;
  4. 清空预览 DOM,调用buildQrCanvas得到 Canvas;
  5. 把 Canvas append 到预览容器中,并展示下载按钮;
  6. 记录lastCanvashasGeneratedOnce标记,后续即可支持「改参数自动重绘」。

为了让体验更「所见即所得」,还提供了防抖重绘:

  • 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 模块承载,通过>

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/28 10:18:14

Switch控制器适配全攻略:从故障排查到跨设备优化的技术实践

Switch控制器适配全攻略&#xff1a;从故障排查到跨设备优化的技术实践 【免费下载链接】BetterJoy Allows the Nintendo Switch Pro Controller, Joycons and SNES controller to be used with CEMU, Citra, Dolphin, Yuzu and as generic XInput 项目地址: https://gitcode…

作者头像 李华
网站建设 2026/2/23 23:16:24

为什么92%的AIGC团队还没用上Seedance2.0?——双分支动态路由、梯度重校准与推理加速三重瓶颈全解析

第一章&#xff1a;Seedance2.0双分支扩散变换器架构解析Seedance2.0 是面向高保真图像生成任务设计的新型扩散模型架构&#xff0c;其核心创新在于解耦式双分支结构——分别处理**语义一致性建模**与**细节纹理增强**。该设计突破了传统单路径扩散模型在长程依赖建模与高频信息…

作者头像 李华
网站建设 2026/2/28 11:49:47

STM32增量编码器硬件解码与工程实践

1. 增量型旋转编码器的硬件原理与工程建模增量型旋转编码器是嵌入式系统中最常用的角位移/旋转方向检测器件之一&#xff0c;其核心价值不在于提供绝对角度&#xff0c;而在于以高可靠性、低延迟、无累积误差的方式反馈相对运动状态。学习板上所用旋钮内部集成的正是典型的双通…

作者头像 李华
网站建设 2026/2/28 5:16:58

Windows系统优化工具:ContextMenuManager效率提升实战指南

Windows系统优化工具&#xff1a;ContextMenuManager效率提升实战指南 【免费下载链接】ContextMenuManager &#x1f5b1;️ 纯粹的Windows右键菜单管理程序 项目地址: https://gitcode.com/gh_mirrors/co/ContextMenuManager 在Windows系统日常使用中&#xff0c;右键…

作者头像 李华
网站建设 2026/2/25 10:06:05

tao-8k开源大模型部署教程:适配国产昇腾/寒武纪平台的交叉编译实践

tao-8k开源大模型部署教程&#xff1a;适配国产昇腾/寒武纪平台的交叉编译实践 1. 模型简介与核心价值 tao-8k是由Hugging Face开发者amu研发并开源的高性能文本嵌入模型。该模型专注于将文本转换为高维向量表示&#xff0c;其核心优势在于支持长达8192&#xff08;8K&#x…

作者头像 李华