<template>
|
<view class="container">
|
|
<!-- 输入区域 -->
|
<view class="input-group">
|
<text class="label">
|
<uni-icons type="compose" size="16" color="#2c3e50" />
|
输入文本或URL:
|
</text>
|
<textarea v-model="inputText" placeholder="在此输入文本、网址或其他信息..." />
|
</view>
|
|
<!-- 示例按钮 -->
|
<view class="examples">
|
<view v-for="(example, index) in examples" :key="index" class="example-btn" @tap="setExample(example.text)">
|
{{ example.label }}
|
</view>
|
</view>
|
|
<!-- 生成按钮 -->
|
<button class="generate-btn" @tap="generateQRCode">
|
<uni-icons type="bolt" size="20" color="#fff" />
|
<text>{{generating ? "生成中...." :"生成二维码" }}</text>
|
</button>
|
|
<!-- 二维码显示区域 -->
|
<view class="qrcode-container">
|
|
<canvas v-if="qrCodeGenerated" ref="qrcodeCanvas" canvas-id="qrcodeCanvas" class="qrcode-canvas"
|
@longpress="handleLongPress" width="200" height="200" />
|
<view v-else class="placeholder">
|
<uni-icons type="qrcode" size="48" color="#95a5a6" />
|
<text>二维码将在此处显示</text>
|
</view>
|
</view>
|
</view>
|
</template>
|
|
|
|
<script>
|
import UQRCode from '@uqrcode/js'; // npm install @uqrcode/js
|
export default {
|
data() {
|
return {
|
inputText: 'https://www.example.com',
|
qrCodeGenerated: false,
|
isMiniprogram: false,
|
qrCodeDataUrl: null,
|
platformName: 'H5',
|
platformIcon: 'circle',
|
error: null,
|
generating: false,
|
saveButtonText: '保存二维码',
|
examples: [{
|
label: '示例网址',
|
text: 'https://www.example.com'
|
},
|
{
|
label: '示例文本',
|
text: 'Hello, World!'
|
},
|
{
|
label: '联系方式',
|
text: '微信:example_user'
|
},
|
{
|
label: 'WiFi连接',
|
text: 'WIFI:T:WPA;S:MyNetwork;P:password123;;'
|
}
|
]
|
};
|
},
|
mounted() {
|
// this.detectPlatform();
|
},
|
methods: {
|
// detectPlatform() {
|
// // 判断是否在小程序环境中
|
// // #ifdef MP-WEIXIN
|
// this.isMiniprogram = true;
|
// this.platformName = '微信小程序';
|
// this.platformIcon = 'weixin';
|
// this.saveButtonText = '保存到相册';
|
// // #endif
|
|
// // #ifdef APP-PLUS
|
// this.isMiniprogram = true;
|
// this.platformName = 'App';
|
// this.platformIcon = 'mobile';
|
// this.saveButtonText = '保存到相册';
|
// // #endif
|
// },
|
|
setExample(text) {
|
this.inputText = text;
|
this.generateQRCode();
|
},
|
|
// 生成二维码 - 使用 canvas-id 替代 ref
|
async generateQRCode() {
|
const text = this.inputText.trim();
|
|
if (!text) {
|
this.error = '请输入要生成二维码的内容!';
|
return;
|
}
|
|
this.generating = true;
|
this.error = null;
|
this.qrCodeGenerated = true;
|
try {
|
const qr = new UQRCode();
|
qr.data = text;
|
qr.size = 200;
|
qr.make();
|
const ctx = uni.createCanvasContext('qrcodeCanvas',
|
this); // 组件内调用需传this,vue3 中 this 为 getCurrentInstance()?.proxy
|
qr.canvasContext = ctx;
|
qr.drawCanvas();
|
this.generating = false;
|
} catch (e) {
|
console.error('二维码生成异常:', e);
|
alert('生成二维码时出错!');
|
this.qrCodeGenerated = false;
|
|
}
|
},
|
|
// 保存二维码
|
saveQRCode() {
|
if (!this.qrCodeGenerated) {
|
alert('请先生成二维码');
|
return;
|
}
|
|
const canvas = this.$refs.qrcodeCanvas;
|
if (!canvas) return;
|
|
// 在不同平台使用不同的保存方式
|
if (this.isMiniprogram) {
|
// 小程序环境保存
|
this.saveInMiniprogram(canvas);
|
} else {
|
// H5环境保存
|
this.saveInH5(canvas);
|
}
|
},
|
// 在H5环境中保存二维码
|
saveInH5(canvas) {
|
const dataURL = canvas.toDataURL('image/png');
|
const link = document.createElement('a');
|
link.href = dataURL;
|
link.download = `qrcode-${new Date().getTime()}.png`;
|
document.body.appendChild(link);
|
link.click();
|
document.body.removeChild(link);
|
|
alert('二维码已保存');
|
},
|
|
// 在小程序环境中保存二维码
|
saveInMiniprogram(canvas) {
|
// 模拟Uniapp保存图片到相册
|
if (typeof uni !== 'undefined') {
|
uni.canvasToTempFilePath({
|
canvas: canvas,
|
success: (res) => {
|
uni.saveImageToPhotosAlbum({
|
filePath: res.tempFilePath,
|
success: () => {
|
uni.showToast({
|
title: '保存成功',
|
icon: 'success'
|
});
|
},
|
fail: () => {
|
uni.showToast({
|
title: '保存失败',
|
icon: 'none'
|
});
|
}
|
});
|
},
|
fail: (err) => {
|
console.error('保存失败:', err);
|
uni.showToast({
|
title: '保存失败',
|
icon: 'none'
|
});
|
}
|
});
|
}
|
// 微信原生小程序保存
|
else if (typeof wx !== 'undefined') {
|
wx.canvasToTempFilePath({
|
canvas: canvas,
|
success: (res) => {
|
wx.saveImageToPhotosAlbum({
|
filePath: res.tempFilePath,
|
success: () => {
|
wx.showToast({
|
title: '保存成功',
|
icon: 'success'
|
});
|
},
|
fail: () => {
|
wx.showToast({
|
title: '保存失败',
|
icon: 'none'
|
});
|
}
|
});
|
},
|
fail: (err) => {
|
console.error('保存失败:', err);
|
wx.showToast({
|
title: '保存失败',
|
icon: 'none'
|
});
|
}
|
});
|
}
|
},
|
|
|
// 小程序长按事件
|
handleLongPress() {
|
if (this.isMiniprogram) {
|
this.saveQRCode();
|
}
|
}
|
}
|
};
|
</script>
|
|
<style lang="scss">
|
* {
|
margin: 0;
|
padding: 0;
|
box-sizing: border-box;
|
font-family: 'Segoe UI', 'Microsoft YaHei', sans-serif;
|
}
|
|
textarea {
|
width: 100%;
|
height: 120px;
|
padding: 15px;
|
border: 2px solid #ddd;
|
border-radius: 12px;
|
font-size: 1rem;
|
resize: none;
|
transition: all 0.3s ease;
|
}
|
|
textarea:focus {
|
border-color: #3498db;
|
outline: none;
|
box-shadow: 0 0 0 3px rgba(52, 152, 219, 0.2);
|
}
|
|
.generate-btn {
|
width: 100%;
|
padding: 15px;
|
background: linear-gradient(to right, #3498db, #2c3e50);
|
color: white;
|
border: none;
|
border-radius: 12px;
|
font-size: 1.2rem;
|
font-weight: 600;
|
cursor: pointer;
|
transition: all 0.3s ease;
|
margin-bottom: 25px;
|
display: flex;
|
justify-content: center;
|
align-items: center;
|
gap: 10px;
|
}
|
|
.generate-btn:hover {
|
background: linear-gradient(to right, #2980b9, #1a252f);
|
transform: translateY(-2px);
|
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
|
}
|
|
.qrcode-container {
|
text-align: center;
|
margin-bottom: 25px;
|
padding: 20px;
|
border-radius: 15px;
|
background: #f8f9fa;
|
box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.05);
|
min-height: 260px;
|
display: flex;
|
flex-direction: column;
|
align-items: center;
|
justify-content: center;
|
}
|
|
.qrcode-canvas {
|
width: 200px;
|
height: 200px;
|
margin: 0 auto;
|
padding: 10px;
|
background: white;
|
border-radius: 10px;
|
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
|
}
|
|
.placeholder {
|
color: #95a5a6;
|
font-size: 1.1rem;
|
}
|
.examples {
|
display: flex;
|
gap: 15px;
|
flex-wrap: wrap;
|
margin-top: 15px;
|
justify-content: center;
|
}
|
|
.example-btn {
|
padding: 8px 15px;
|
background: #e0e7ff;
|
color: #4f46e5;
|
border-radius: 20px;
|
font-size: 0.9rem;
|
cursor: pointer;
|
transition: all 0.2s;
|
}
|
|
.example-btn:hover {
|
background: #c7d2fe;
|
}
|
|
|
|
@media (max-width: 500px) {
|
#app {
|
padding: 20px;
|
}
|
|
.header h1 {
|
font-size: 1.8rem;
|
}
|
|
.header p {
|
font-size: 1rem;
|
}
|
|
.qrcode-canvas {
|
width: 180px;
|
height: 180px;
|
}
|
}
|
</style>
|