npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

vue3-next-qrcode

v4.1.1

Published

<p align="center"> <a href="https://github.com/XiaoDaiGua-Ray/vue3-next-qrcode"> <img width="216" src="https://usc1.contabostorage.com/c2e495d7890844d392e8ec0c6e5d77eb:alist/ray/ray.svg?sign=ZklU9Bh5b6oKp1X0LOhGwkx4g5mW4wk_w9Jt5zlZ5EQ=:0"> </a> </

Downloads

1,189

Readme

vue3-next-qrcode

English | 简体中文

面向 Vue 3 的二维码组件,支持 Logo、图片/GIF 背景、状态 UI、useQRCode,并且包入口可在 SSR 中安全导入。

效果预览

为什么用它

  • 既可以作为 Vue 组件使用,也可以用 useQRCode 编程式生成二维码。
  • 支持 Logo、图片背景、GIF 背景、自定义点样式、加载/错误状态和下载。
  • 根入口在 Nuxt 等 SSR 框架中可以安全导入。
  • 渲染核心按需懒加载,GIF parser/encoder 只在使用 GIF 背景时加载。
  • GIF 渲染带资源保护并按需加载;当前包构建使用已验证的主线程渲染路径。
  • 使用 TypeScript 编写,提供组件、composable 和实例类型。

安装

pnpm add vue3-next-qrcode
npm install vue3-next-qrcode

支持 Vue 3.0.1 及以上版本,peer 范围继续保持 ^3.0.1

快速开始

<script setup lang="ts">
import { Vue3NextQrcode } from 'vue3-next-qrcode'
import 'vue3-next-qrcode/style.css'
</script>

<template>
  <Vue3NextQrcode text="https://github.com/XiaoDaiGua-Ray/vue3-next-qrcode" />
</template>

如果你更喜欢全局注册:

import { createApp } from 'vue'
import Vue3NextQrcode from 'vue3-next-qrcode'
import 'vue3-next-qrcode/style.css'
import App from './App.vue'

createApp(App).use(Vue3NextQrcode).mount('#app')

常见用法

自定义大小和颜色

<script setup lang="ts">
import { QRErrorCorrectLevel } from 'vue3-next-qrcode'
</script>

<template>
  <Vue3NextQrcode
    text="Hello QR"
    :size="240"
    :margin="16"
    colorDark="#111827"
    colorLight="#ffffff"
    :correctLevel="QRErrorCorrectLevel.H"
  />
</template>

中间添加 Logo

<Vue3NextQrcode
  text="https://example.com"
  logoImage="https://example.com/logo.png"
  :logoScale="0.28"
  :logoMargin="8"
  :logoCornerRadius="6"
/>

GIF 背景

<script setup lang="ts">
const gifUrl = 'https://example.com/background.gif'
</script>

<template>
  <Vue3NextQrcode
    text="动态二维码"
    :gifBackgroundURL="gifUrl"
    :dotScale="0.5"
    colorDark="#64d9d6"
  />
</template>

普通二维码不会加载 GIF parser 和 encoder 代码。只有使用 gifBackgroundURLgifBackground 时才会按需加载。

加载和错误状态

<template>
  <Vue3NextQrcode text="loading" status="loading" />

  <Vue3NextQrcode
    text="expired"
    status="error"
    errorDescription="二维码已过期"
    errorActionDescription="重新加载"
    :onReload="refreshQRCode"
  />
</template>

默认 UI 不够时可以使用插槽:

<Vue3NextQrcode text="loading" status="loading">
  <template #loading>
    <span>生成中...</span>
  </template>
</Vue3NextQrcode>

下载二维码

<script setup lang="ts">
import { ref } from 'vue'
import type { QRCodeInst } from 'vue3-next-qrcode'

const qrcodeRef = ref<QRCodeInst>()

const download = () => {
  qrcodeRef.value?.downloadQRCode('qrcode.png')
}
</script>

<template>
  <Vue3NextQrcode ref="qrcodeRef" text="下载我" />
  <button @click="download">下载</button>
</template>

Nuxt 4 和 SSR

包入口可以在 SSR 阶段安全导入。二维码图片生成仍然依赖浏览器 Canvas,因此组件渲染请放到 <ClientOnly> 或等价的客户端边界中。

<template>
  <ClientOnly>
    <QRCodeClient text="Hello Nuxt" />
    <template #fallback>
      <span>二维码加载中...</span>
    </template>
  </ClientOnly>
</template>

<script setup lang="ts">
import { QRCodeClient } from 'vue3-next-qrcode/client'
import 'vue3-next-qrcode/style.css'
</script>

也可以对特定路由关闭 SSR:

export default defineNuxtConfig({
  routeRules: {
    '/qrcode': { ssr: false },
  },
})

Nuxt 4 项目应把页面或组件放在 app/pages/app/components/ 下,并显式导入 vue3-next-qrcode/style.css。Nuxt 会从服务端构建中 tree-shake 掉 <ClientOnly> 默认插槽,因此只由内部组件引入的 CSS 不一定出现在首屏 HTML 中;建议同时提供 #fallback,保证 SSR 占位稳定并减少布局抖动。多数项目不需要 transpile、alias 或 optimizeDeps 配置。

