更新记录

1.0.0(2026-10-23) 下载此版本

第一版


平台兼容性

其他

多语言 暗黑模式 宽屏模式 蒸汽模式
× × √ ×

gibbs-qrcode

二维码 / 条形码 的生成与扫码

基于 Canvas 生成二维码或条形码图片,集成 uni.scanCode 扫码能力。插件自动注册,无需手动 import。


快速上手

1. 安装

将 gibbs-qrcode 目录放入项目的 uni_modules 下。

2. 生成二维码(最简用法)

<gibbs-qrcode val="https://www.example.com" :size="260" unit="upx" :loadMake="true" />

3. 保存到相册

this.$refs.qrcode.save()

4. 扫码

<gibbs-qrcode ref="scanner" val="" :size="0"
  @scanSuccess="res => console.log(res.result)"
/>
this.$refs.scanner.scan()

平台兼容性

平台 生成码图 扫码
App (iOS/Android) ✅ ✅
H5 ✅ ❌
微信小程序 ✅ ✅
支付宝小程序 ✅ ✅
百度小程序 ✅ ✅
字节跳动小程序 ✅ ✅
QQ小程序 ✅ ✅

H5 端不支持扫码,调用 scan() 会弹出提示并触发 scanFail 事件。


使用指南

二维码

基础用法

<gibbs-qrcode
  val="https://www.example.com"
  :size="260"
  unit="upx"
  :loadMake="true"
  @result="onResult"
/>
methods: {
  onResult(src) {
    console.log('码图路径:', src)
  }
}

带中心图标

<gibbs-qrcode
  val="https://www.example.com"
  :size="260"
  unit="upx"
  icon="/static/logo.png"
  :iconSize="40"
  :loadMake="true"
/>

自定义颜色

foreground 控制码点颜色,pdground 控制三个定位角点的颜色:

<gibbs-qrcode
  val="https://www.example.com"
  :size="260"
  unit="upx"
  background="#f0f0f0"
  foreground="#333333"
  pdground="#e74c3c"
  :loadMake="true"
/>

容错级别

lv 取值 0(L) / 1(M) / 2(Q) / 3(H),级别越高容错越强但码图越密:

<gibbs-qrcode val="https://www.example.com" :size="260" unit="upx" :lv="3" :loadMake="true" />

条形码

设置 mode="barcode" 即可,此时 icon、iconSize、lv、pdground 无效:

<gibbs-qrcode
  mode="barcode"
  val="6901234567890"
  :size="400"
  unit="upx"
  :loadMake="true"
/>

动态内容

onval 为 true 时,val 变化自动重新生成(内置 100ms 防抖):

<gibbs-qrcode :val="dynamicValue" :size="260" unit="upx" :onval="true" :loadMake="true" />
data() {
  return { dynamicValue: 'https://www.example.com' }
},
methods: {
  changeValue() {
    this.dynamicValue = 'https://www.new-url.com'
  }
}

手动调用

不使用 loadMake 时,需手动调用 make() 生成:

<gibbs-qrcode ref="qrcode" val="https://www.example.com" :size="260" unit="upx" />
this.$refs.qrcode.make()   // 生成码图
this.$refs.qrcode.clear()  // 清除码图
this.$refs.qrcode.save()   // 保存到相册(自动处理权限)

扫码

基础用法

<gibbs-qrcode ref="scanner" val="" :size="0"
  @scanSuccess="onScanSuccess"
  @scanFail="onScanFail"
/>
<button @click="$refs.scanner.scan()">扫码</button>
methods: {
  onScanSuccess(res) {
    console.log('扫码结果:', res.result)
    console.log('码类型:', res.scanType)
  },
  onScanFail(err) {
    console.log('扫码失败:', err)
  }
}

扫码选项

// 仅相机扫码,禁止从相册选择
this.$refs.scanner.scan({ onlyFromCamera: true })

// 仅扫二维码
this.$refs.scanner.scan({ scanType: ['qrCode'] })

// 仅扫条形码
this.$refs.scanner.scan({ scanType: ['barCode'] })

// 自动识别(默认)
this.$refs.scanner.scan({ scanType: ['qrCode', 'barCode'] })

API 参考

Props

参数 说明 类型 默认值 必填
cid canvas-id,多实例时需区分 String 自动生成 否
mode 码类型:qrcode / barcode String 'qrcode' 否
val 码内容 String '' 是
size 码尺寸 Number 200 否
unit 尺寸单位:upx / px / rpx String 'upx' 否
show 是否显示生成的码图 Boolean true 否
background 背景色 String '#ffffff' 否
foreground 前景色(码点颜色) String '#000000' 否
pdground 定位角点颜色(仅二维码) String '#000000' 否
icon 中心图标路径(仅二维码) String '' 否
iconSize 中心图标尺寸(仅二维码) Number 40 否
lv 容错级别(仅二维码):0=L / 1=M / 2=Q / 3=H Number 3 否
onval val 变化时自动重新生成(内置防抖) Boolean false 否
loadMake 组件挂载时自动生成 Boolean false 否
usingComponents 是否在自定义组件中使用 Boolean true 否
showLoading 生成中是否显示 loading Boolean true 否
loadingText loading 提示文字 String '码图生成中' 否

Events

事件名 说明 回调参数
result 码图生成完成 src(图片临时路径)
scanSuccess 扫码成功 { result, scanType, charSet, path, rawData }
scanFail 扫码失败 错误信息
scanComplete 扫码完成(无论成功失败) 结果

Methods

方法名 说明 参数
make() 手动生成码图 -
clear() 清除已生成的码图 -
save() 保存码图到相册(自动处理权限) -
scan(options) 调起扫码 { onlyFromCamera?, scanType?, autoDecodeCharSet? }

