|
|
@@ -1,940 +0,0 @@
|
|
|
-# 二维码组件 API 参考
|
|
|
-
|
|
|
-> **版本**: v2.0.0 | **更新时间**: 2026-04-13
|
|
|
-
|
|
|
----
|
|
|
-
|
|
|
-## 📦 VbQrGen - 单个二维码组件
|
|
|
-
|
|
|
-### 基础用法
|
|
|
-
|
|
|
-```vue
|
|
|
-<template>
|
|
|
- <VbQrGen
|
|
|
- ref="qrRef"
|
|
|
- v-model="text"
|
|
|
- title="我的二维码"
|
|
|
- :size="200"
|
|
|
- @success="handleSuccess"
|
|
|
- @error="handleError"
|
|
|
- />
|
|
|
- <el-button @click="generate">生成</el-button>
|
|
|
-</template>
|
|
|
-
|
|
|
-<script setup lang="ts">
|
|
|
-import { ref } from 'vue'
|
|
|
-import VbQrGen from '@/components/qrcode/VbQrGen.vue'
|
|
|
-
|
|
|
-const qrRef = ref<InstanceType<typeof VbQrGen>>()
|
|
|
-const text = ref('https://example.com')
|
|
|
-
|
|
|
-function generate() {
|
|
|
- qrRef.value?.generateQRCode()
|
|
|
-}
|
|
|
-
|
|
|
-function handleSuccess(dataURL) {
|
|
|
- console.log('生成成功', dataURL)
|
|
|
-}
|
|
|
-
|
|
|
-function handleError(error) {
|
|
|
- console.error('生成失败', error)
|
|
|
-}
|
|
|
-</script>
|
|
|
-```
|
|
|
-
|
|
|
----
|
|
|
-
|
|
|
-### Props
|
|
|
-
|
|
|
-| 属性 | 类型 | 默认值 | 说明 |
|
|
|
-| --------------------- | ------------------- | ----------------- | ---------------------------- |
|
|
|
-| **modelValue** | `string` | `""` | 二维码文本内容(v-model) |
|
|
|
-| **title** | `string` | `""` | 标题文本 |
|
|
|
-| **titlePosition** | `"top" \| "bottom"` | `"top"` | 标题位置 |
|
|
|
-| **titleStyle** | `object` | `undefined` | 标题自定义样式 |
|
|
|
-| **size** | `number` | `200` | 二维码尺寸(像素) |
|
|
|
-| **margin** | `number` | `12` | 二维码边距(像素) |
|
|
|
-| **colorDark** | `string` | `"#000000"` | 深色块颜色 |
|
|
|
-| **colorLight** | `string` | `"#ffffff"` | 浅色块颜色 |
|
|
|
-| **correctLevel** | `0 \| 1 \| 2 \| 3` | `1` | 纠错等级 (L/M/Q/H) |
|
|
|
-| **logoImage** | `string` | `undefined` | Logo 图片地址 |
|
|
|
-| **logoScale** | `number` | `0.4` | Logo 相对比例 (0-1) |
|
|
|
-| **logoMargin** | `number` | `6` | Logo 边距(像素) |
|
|
|
-| **logoCornerRadius** | `number` | `8` | Logo 圆角(像素) |
|
|
|
-| **backgroundImage** | `string` | `undefined` | 背景图片地址 |
|
|
|
-| **backgroundDimming** | `string` | `"rgba(0,0,0,0)"` | 背景遮罩颜色 |
|
|
|
-| **gifBackgroundURL** | `string` | `undefined` | GIF 背景图片 |
|
|
|
-| **whiteMargin** | `boolean` | `true` | 白色边距 |
|
|
|
-| **autoColor** | `boolean` | `true` | 自动计算浅色 |
|
|
|
-| **dotScale** | `number` | `1` | 定位点缩放 (0-1),越小越精致 |
|
|
|
-| **loadingText** | `string` | `"生成中..."` | 加载提示文本 |
|
|
|
-| **errorText** | `string` | `"生成失败"` | 错误提示文本 |
|
|
|
-
|
|
|
-**纠错等级说明:**
|
|
|
-- `0` = L (7% 容错)
|
|
|
-- `1` = M (15% 容错) ⭐ 推荐
|
|
|
-- `2` = Q (25% 容错)
|
|
|
-- `3` = H (30% 容错)
|
|
|
-
|
|
|
-**dotScale 效果:**
|
|
|
-- `0.2` - 超精致定位点
|
|
|
-- `0.35` - 精致定位点 ⭐ 推荐
|
|
|
-- `0.5` - 适中
|
|
|
-- `0.8` - 传统风格
|
|
|
-- `1.0` - 默认大小
|
|
|
-
|
|
|
----
|
|
|
-
|
|
|
-### Events
|
|
|
-
|
|
|
-| 事件名 | 参数 | 触发时机 |
|
|
|
-| --------------------- | ----------------------------------------------- | -------------- |
|
|
|
-| **update:modelValue** | `(value: string)` | v-model 更新时 |
|
|
|
-| **success** | `(dataURL: ArrayBuffer \| string \| undefined)` | 二维码生成成功 |
|
|
|
-| **error** | `(error: unknown)` | 二维码生成失败 |
|
|
|
-
|
|
|
----
|
|
|
-
|
|
|
-### Exposed Methods
|
|
|
-
|
|
|
-通过 `ref` 访问的方法:
|
|
|
-
|
|
|
-```typescript
|
|
|
-interface VbQrGenExposed {
|
|
|
- // ✅ 核心方法 - 返回 Promise
|
|
|
- generateQRCode(options?: QRCodeGenerateOptions): Promise<ArrayBuffer | string | undefined>
|
|
|
- clearQRCode(): void
|
|
|
- downloadQRCode(fileName?: string): Promise<void>
|
|
|
- printQRCode(title?: string): Promise<void>
|
|
|
- getQRCodeDataURL(): string | null
|
|
|
-
|
|
|
- // ✅ 状态获取
|
|
|
- getQRCodeState(): {
|
|
|
- url: string | ArrayBuffer | undefined
|
|
|
- loading: boolean
|
|
|
- error: unknown
|
|
|
- }
|
|
|
-}
|
|
|
-```
|
|
|
-
|
|
|
-#### generateQRCode(options?)
|
|
|
-
|
|
|
-生成二维码。
|
|
|
-
|
|
|
-**参数:**
|
|
|
-```typescript
|
|
|
-interface QRCodeGenerateOptions {
|
|
|
- text?: string // 文本内容(可选,默认使用 modelValue)
|
|
|
- size?: number // 尺寸
|
|
|
- margin?: number // 边距
|
|
|
- correctLevel?: 0 | 1 | 2 | 3 // 纠错等级
|
|
|
- maskPattern?: number // 掩码图案 (0-7)
|
|
|
- version?: number // 版本 (1-40)
|
|
|
- colorDark?: string // 深色
|
|
|
- colorLight?: string // 浅色
|
|
|
- autoColor?: boolean // 自动计算浅色
|
|
|
- logoImage?: string // Logo
|
|
|
- logoScale?: number // Logo 比例
|
|
|
- logoMargin?: number // Logo 边距
|
|
|
- logoCornerRadius?: number // Logo 圆角
|
|
|
- backgroundImage?: string // 背景图
|
|
|
- backgroundDimming?: string // 背景遮罩
|
|
|
- gifBackgroundURL?: string // GIF 背景
|
|
|
- whiteMargin?: boolean // 白色边距
|
|
|
- dotScale?: number // 定位点缩放
|
|
|
-}
|
|
|
-```
|
|
|
-
|
|
|
-**返回值:** `Promise<dataURL>`
|
|
|
-
|
|
|
-**示例:**
|
|
|
-```typescript
|
|
|
-// 基础用法 - 使用 modelValue
|
|
|
-qrRef.value?.generateQRCode()
|
|
|
-
|
|
|
-// 自定义配置
|
|
|
-qrRef.value?.generateQRCode({
|
|
|
- text: 'https://example.com',
|
|
|
- size: 300,
|
|
|
- colorDark: '#1677ff',
|
|
|
- dotScale: 0.35
|
|
|
-})
|
|
|
-
|
|
|
-// 链式调用
|
|
|
-qrRef.value?.generateQRCode()
|
|
|
- .then((dataURL) => console.log('成功', dataURL))
|
|
|
- .catch((error) => console.error('失败', error))
|
|
|
-```
|
|
|
-
|
|
|
----
|
|
|
-
|
|
|
-#### clearQRCode()
|
|
|
-
|
|
|
-清除当前二维码。
|
|
|
-
|
|
|
-**示例:**
|
|
|
-```typescript
|
|
|
-qrRef.value?.clearQRCode()
|
|
|
-```
|
|
|
-
|
|
|
----
|
|
|
-
|
|
|
-#### downloadQRCode(fileName?)
|
|
|
-
|
|
|
-下载二维码为 PNG 图片。
|
|
|
-
|
|
|
-**参数:**
|
|
|
-- `fileName`: 文件名(不含扩展名),默认 `"qrcode"`
|
|
|
-
|
|
|
-**返回值:** `Promise<void>`
|
|
|
-
|
|
|
-**示例:**
|
|
|
-```typescript
|
|
|
-qrRef.value?.downloadQRCode('my-qrcode')
|
|
|
- .then(() => console.log('下载成功'))
|
|
|
- .catch((error) => console.error('下载失败', error))
|
|
|
-```
|
|
|
-
|
|
|
----
|
|
|
-
|
|
|
-#### printQRCode(title?)
|
|
|
-
|
|
|
-打印二维码(打开打印窗口)。
|
|
|
-
|
|
|
-**参数:**
|
|
|
-- `title`: 打印标题,默认使用组件的 `title` prop 或 `"二维码"`
|
|
|
-
|
|
|
-**返回值:** `Promise<void>`
|
|
|
-
|
|
|
-**示例:**
|
|
|
-```typescript
|
|
|
-qrRef.value?.printQRCode('产品二维码')
|
|
|
- .then(() => console.log('打印窗口已打开'))
|
|
|
- .catch((error) => console.error('打印失败', error))
|
|
|
-```
|
|
|
-
|
|
|
----
|
|
|
-
|
|
|
-#### getQRCodeDataURL()
|
|
|
-
|
|
|
-获取二维码的 Data URL。
|
|
|
-
|
|
|
-**返回值:** `string | null`
|
|
|
-
|
|
|
-**示例:**
|
|
|
-```typescript
|
|
|
-const dataURL = qrRef.value?.getQRCodeDataURL()
|
|
|
-if (dataURL) {
|
|
|
- console.log('Data URL:', dataURL.substring(0, 50) + '...')
|
|
|
-}
|
|
|
-```
|
|
|
-
|
|
|
----
|
|
|
-
|
|
|
-#### getQRCodeState()
|
|
|
-
|
|
|
-获取二维码当前状态。
|
|
|
-
|
|
|
-**返回值:**
|
|
|
-```typescript
|
|
|
-{
|
|
|
- url: string | ArrayBuffer | undefined // 二维码数据
|
|
|
- loading: boolean // 是否正在生成
|
|
|
- error: unknown // 错误信息
|
|
|
-}
|
|
|
-```
|
|
|
-
|
|
|
-**示例:**
|
|
|
-```typescript
|
|
|
-const state = qrRef.value?.getQRCodeState()
|
|
|
-console.log('加载状态:', state.loading)
|
|
|
-console.log('错误信息:', state.error)
|
|
|
-```
|
|
|
-
|
|
|
----
|
|
|
-
|
|
|
-### Slots
|
|
|
-
|
|
|
-| 插槽名 | 作用域参数 | 说明 |
|
|
|
-| ----------- | --------------------- | ---------------- |
|
|
|
-| **title** | - | 自定义标题 |
|
|
|
-| **qrcode** | `{ qrcodeURL, size }` | 自定义二维码显示 |
|
|
|
-| **loading** | - | 自定义加载状态 |
|
|
|
-| **error** | `{ error }` | 自定义错误状态 |
|
|
|
-
|
|
|
-**示例:**
|
|
|
-```vue
|
|
|
-<VbQrGen v-model="text">
|
|
|
- <!-- 自定义标题 -->
|
|
|
- <template #title>
|
|
|
- <h2 style="color: blue">自定义标题</h2>
|
|
|
- </template>
|
|
|
-
|
|
|
- <!-- 自定义二维码显示 -->
|
|
|
- <template #qrcode="{ qrcodeURL, size }">
|
|
|
- <img :src="qrcodeURL" :style="{ width: size + 'px' }" />
|
|
|
- </template>
|
|
|
-
|
|
|
- <!-- 自定义加载状态 -->
|
|
|
- <template #loading>
|
|
|
- <div class="custom-loading">加载中...</div>
|
|
|
- </template>
|
|
|
-
|
|
|
- <!-- 自定义错误状态 -->
|
|
|
- <template #error="{ error }">
|
|
|
- <div class="custom-error">生成失败: {{ error }}</div>
|
|
|
- </template>
|
|
|
-</VbQrGen>
|
|
|
-```
|
|
|
-
|
|
|
----
|
|
|
-
|
|
|
-## 📦 VbQrMulti - 批量二维码组件
|
|
|
-
|
|
|
-### 基础用法
|
|
|
-
|
|
|
-```vue
|
|
|
-<template>
|
|
|
- <VbQrMulti
|
|
|
- ref="multiRef"
|
|
|
- v-model:items="qrItems"
|
|
|
- :columns="4"
|
|
|
- @generate-all-complete="handleComplete"
|
|
|
- />
|
|
|
- <el-button @click="generateAll">批量生成</el-button>
|
|
|
-</template>
|
|
|
-
|
|
|
-<script setup lang="ts">
|
|
|
-import { ref } from 'vue'
|
|
|
-import VbQrMulti from '@/components/qrcode/VbQrMulti.vue'
|
|
|
-import type { QRCodeItem } from '@/components/qrcode/VbQrMulti.vue'
|
|
|
-
|
|
|
-const multiRef = ref<InstanceType<typeof VbQrMulti>>()
|
|
|
-const qrItems = ref<QRCodeItem[]>([
|
|
|
- { id: '1', text: 'https://a.com', title: '产品 A' },
|
|
|
- { id: '2', text: 'https://b.com', title: '产品 B' }
|
|
|
-])
|
|
|
-
|
|
|
-function generateAll() {
|
|
|
- multiRef.value?.generateAll()
|
|
|
- .then((result) => {
|
|
|
- console.log(`成功: ${result.success}, 失败: ${result.fail}`)
|
|
|
- })
|
|
|
-}
|
|
|
-
|
|
|
-function handleComplete(result: { success: number; fail: number }) {
|
|
|
- console.log('批量生成完成', result)
|
|
|
-}
|
|
|
-</script>
|
|
|
-```
|
|
|
-
|
|
|
----
|
|
|
-
|
|
|
-### QRCodeItem 类型
|
|
|
-
|
|
|
-```typescript
|
|
|
-interface QRCodeItem {
|
|
|
- id: string // 唯一标识
|
|
|
- text: string // 二维码文本
|
|
|
- title?: string // 标题(可选)
|
|
|
- options?: QRCodeGenerateOptions // 自定义配置(可选)
|
|
|
-}
|
|
|
-```
|
|
|
-
|
|
|
----
|
|
|
-
|
|
|
-### Props
|
|
|
-
|
|
|
-| 属性 | 类型 | 默认值 | 说明 |
|
|
|
-| --------------------- | -------------------- | ----------- | --------------------- |
|
|
|
-| **items** | `QRCodeItem[]` | `[]` | 二维码列表(v-model) |
|
|
|
-| **size** | `number` | `150` | 默认尺寸 |
|
|
|
-| **margin** | `number` | `10` | 默认边距 |
|
|
|
-| **dotScale** | `number` | `0.35` | 默认定位点缩放 |
|
|
|
-| **colorDark** | `string` | `undefined` | 默认深色 |
|
|
|
-| **colorLight** | `string` | `undefined` | 默认浅色 |
|
|
|
-| **correctLevel** | `0 \| 1 \| 2 \| 3` | `undefined` | 默认纠错等级 |
|
|
|
-| **logoImage** | `string` | `undefined` | 默认 Logo |
|
|
|
-| **logoScale** | `number` | `undefined` | 默认 Logo 比例 |
|
|
|
-| **logoMargin** | `number` | `undefined` | 默认 Logo 边距 |
|
|
|
-| **logoCornerRadius** | `number` | `undefined` | 默认 Logo 圆角 |
|
|
|
-| **backgroundImage** | `string` | `undefined` | 默认背景图 |
|
|
|
-| **backgroundDimming** | `string` | `undefined` | 默认背景遮罩 |
|
|
|
-| **gifBackgroundURL** | `string` | `undefined` | 默认 GIF 背景 |
|
|
|
-| **whiteMargin** | `boolean` | `undefined` | 默认白色边距 |
|
|
|
-| **autoColor** | `boolean` | `undefined` | 默认自动计算浅色 |
|
|
|
-| **maskPattern** | `number` | `undefined` | 默认掩码图案 |
|
|
|
-| **version** | `number` | `undefined` | 默认版本 |
|
|
|
-| **layout** | `"grid" \| "list"` | `"grid"` | 布局方式 |
|
|
|
-| **columns** | `number` | `5` | 网格列数 |
|
|
|
-| **title** | `string \| function` | `undefined` | 标题或标题生成函数 |
|
|
|
-| **showItemActions** | `boolean` | `true` | 显示单项操作按钮 |
|
|
|
-| **concurrency** | `number` | `50` | 批量生成并发数 |
|
|
|
-| **autoGenerate** | `boolean` | `true` | 自动生成开关 |
|
|
|
-
|
|
|
-**title 函数签名:**
|
|
|
-```typescript
|
|
|
-title?: (item: QRCodeItem, index: number) => string
|
|
|
-```
|
|
|
-
|
|
|
-**配置优先级:**
|
|
|
-1. `item.options` 中的配置(最高优先级)
|
|
|
-2. Props 中的默认配置
|
|
|
-3. 组件内部默认值
|
|
|
-
|
|
|
----
|
|
|
-
|
|
|
-### Events
|
|
|
-
|
|
|
-| 事件名 | 参数 | 触发时机 |
|
|
|
-| ------------------------- | ----------------------- | -------------- |
|
|
|
-| **update:items** | `(items: QRCodeItem[])` | 列表变化时 |
|
|
|
-| **add** | `(item: QRCodeItem)` | 添加二维码 |
|
|
|
-| **remove** | `(id: string)` | 删除二维码 |
|
|
|
-| **generate** | `(item: QRCodeItem)` | 生成单个二维码 |
|
|
|
-| **clear** | `(id: string)` | 清除二维码 |
|
|
|
-| **generate-all-complete** | `({ success, fail })` | ✅ 批量生成完成 |
|
|
|
-| **download-all-complete** | `(count: number)` | ✅ 批量下载完成 |
|
|
|
-| **print-all-complete** | `(count: number)` | ✅ 批量打印完成 |
|
|
|
-
|
|
|
----
|
|
|
-
|
|
|
-### Exposed Methods
|
|
|
-
|
|
|
-```typescript
|
|
|
-interface VbQrMultiExposed {
|
|
|
- // 数据
|
|
|
- qrList: Ref<QRCodeItem[]>
|
|
|
-
|
|
|
- // 管理方法
|
|
|
- addQRCode(item?: Partial<QRCodeItem>): void
|
|
|
- removeQRCode(id: string): void
|
|
|
- clearAll(): void
|
|
|
-
|
|
|
- // 单个操作
|
|
|
- generateOne(item: QRCodeItem): void
|
|
|
- downloadOne(item: QRCodeItem, index: number): void
|
|
|
- printOne(item: QRCodeItem, index: number): void
|
|
|
-
|
|
|
- // 批量操作 - 返回 Promise
|
|
|
- generateAll(): Promise<{ success: number; fail: number }>
|
|
|
- downloadAll(): Promise<void>
|
|
|
- printAll(): Promise<void>
|
|
|
-
|
|
|
- // 获取子组件引用
|
|
|
- getQRRef(id: string): InstanceType<typeof VbQrGen> | undefined
|
|
|
-}
|
|
|
-```
|
|
|
-
|
|
|
-#### addQRCode(item?)
|
|
|
-
|
|
|
-添加新二维码。
|
|
|
-
|
|
|
-**参数:**
|
|
|
-```typescript
|
|
|
-{
|
|
|
- id?: string // 可选,自动生成
|
|
|
- text?: string // 文本内容
|
|
|
- title?: string // 标题
|
|
|
- options?: QRCodeGenerateOptions // 自定义配置
|
|
|
-}
|
|
|
-```
|
|
|
-
|
|
|
-**示例:**
|
|
|
-```typescript
|
|
|
-multiRef.value?.addQRCode({
|
|
|
- text: 'https://example.com',
|
|
|
- title: '新产品',
|
|
|
- options: {
|
|
|
- size: 200,
|
|
|
- colorDark: '#1677ff'
|
|
|
- }
|
|
|
-})
|
|
|
-```
|
|
|
-
|
|
|
----
|
|
|
-
|
|
|
-#### removeQRCode(id)
|
|
|
-
|
|
|
-删除指定二维码。
|
|
|
-
|
|
|
-**参数:**
|
|
|
-- `id`: 二维码 ID
|
|
|
-
|
|
|
-**示例:**
|
|
|
-```typescript
|
|
|
-multiRef.value?.removeQRCode('qr_123')
|
|
|
-```
|
|
|
-
|
|
|
----
|
|
|
-
|
|
|
-#### generateOne(item)
|
|
|
-
|
|
|
-生成单个二维码。
|
|
|
-
|
|
|
-**参数:**
|
|
|
-- `item`: QRCodeItem 对象
|
|
|
-
|
|
|
-**示例:**
|
|
|
-```typescript
|
|
|
-const item = qrItems.value[0]
|
|
|
-multiRef.value?.generateOne(item)
|
|
|
-```
|
|
|
-
|
|
|
----
|
|
|
-
|
|
|
-#### downloadOne(item, index)
|
|
|
-
|
|
|
-下载单个二维码。
|
|
|
-
|
|
|
-**参数:**
|
|
|
-- `item`: QRCodeItem 对象
|
|
|
-- `index`: 索引(用于生成文件名)
|
|
|
-
|
|
|
-**示例:**
|
|
|
-```typescript
|
|
|
-multiRef.value?.downloadOne(qrItems.value[0], 0)
|
|
|
-```
|
|
|
-
|
|
|
----
|
|
|
-
|
|
|
-#### printOne(item, index)
|
|
|
-
|
|
|
-打印单个二维码。
|
|
|
-
|
|
|
-**参数:**
|
|
|
-- `item`: QRCodeItem 对象
|
|
|
-- `index`: 索引(用于生成标题)
|
|
|
-
|
|
|
-**示例:**
|
|
|
-```typescript
|
|
|
-multiRef.value?.printOne(qrItems.value[0], 0)
|
|
|
-```
|
|
|
-
|
|
|
----
|
|
|
-
|
|
|
-#### generateAll()
|
|
|
-
|
|
|
-批量生成所有二维码(并发处理)。
|
|
|
-
|
|
|
-**返回值:** `Promise<{ success: number; fail: number }>`
|
|
|
-
|
|
|
-**示例:**
|
|
|
-```typescript
|
|
|
-multiRef.value?.generateAll()
|
|
|
- .then((result) => {
|
|
|
- console.log(`成功: ${result.success}, 失败: ${result.fail}`)
|
|
|
- })
|
|
|
- .catch((error) => {
|
|
|
- console.error('批量生成出错', error)
|
|
|
- })
|
|
|
-```
|
|
|
-
|
|
|
-**性能参考(100个二维码):**
|
|
|
-- 并发 50:约 5-10 秒
|
|
|
-- 并发 100:约 3-5 秒
|
|
|
-- 并发 200:约 2-3 秒
|
|
|
-
|
|
|
----
|
|
|
-
|
|
|
-#### downloadAll()
|
|
|
-
|
|
|
-批量下载所有二维码(合并为一张图片)。
|
|
|
-
|
|
|
-**返回值:** `Promise<void>`
|
|
|
-
|
|
|
-**示例:**
|
|
|
-```typescript
|
|
|
-multiRef.value?.downloadAll()
|
|
|
- .then(() => console.log('批量下载完成'))
|
|
|
- .catch((error) => console.error('下载失败', error))
|
|
|
-```
|
|
|
-
|
|
|
----
|
|
|
-
|
|
|
-#### printAll()
|
|
|
-
|
|
|
-批量打印所有二维码(合并在一个页面)。
|
|
|
-
|
|
|
-**返回值:** `Promise<void>`
|
|
|
-
|
|
|
-**示例:**
|
|
|
-```typescript
|
|
|
-multiRef.value?.printAll()
|
|
|
- .then(() => console.log('批量打印完成'))
|
|
|
- .catch((error) => console.error('打印失败', error))
|
|
|
-```
|
|
|
-
|
|
|
----
|
|
|
-
|
|
|
-#### clearAll()
|
|
|
-
|
|
|
-清空所有二维码(不清除列表,只清除生成的图片)。
|
|
|
-
|
|
|
-**示例:**
|
|
|
-```typescript
|
|
|
-multiRef.value?.clearAll()
|
|
|
-```
|
|
|
-
|
|
|
----
|
|
|
-
|
|
|
-#### getQRRef(id)
|
|
|
-
|
|
|
-获取指定二维码的子组件引用。
|
|
|
-
|
|
|
-**参数:**
|
|
|
-- `id`: 二维码 ID
|
|
|
-
|
|
|
-**返回值:** `InstanceType<typeof VbQrGen> | undefined`
|
|
|
-
|
|
|
-**示例:**
|
|
|
-```typescript
|
|
|
-const qrRef = multiRef.value?.getQRRef('qr_123')
|
|
|
-if (qrRef) {
|
|
|
- qrRef.downloadQRCode('custom-name')
|
|
|
-}
|
|
|
-```
|
|
|
-
|
|
|
----
|
|
|
-
|
|
|
-### Slots
|
|
|
-
|
|
|
-| 插槽名 | 作用域参数 | 说明 |
|
|
|
-| --------- | ----------------------------------------------------------- | ---------------- |
|
|
|
-| **item** | `{ item, index, title, generate, download, print, remove }` | 自定义二维码卡片 |
|
|
|
-| **empty** | - | 自定义空状态 |
|
|
|
-
|
|
|
-**item 插槽参数详解:**
|
|
|
-```typescript
|
|
|
-{
|
|
|
- item: QRCodeItem // 当前项数据
|
|
|
- index: number // 索引
|
|
|
- title: string // 计算后的标题
|
|
|
- generate: () => void // 生成函数
|
|
|
- download: () => void // 下载函数
|
|
|
- print: () => void // 打印函数
|
|
|
- remove: () => void // 删除函数
|
|
|
-}
|
|
|
-```
|
|
|
-
|
|
|
-**示例:**
|
|
|
-```vue
|
|
|
-<VbQrMulti v-model:items="items">
|
|
|
- <template #item="{ item, index, title, generate, download, print, remove }">
|
|
|
- <div class="custom-card">
|
|
|
- <div class="card-header">
|
|
|
- <h3>{{ title }}</h3>
|
|
|
- <el-button size="small" @click="remove">删除</el-button>
|
|
|
- </div>
|
|
|
-
|
|
|
- <VbQrGen
|
|
|
- :ref="(el) => setQRRef(item.id, el)"
|
|
|
- v-model="item.text"
|
|
|
- :title="title"
|
|
|
- />
|
|
|
-
|
|
|
- <div class="card-footer">
|
|
|
- <el-button size="small" @click="generate">生成</el-button>
|
|
|
- <el-button size="small" @click="download">下载</el-button>
|
|
|
- <el-button size="small" @click="print">打印</el-button>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </template>
|
|
|
-
|
|
|
- <template #empty>
|
|
|
- <div class="empty-state">
|
|
|
- <p>暂无二维码</p>
|
|
|
- <el-button @click="addFirst">添加第一个</el-button>
|
|
|
- </div>
|
|
|
- </template>
|
|
|
-</VbQrMulti>
|
|
|
-```
|
|
|
-
|
|
|
----
|
|
|
-
|
|
|
-## 🎯 常见场景
|
|
|
-
|
|
|
-### 1. 模态框中使用
|
|
|
-
|
|
|
-```vue
|
|
|
-<template>
|
|
|
- <el-dialog v-model="visible" title="二维码">
|
|
|
- <VbQrGen
|
|
|
- ref="qrRef"
|
|
|
- :model-value="currentURL"
|
|
|
- :size="300"
|
|
|
- />
|
|
|
- <template #footer>
|
|
|
- <el-button @click="download">下载</el-button>
|
|
|
- <el-button @click="print">打印</el-button>
|
|
|
- </template>
|
|
|
- </el-dialog>
|
|
|
-</template>
|
|
|
-
|
|
|
-<script setup lang="ts">
|
|
|
-import { ref, watch } from 'vue'
|
|
|
-
|
|
|
-const visible = ref(false)
|
|
|
-const currentURL = ref('')
|
|
|
-const qrRef = ref()
|
|
|
-
|
|
|
-// 对话框打开时生成
|
|
|
-watch(visible, (val) => {
|
|
|
- if (val && currentURL.value) {
|
|
|
- setTimeout(() => {
|
|
|
- qrRef.value?.generateQRCode()
|
|
|
- }, 100)
|
|
|
- }
|
|
|
-})
|
|
|
-
|
|
|
-function download() {
|
|
|
- qrRef.value?.downloadQRCode('qrcode')
|
|
|
-}
|
|
|
-
|
|
|
-function print() {
|
|
|
- qrRef.value?.printQRCode('二维码')
|
|
|
-}
|
|
|
-</script>
|
|
|
-```
|
|
|
-
|
|
|
----
|
|
|
-
|
|
|
-### 2. 带 Logo 的二维码
|
|
|
-
|
|
|
-```vue
|
|
|
-<VbQrGen
|
|
|
- v-model="text"
|
|
|
- logo-image="/logo.png"
|
|
|
- :logo-scale="0.3"
|
|
|
- :logo-margin="8"
|
|
|
- :logo-corner-radius="10"
|
|
|
-/>
|
|
|
-```
|
|
|
-
|
|
|
----
|
|
|
-
|
|
|
-### 3. 动态标题
|
|
|
-
|
|
|
-```vue
|
|
|
-<VbQrMulti
|
|
|
- v-model:items="items"
|
|
|
- :title="(item, index) => {
|
|
|
- // 优先使用 item.title
|
|
|
- if (item.title) return item.title
|
|
|
-
|
|
|
- // 否则从 URL 提取域名
|
|
|
- try {
|
|
|
- const url = new URL(item.text)
|
|
|
- return url.hostname
|
|
|
- } catch {
|
|
|
- return `二维码 ${index + 1}`
|
|
|
- }
|
|
|
- }}"
|
|
|
-/>
|
|
|
-```
|
|
|
-
|
|
|
----
|
|
|
-
|
|
|
-### 4. 大量数据优化
|
|
|
-
|
|
|
-```vue
|
|
|
-<template>
|
|
|
- <!-- 关闭自动生成,手动控制 -->
|
|
|
- <VbQrMulti
|
|
|
- ref="multiRef"
|
|
|
- v-model:items="items"
|
|
|
- :auto-generate="false"
|
|
|
- :concurrency="30"
|
|
|
- />
|
|
|
- <el-button @click="manualGenerate">手动生成</el-button>
|
|
|
-</template>
|
|
|
-
|
|
|
-<script setup lang="ts">
|
|
|
-import { ref, onMounted } from 'vue'
|
|
|
-
|
|
|
-const multiRef = ref()
|
|
|
-const items = ref([...]) // 大量数据
|
|
|
-
|
|
|
-onMounted(() => {
|
|
|
- // 等待 DOM 渲染后手动生成
|
|
|
- setTimeout(() => {
|
|
|
- multiRef.value?.generateAll()
|
|
|
- }, 100)
|
|
|
-})
|
|
|
-
|
|
|
-function manualGenerate() {
|
|
|
- multiRef.value?.generateAll()
|
|
|
- .then((result) => {
|
|
|
- console.log(`生成完成: ${result.success}/${result.fail}`)
|
|
|
- })
|
|
|
-}
|
|
|
-</script>
|
|
|
-```
|
|
|
-
|
|
|
----
|
|
|
-
|
|
|
-### 5. 导出为 PDF
|
|
|
-
|
|
|
-```vue
|
|
|
-<script setup lang="ts">
|
|
|
-import jsPDF from 'jspdf'
|
|
|
-
|
|
|
-async function exportToPDF() {
|
|
|
- // 先生成所有二维码
|
|
|
- await multiRef.value?.generateAll()
|
|
|
-
|
|
|
- const pdf = new jsPDF()
|
|
|
- let y = 20
|
|
|
-
|
|
|
- // 遍历所有二维码
|
|
|
- for (let i = 0; i < items.value.length; i++) {
|
|
|
- const qrRef = multiRef.value?.getQRRef(items.value[i].id)
|
|
|
- const dataURL = qrRef?.getQRCodeDataURL()
|
|
|
-
|
|
|
- if (dataURL) {
|
|
|
- pdf.addImage(dataURL, 'PNG', 20, y, 50, 50)
|
|
|
- pdf.text(items.value[i].title || `二维码 ${i + 1}`, 80, y + 25)
|
|
|
- y += 60
|
|
|
-
|
|
|
- if (y > 250) {
|
|
|
- pdf.addPage()
|
|
|
- y = 20
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- pdf.save('qrcodes.pdf')
|
|
|
-}
|
|
|
-</script>
|
|
|
-```
|
|
|
-
|
|
|
----
|
|
|
-
|
|
|
-## ⚠️ 注意事项
|
|
|
-
|
|
|
-### 异步处理
|
|
|
-
|
|
|
-✅ **推荐** - 使用 Promise 链:
|
|
|
-```typescript
|
|
|
-qrRef.value?.generateQRCode()
|
|
|
- .then((dataURL) => console.log('成功', dataURL))
|
|
|
- .catch((error) => console.error('失败', error))
|
|
|
-```
|
|
|
-
|
|
|
-⚠️ **可用但不推荐** - async/await:
|
|
|
-```typescript
|
|
|
-async function handleGenerate() {
|
|
|
- try {
|
|
|
- const dataURL = await qrRef.value?.generateQRCode()
|
|
|
- console.log('成功', dataURL)
|
|
|
- } catch (error) {
|
|
|
- console.error('失败', error)
|
|
|
- }
|
|
|
-}
|
|
|
-```
|
|
|
-
|
|
|
----
|
|
|
-
|
|
|
-### 状态访问
|
|
|
-
|
|
|
-❌ **错误** - 直接访问内部状态:
|
|
|
-```typescript
|
|
|
-const url = qrRef.value?.qrcodeURL // ❌ 不存在
|
|
|
-const loading = qrRef.value?.isLoading // ❌ 不存在
|
|
|
-```
|
|
|
-
|
|
|
-✅ **正确** - 使用 getter 方法:
|
|
|
-```typescript
|
|
|
-const state = qrRef.value?.getQRCodeState()
|
|
|
-const url = state?.url
|
|
|
-const loading = state?.loading
|
|
|
-```
|
|
|
-
|
|
|
----
|
|
|
-
|
|
|
-### 性能建议
|
|
|
-
|
|
|
-1. **大量二维码时关闭自动生成**
|
|
|
- ```vue
|
|
|
- <VbQrMulti :auto-generate="false" />
|
|
|
- ```
|
|
|
-
|
|
|
-2. **调整并发数**
|
|
|
- ```vue
|
|
|
- <!-- 根据机器性能调整 -->
|
|
|
- <VbQrMulti :concurrency="30" />
|
|
|
- ```
|
|
|
-
|
|
|
-3. **降低二维码尺寸**
|
|
|
- ```vue
|
|
|
- <VbQrMulti :size="100" />
|
|
|
- ```
|
|
|
-
|
|
|
-4. **使用列表布局**
|
|
|
- ```vue
|
|
|
- <VbQrMulti layout="list" />
|
|
|
- ```
|
|
|
-
|
|
|
----
|
|
|
-
|
|
|
-## 🔧 故障排查
|
|
|
-
|
|
|
-### Q1: 生成失败
|
|
|
-
|
|
|
-**可能原因:**
|
|
|
-- text 为空
|
|
|
-- 文本过长超出容量
|
|
|
-- 网络问题(在线资源)
|
|
|
-
|
|
|
-**解决:**
|
|
|
-```typescript
|
|
|
-qrRef.value?.generateQRCode()
|
|
|
- .catch((error) => {
|
|
|
- console.error('错误:', error)
|
|
|
- // 检查 text
|
|
|
- // 尝试降低 correctLevel
|
|
|
- // 移除 logoImage 测试
|
|
|
- })
|
|
|
-```
|
|
|
-
|
|
|
----
|
|
|
-
|
|
|
-### Q2: 批量生成部分失败
|
|
|
-
|
|
|
-**可能原因:**
|
|
|
-- 并发数过高
|
|
|
-- 某些文本无效
|
|
|
-
|
|
|
-**解决:**
|
|
|
-```vue
|
|
|
-<VbQrMulti
|
|
|
- :concurrency="20"
|
|
|
- @generate-all-complete="handleComplete"
|
|
|
-/>
|
|
|
-
|
|
|
-<script setup>
|
|
|
-function handleComplete(result) {
|
|
|
- console.log(`成功: ${result.success}, 失败: ${result.fail}`)
|
|
|
-}
|
|
|
-</script>
|
|
|
-```
|
|
|
-
|
|
|
----
|
|
|
-
|
|
|
-### Q3: 打印窗口被拦截
|
|
|
-
|
|
|
-**原因:** 浏览器弹窗拦截
|
|
|
-
|
|
|
-**解决:** 确保用户主动触发(点击按钮),避免在异步回调中调用
|
|
|
-
|
|
|
----
|
|
|
-
|
|
|
-## 📚 相关文档
|
|
|
-
|
|
|
-- [README.md](./README.md) - 快速开始指南
|
|
|
-- [OPTIMIZATION_SUMMARY.md](./OPTIMIZATION_SUMMARY.md) - 优化总结
|
|
|
-- [MIGRATION_GUIDE.md](./MIGRATION_GUIDE.md) - 迁移指南
|
|
|
-
|
|
|
----
|
|
|
-
|
|
|
-**最后更新**: 2026-04-13
|