参考官方 Nuxt <ClientOnly> 文档Nuxt 4 升级指南

编程式生成

当你只想拿到二维码图片,而不想使用组件内置 UI 时,可以使用 useQRCode

<script setup lang="ts">
import { ref } from 'vue'
import { QRCodeGenerationCancelledError, useQRCode } from 'vue3-next-qrcode'

const text = ref('Hello from useQRCode')
const { qrcodeURL, isLoading, status, error, generate, cancel, reset } =
  useQRCode({ concurrency: 'latest' })

const create = async () => {
  try {
    await generate({ text: text.value, size: 300, margin: 20 })
  } catch (cause) {
    if (!(cause instanceof QRCodeGenerationCancelledError)) throw cause
  }
}
</script>

<template>
  <input v-model="text" />
  <button :disabled="isLoading" @click="create">
    {{ isLoading ? '生成中...' : '生成' }}
  </button>
  <button @click="cancel">取消</button>
  <button @click="reset">重置</button>

  <p>状态:{{ status }}</p>
  <p v-if="error">{{ error.message }}</p>
  <img v-if="typeof qrcodeURL === 'string'" :src="qrcodeURL" alt="二维码" />
</template>

useQRCode 返回值

function useQRCode(): {
  qrcodeURL: Ref<string | ArrayBuffer | Uint8Array | undefined>
  isLoading: Ref<boolean>
  status: Ref<'idle' | 'loading' | 'success' | 'error' | 'cancelled'>
  error: Ref<Error | null>
  generate: (
    options: UseQRCodeOptions,
  ) => Promise<string | ArrayBuffer | Uint8Array | undefined>
  canDownload: ComputedRef<boolean>
  download: (fileName?: string) => Promise<void>
  cancel: () => void
  reset: () => void
  clear: () => void
  dispose: () => void
}

useQRCode({ defaultOptions, concurrency }) 支持兼容默认值 rejectlatest。当 defaultOptions.text 完整提供时,可以无参数调用 generate()。 被替代、取消或 dispose 的调用会以 QRCodeGenerationCancelledError 拒绝。 cancel() 保留上一次成功图片;reset() 清空结果;clear() 继续作为 reset() 的兼容别名。Vue 作用域中的 Hook 会自动 dispose,也可以显式调用。

如果只需要复用下载行为,也可以直接使用导出的 useQRCodeDownload(sourceRef)。需要清理共享 GIF URL 缓存时,调用 clearQRCodeGIFCache()

包导出

import {
  Vue3NextQrcode,
  useQRCode,
  useQRCodeDownload,
  clearQRCodeGIFCache,
} from 'vue3-next-qrcode'
import { QRCodeClient } from 'vue3-next-qrcode/client'
import 'vue3-next-qrcode/style.css'

旧样式路径仍然保留:

import 'vue3-next-qrcode/es/style.css'
import 'vue3-next-qrcode/lib/style.css'

Props

| Prop | 类型 | 默认值 | 说明 | | ------------------------ | ----------------------------------- | ----------------------------- | --------------------------------------------------------------------------- | | text | string | 必填 | 编码到二维码里的文本。 | | size | number | 160 | 二维码尺寸,单位像素。 | | margin | number | 12 | 二维码主体周围的安静区边距。 | | correctLevel | 0 \| 1 \| 2 \| 3 | 1 | 纠错级别映射:L=1M=0Q=3H=2,推荐使用 QRErrorCorrectLevel。 | | watchText | boolean | true | text 变化时自动重新渲染。 | | status | 'loading' \| 'error' \| 'success' | undefined | 展示加载或错误状态。 | | colorDark | string | '#000000' | 二维码模块颜色。 | | colorLight | string | '#ffffff' | 二维码背景颜色。 | | autoColor | boolean | true | 尽可能根据图片/GIF 背景推导二维码颜色。 | | backgroundImage | string | undefined | 静态背景图 URL 或 data URL。 | | backgroundDimming | string | 'rgba(0, 0, 0, 0)' | 背景图上方的遮罩颜色。 | | gifBackgroundURL | string | undefined | GIF 背景 URL。 | | gifBackground | ArrayBuffer | undefined | GIF 背景二进制数据。 | | logoImage | string | undefined | 中间 Logo 图片 URL 或 data URL。 | | logoScale | number | 0.4 | Logo 相对二维码尺寸的比例。 | | logoMargin | number | 6 | Logo 边距,单位像素。 | | logoCornerRadius | number | 8 | Logo 圆角,单位像素。 | | dotScale | number | undefined | 可选全局点阵比例 (0, 1];显式设置时覆盖 data/timing/alignment 比例。 | | whiteMargin | boolean | true | 使用白色安静区,而不是透明安静区。 | | components | ComponentOptions | 内置默认值 | 精细控制二维码局部样式。 | | maskPattern | number | undefined | 强制指定 07 的 QR mask pattern,一般无需设置。 | | version | number | undefined | 强制指定 QR version,范围 140,一般无需设置。 | | defineProvider | Partial<DefineProvider> | undefined | 当前组件的 CSS 变量覆盖。 | | maskColor | string | 'rgba(255, 255, 255, 0.96)' | 加载/错误遮罩颜色。 | | errorDescription | string \| VNode | '二维码已过期' | 错误状态描述。 | | errorActionDescription | string | '重新加载' | 错误操作文案。 | | onSuccess | (result) => void 或数组 | null | 生成成功后触发,结果为 string \| ArrayBuffer \| Uint8Array \| undefined。 | | onError | (error) => void 或数组 | null | 生成失败后触发。 | | onReload | () => void 或数组 | null | 点击内置错误操作时触发。 |

