This commit is contained in:
2026-09-24 16:25:22 +08:00
commit 7428184f01
1198 changed files with 314515 additions and 0 deletions
@@ -0,0 +1,361 @@
<script lang="ts">
import { type PropType } from "vue"
import { getUid, rpx2px } from "../../core/util/xCoreUtil.uts"
import { getDefaultColor } from "../../core/util/xCoreColorUtil.uts"
import { checkIsCssUnit } from "../../core/util/xCoreUtil.uts"
import { xConfig } from "../../config/xConfig.uts"
import {drawQrcode} from "./drawQrcoder.uts"
import {XQrcoderProps} from "./interface.uts"
import { toPngFile } from "@/uni_modules/x-base642file-s"
type DATATYP = {
action : string
}
/**
* @name 二维码 xQrcoder
* @description 本组件使用UTS原生代码绘制,性能非常高,如果你是在1.1.9之前版本请使用x-qrcoder-s原生插件获得高性能。从1.1.9版本后请
* 使用组件绘制QR码来获得更高性能和更多样式配置。
* @page /pages/index/qrcoder
* @category 其它组件
* @constant 平台兼容
* | Harmony | H5 | andriod | IOS | 小程序 | UTS | UNIAPP-X SDK | version |
| --- | --- | --- | --- | --- | --- | --- | --- |
| ☑ | ☑ | ☑️ | ☑️ | ☑️ | ☑️ | 4.76+ | 1.1.18 |
*/
export default {
data() {
return {
id: ("xQrcode-" + getUid()) as string,
id2: ("xQrcode1" + getUid()) as string,
isLoaded: false,
tid2: 0
}
},
props: {
/**
* 窗口宽
*/
width: {
type: String,
default: '250px'
},
/**
* 宽器高,这将影响条码的高度
*/
height: {
type: String,
default: '250px'
},
/**
* 码颜色
*/
color: {
type: String,
default: "primary"
},
/**
* 码背景颜色
*/
bgColor: {
type: String,
default: "white"
},
/**
* 码的定位点颜色,不填写和原前景一致
*/
posColor: {
type: String,
default: ""
},
/**
* 条码内容
*/
text: {
type: String,
default: "https://xui.tmui.design"
},
/**
* 是否绘制Logo到qr上。
*/
logo: {
type: String,
default: ""
},
/**
* 是否绘制Logo到qr上。
*/
logoBgColor: {
type: String,
default: "#fff"
},
/**
* logo大小。
*/
logoSize: {
type: String,
default: "50px"
},
/**
* 边距
*/
padding:{
type: Number,
default: 2
},
/**
* 绘制的样式目前提供
* rect :普通码矩形
* circular :小圆点
* line :线条
* rectSmall :小方格
* xing :星形
* vertical :竖圆形
*/
mode:{
type: String,
default: "rect"
},
/**
* 定位位点是否使用圆角。
*/
pdRounded:{
type:Boolean,
default:false
},
/**
* 生成自动连接的wifi码,手机原生相机扫码时,可以根据你设置帐号密码自动连接你的wifi.
* 包含的字段:ssid:wifi名称,auth:授权方式(NONEWPAWEP)的一种,password:密码,hidden:是否隐藏密码,字符串'true'/'false'
*/
wifi:{
type:Object as PropType<UTSJSONObject>,
default:():UTSJSONObject => ({} as UTSJSONObject)
}
},
computed: {
_width() : number {
let p = parseInt(this.width);
if (this.width.lastIndexOf('rpx') > -1 || this.width.lastIndexOf('px') == -1) {
p = rpx2px(p);
}
return Math.floor(p)
},
_height() : number {
let p = parseInt(this.height);
if (this.height.lastIndexOf('rpx') > -1 || this.height.lastIndexOf('px') == -1) {
p = rpx2px(p);
}
return Math.floor(p)
},
_color() : string {
return getDefaultColor(this.color);
},
_bgColor() : string {
return getDefaultColor(this.bgColor);
},
_posColor() : string {
if(this.posColor=='') return this._color
return getDefaultColor(this.posColor);
},
_text() : string {
let wifisize = this.wifi.toMap().size
if(wifisize>0){
return `WIFI:T:${this.wifi['auth']??''};S:${this.wifi['ssid']??''};P:${this.wifi['password']??''};H:${this.wifi['hidden']??'true'};`
}
return this.text;
},
_logo() : string {
return this.logo;
},
_logoBgColor() : string {
return this.logoBgColor;
},
_padding() : number {
return this.padding;
},
_logoSize() : number {
let p = parseInt(this.logoSize);
if (this.logoSize.lastIndexOf('rpx') > -1 || this.logoSize.lastIndexOf('px') == -1) {
p = rpx2px(p);
}
return Math.floor(p)
},
},
watch: {
text(newValue : string) {
if (newValue == "") return;
this.drawer();
},
wifi:{
handler(){
this.drawer();
},
deep:true
},
mode() {
this.drawer();
},
logo() {
this.drawer();
},
color(newValue : string) {
if (newValue == "") return;
this.drawer();
},
bgColor(newValue : string) {
if (newValue == "") return;
this.drawer();
},
logoSize(newValue : string) {
if (newValue == "") return;
this.drawer();
},
padding(newValue : string) {
if (newValue == "") return;
this.drawer();
},
width(newValue : string) {
if (newValue == "") return;
this.drawer();
},
height(newValue : string) {
if (newValue == "") return;
this.drawer();
}
},
mounted() {
// #ifndef APP-HARMONY
this.drawer()
// #endif
// #ifdef APP-HARMONY
let t = this;
this.tid2 = setTimeout(function() {
t.drawer()
}, 120);
// #endif
},
beforeUnmount() {
clearTimeout(this.tid2)
},
methods: {
drawer(){
let _this = this;
// #ifdef APP || MP
uni.createCanvasContextAsync({
id:this.id2,
component:this,
success(context){
let ctx = context.getContext('2d')!;
let canvas = ctx.canvas
if (ctx == null) return;
let ratio = uni.getWindowInfo()?.pixelRatio??1
ctx!.clearRect(0,0, canvas.offsetWidth,canvas.offsetHeight)
canvas.width = canvas.offsetWidth * ratio
canvas.height = canvas.offsetHeight * ratio
// #ifdef APP
ctx.reset();
// #endif
ctx.scale(ratio, ratio);
let img =null as null|any
// #ifdef MP-WEIXIN||APP-HARMONY
img = context.createImage()
// #endif
drawQrcode({
ctx:ctx,
text:_this._text,
size:_this._width,
foreground:_this._color,
background:_this._bgColor,
padding:_this._padding,
logo:_this._logo,
logoSize:_this._logoSize,
logoBgColor:_this._logoBgColor,
ecc:"H",
mode:_this.mode,
pdColor:_this._posColor,
pdRounded:_this.pdRounded,
} as XQrcoderProps,img)
},
fail(){
uni.showToast({title:'错误',icon:'none'})
}
})
// #endif
// #ifdef WEB
let canvas = this.$refs['canvas'] as UniCanvasElement
let ratio = window.devicePixelRatio;
canvas.width = canvas.offsetWidth * ratio
canvas.height = canvas.offsetHeight * ratio
let ctx = canvas.getContext('2d')!
ctx.scale(ratio, ratio);
drawQrcode({
ctx:ctx,
text:this._text,
size:this._width,
foreground:this._color,
background:this._bgColor,
padding:this._padding,
logoBgColor:_this._logoBgColor,
logo:this._logo,
logoSize:this._logoSize,
ecc:"H",
mode:this.mode,
pdColor:_this._posColor,
pdRounded:_this.pdRounded
} as XQrcoderProps)
// #endif
},
/**
* 返回一个上传图片的临时文件地址
* @param call(string) 返回图片路径,失败返回的是空字符串
*/
getQrImg(call:(imgstr:string)=>void) {
// #ifdef APP
let ele = this.$refs['xQrcodeEle'] as UniElement;
ele.takeSnapshot({
success(res) {
call(res.tempFilePath)
},
fail() {
call('')
}
})
// #endif
// #ifdef WEB
let ele2= this.$refs['canvas'] as HTMLCanvasElement;
toPngFile(ele2.toDataURL('image/png',1)).then(furl=>call(furl)).catch(call(''))
// #endif
// #ifdef MP-WEIXIN
uni.createCanvasContextAsync({
id:this.id2,
component:this,
success(context){
let ctx = context.getContext('2d')!;
let canvas = ctx.canvas
var imageData = canvas.toDataURL('image/png',1);
toPngFile(imageData).then(furl=>call(furl)).catch(call(''))
},
fail(err){
console.error(err)
call('')
}
},this)
// #endif
},
}
}
</script>
<template>
<view ref="xQrcodeEle" :style="{width:_width+'px',height:_height+'px'}">
<canvas ref="canvas" :canvas-id="id2" type="2d" :id="id2" :style="{width:_width+'px',height:_height+'px'}"></canvas>
</view>
</template>
<style scoped>
</style>