scan options

参数 说明 类型 默认值
onlyFromCamera 仅相机扫码,禁止从相册选择 Boolean false
scanType 码类型:qrCode / barCode Array ['qrCode', 'barCode']
autoDecodeCharSet 是否自动解码字符集 Boolean true

完整示例

生成码图页面

<template>
  <view class="page">
    <view class="section">
      <text class="title">码图生成</text>

      <view class="form-item">
        <text>内容:</text>
        <input v-model="formData.val" placeholder="输入码内容" class="input" />
      </view>

      <view class="form-item">
        <text>类型:</text>
        <radio-group @change="onModeChange">
          <radio value="qrcode" :checked="formData.mode === 'qrcode'" /> 二维码
          <radio value="barcode" :checked="formData.mode === 'barcode'" /> 条形码
        </radio-group>
      </view>

      <view class="form-item" v-if="formData.mode === 'qrcode'">
        <text>中心图标:</text>
        <switch :checked="formData.showIcon" @change="formData.showIcon = $event.detail.value" />
      </view>

      <button @click="generate" type="primary">生成</button>
    </view>

    <view class="preview" v-if="showPreview">
      <gibbs-qrcode
        ref="qrcode"
        :mode="formData.mode"
        :val="formData.val"
        :size="260"
        unit="upx"
        :icon="formData.showIcon ? '/static/logo.png' : ''"
        :iconSize="40"
        :lv="3"
        :loadMake="true"
        @result="onResult"
      />
      <view class="btn-group">
        <button size="mini" @click="$refs.qrcode.save()">保存到相册</button>
        <button size="mini" @click="goScan">去扫码验证</button>
      </view>
    </view>
  </view>
</template>

<script>
export default {
  data() {
    return {
      formData: {
        val: 'https://www.example.com',
        mode: 'qrcode',
        showIcon: false
      },
      showPreview: false
    }
  },
  methods: {
    onModeChange(e) {
      this.formData.mode = e.detail.value
      if (e.detail.value === 'barcode') {
        this.formData.val = '6901234567890'
      } else {
        this.formData.val = 'https://www.example.com'
      }
    },
    generate() {
      if (!this.formData.val) {
        uni.showToast({ title: '请输入内容', icon: 'none' })
        return
      }
      this.showPreview = false
      this.$nextTick(() => {
        this.showPreview = true
      })
    },
    onResult(src) {
      console.log('码图已生成:', src)
    },
    goScan() {
      uni.navigateTo({ url: '/pages/demo/qrscan' })
    }
  }
}
</script>

<style scoped>
.page { padding: 30rpx; }
.section { margin-bottom: 40rpx; }
.title { font-size: 36rpx; font-weight: bold; margin-bottom: 20rpx; }
.form-item { margin-bottom: 20rpx; display: flex; align-items: center; }
.input { border: 1px solid #ddd; padding: 10rpx 20rpx; flex: 1; }
.preview { margin-top: 40rpx; display: flex; flex-direction: column; align-items: center; }
.btn-group { margin-top: 20rpx; display: flex; gap: 20rpx; }
</style>

扫码页面

<template>
  <view class="page">
    <view class="section">
      <text class="title">扫码</text>

      <button @click="scanQr" type="primary">扫二维码</button>
      <button @click="scanBar" type="default" style="margin-top: 20rpx;">扫条形码</button>
      <button @click="scanAll" type="default" style="margin-top: 20rpx;">自动识别</button>
    </view>

    <view class="result" v-if="scanResult">
      <text class="result-title">扫码结果</text>
      <view class="result-item">
        <text class="label">类型:</text>
        <text>{{ scanResult.scanType }}</text>
      </view>
      <view class="result-item">
        <text class="label">内容:</text>
        <text selectable>{{ scanResult.result }}</text>
      </view>
      <view class="result-item" v-if="scanResult.charSet">
        <text class="label">字符集:</text>
        <text>{{ scanResult.charSet }}</text>
      </view>
    </view>

    <gibbs-qrcode
      ref="scanner"
      val=""
      :size="0"
      @scanSuccess="onScanSuccess"
      @scanFail="onScanFail"
    />
  </view>
</template>

<script>
export default {
  data() {
    return { scanResult: null }
  },
  methods: {
    scanQr() {
      this.$refs.scanner.scan({ scanType: ['qrCode'], onlyFromCamera: true })
    },
    scanBar() {
      this.$refs.scanner.scan({ scanType: ['barCode'], onlyFromCamera: true })
    },
    scanAll() {
      this.$refs.scanner.scan({ scanType: ['qrCode', 'barCode'] })
    },
    onScanSuccess(res) {
      this.scanResult = res
      uni.showToast({ title: '扫码成功', icon: 'success' })
    },
    onScanFail(err) {
      console.log('扫码失败:', err)
      uni.showToast({ title: '扫码取消或失败', icon: 'none' })
    }
  }
}
</script>

<style scoped>
.page { padding: 30rpx; }
.section { margin-bottom: 40rpx; }
.title { font-size: 36rpx; font-weight: bold; margin-bottom: 20rpx; }
.result { margin-top: 40rpx; background: #f8f8f8; border-radius: 12rpx; padding: 30rpx; }
.result-title { font-size: 32rpx; font-weight: bold; margin-bottom: 20rpx; }
.result-item { margin-bottom: 16rpx; display: flex; }
.label { color: #999; width: 140rpx; }
</style>

需在 pages.json 中注册页面路由:

{ "path": "pages/demo/qrscan", "style": { "navigationBarTitleText": "扫码" } }

隐私、权限声明

1. 本插件需要申请的系统权限列表:

无

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

无

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

无

许可协议

MIT协议