在 SFC 模板中,你可以按项目习惯使用 camelCase(gifBackgroundURL)或 kebab-case(gif-background-url)。

插槽和实例方法

| 插槽 | 说明 | | ------------- | -------------------- | | loading | 自定义加载状态。 | | errorAction | 自定义错误操作区域。 |

interface QRCodeInst {
  downloadQRCode: (fileName?: string) => Promise<void>
}

CSS 变量

| 区域 | 变量 | | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | 尺寸 | --r-qrcode-width--r-qrcode-height | | 容器 | --r-qrcode-background-color--r-qrcode-border-width--r-qrcode-border-style--r-qrcode-border-color--r-qrcode-border-radius--r-qrcode-overflow--r-qrcode-font-family | | 图片/遮罩 | --r-qrcode-image-object-fit--r-qrcode-mask-color | | Loading | --r-qrcode-loading-spinner-size--r-qrcode-loading-spinner-border-width--r-qrcode-loading-spinner-color--r-qrcode-loading-animation-duration | | Error | --r-qrcode-error-z-index--r-qrcode-error-gap--r-qrcode-error-color--r-qrcode-error-content-padding | | Action | --r-qrcode-action-color--r-qrcode-action-hover-color--r-qrcode-action-active-color--r-qrcode-action-transition-duration |

旧变量 --r-qrcode-primary-color--r-qrcode-primary-color-2--r-qrcode-spin-size 继续作为兼容 fallback。

使用 defineProvider 可以对单个组件覆盖:

<Vue3NextQrcode
  text="Styled QR"
  :defineProvider="{
    '--r-qrcode-background-color': '#101828',
    '--r-qrcode-border-color': '#6941c6',
    '--r-qrcode-border-radius': '16px',
    '--r-qrcode-loading-spinner-color': '#9e77ed',
    '--r-qrcode-action-color': '#fdb022',
    '--r-qrcode-action-hover-color': '#f79009',
  }"
/>

TypeScript

import type {
  QRCodeInst,
  QRCodeLevel,
  QRCodeStatus,
  QRCodeProps,
  QRCodeOptions,
  ComponentOptions,
  UseQRCodeOptions,
  UseQRCodeReturnType,
  QRCodeDownloadSource,
  UseQRCodeDownloadReturn,
} from 'vue3-next-qrcode'

测试

当前包同时覆盖单元测试和发布 smoke:

  • vitest + happy-dom 覆盖 prop 校验、GIF URL 缓存/请求去重、下载行为、渲染队列语义、useQRCodeQRCode 组件异步渲染,以及当前包构建的主线程渲染路径。
  • scripts/smoke.mjs 校验 ESM/CJS 根入口、client 子路径、样式导出、发布文件完整性、声明文件消费、私有路径残留、packaged worker 禁用引用,以及 emoji 二维码编码。

执行完整验证:

pnpm run test

迁移说明

v4.1.0

  • 推荐使用 vue3-next-qrcode/style.css 引入样式。
  • Nuxt 中推荐使用 vue3-next-qrcode/client<ClientOnly>
  • 根入口和 useQRCode 导入是 SSR-safe 的,但二维码图片生成仍在客户端。
  • 浏览器侧二进制结果使用 Uint8Array,不再暴露 Node Buffer 类型。
  • downloadQRCode() 返回 Promise<void>
  • 非法 versionmaskPatterndotScale 会直接校验失败。
  • 未列入 package exports 的内部深层导入不受支持。
  • Vue 最低版本仍是 3.0.1,不是破坏性升级。

详见 v4.1.0 迁移文档

从 v3 迁移

  • CSS 类名前缀从 ray-qrcode 改为 r-qrcode
  • img_tag 改为 data-component
  • GIF 和图片渲染逻辑现在会按需懒加载。

常见问题

SSR 中能 import 吗?

可以。根入口和 useQRCode 都可以在 SSR 阶段安全导入。二维码图片渲染仍需要放到客户端。

Nuxt SSR 时为什么看不到二维码?

QRCodeClient 是客户端渲染组件。如果需要 SSR 占位内容,可以给 <ClientOnly> 添加 fallback。

GIF 渲染需要配置 Worker 吗?

不需要。当前包构建使用已验证的主线程 GIF 渲染。Worker 渲染会等相对 worker URL 通过 ESM 和 CJS 包 smoke 后再恢复。

可以在小程序里使用吗?

不能直接使用。小程序使用平台特定 Canvas API,需要单独适配。

License

MIT