HomeLease/examples/single-image-upload-usage.vue
2025-08-21 13:37:29 +08:00

318 lines
7.4 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="usage-example">
<view class="example-header">
<text class="title">单图上传使用示例</text>
<text class="desc">展示如何在页面中集成图片上传功能</text>
</view>
<!-- 方法一跳转到上传页面 -->
<view class="method-section">
<text class="method-title">方法一跳转到上传页面</text>
<text class="method-desc">跳转到专门的上传页面上传完成后返回</text>
<button class="method-btn" @click="method1">跳转上传</button>
<view v-if="method1Result" class="result-box">
<text class="result-label">上传结果:</text>
<image :src="method1Result" mode="widthFix" class="result-image"></image>
<text class="result-url">{{ method1Result }}</text>
</view>
</view>
<!-- 方法二:内嵌上传组件 -->
<view class="method-section">
<text class="method-title">方法二:内嵌上传组件</text>
<text class="method-desc">在当前页面直接使用上传组件</text>
<view class="inline-upload">
<view class="upload-area" @click="chooseImage">
<view v-if="!selectedImage" class="upload-placeholder">
<text>点击选择图片</text>
</view>
<image v-else :src="selectedImage" mode="aspectFit" class="preview-image"></image>
</view>
<button
class="upload-btn"
@click="uploadSelectedImage"
:disabled="!selectedImage || uploading"
>
{{ uploading ? '上传中...' : '上传' }}
</button>
</view>
<view v-if="method2Result" class="result-box">
<text class="result-label">上传结果:</text>
<image :src="method2Result" mode="widthFix" class="result-image"></image>
<text class="result-url">{{ method2Result }}</text>
</view>
</view>
</view>
</template>
<script>
import { getQiniuUploadToken, uploadToQiniu } from '@/api/upload.js'
export default {
data() {
return {
// 方法一结果
method1Result: '',
// 方法二数据
selectedImage: '',
uploading: false,
method2Result: '',
qiniuToken: '',
}
},
onLoad() {
// 监听上传成功事件
uni.$on('image-upload-success', this.onImageUploadSuccess)
},
onUnload() {
// 移除事件监听
uni.$off('image-upload-success', this.onImageUploadSuccess)
},
methods: {
// 方法一:跳转到上传页面
method1() {
uni.navigateTo({
url: '/pages/image-upload/image-upload'
})
},
// 监听上传成功事件
onImageUploadSuccess(imageUrl) {
this.method1Result = imageUrl
uni.showToast({
title: '图片上传成功',
icon: 'success'
})
},
// 方法二:选择图片
chooseImage() {
uni.chooseImage({
count: 1,
sizeType: ['compressed'],
sourceType: ['album', 'camera'],
success: (res) => {
this.selectedImage = res.tempFilePaths[0]
this.method2Result = ''
}
})
},
// 方法二:上传选中的图片
async uploadSelectedImage() {
if (!this.selectedImage) {
uni.showToast({
title: '请先选择图片',
icon: 'none'
})
return
}
this.uploading = true
try {
// 获取token
if (!this.qiniuToken) {
await this.getQiniuToken()
}
// 生成文件名
const key = `examples/${Date.now()}_${Math.random().toString(36).slice(2)}.jpg`
// 上传
const result = await uploadToQiniu(this.selectedImage, this.qiniuToken, key)
this.method2Result = `https://api.ccttiot.com/${result.key}`
uni.showToast({
title: '上传成功',
icon: 'success'
})
} catch (error) {
console.error('上传失败:', error)
uni.showToast({
title: '上传失败',
icon: 'none'
})
} finally {
this.uploading = false
}
},
// 获取七牛云token
async getQiniuToken() {
try {
const res = await getQiniuUploadToken()
if (res.code === 200) {
const token = res.data?.token || res.data?.uploadToken || res.token || res.data
if (token) {
this.qiniuToken = token
} else {
throw new Error('Token字段不存在')
}
} else {
throw new Error(res.msg || '获取Token失败')
}
} catch (error) {
console.error('获取Token失败:', error)
throw error
}
}
}
}
</script>
<style lang="scss" scoped>
.usage-example {
padding: 30rpx;
background: #f5f5f5;
min-height: 100vh;
.example-header {
text-align: center;
margin-bottom: 40rpx;
.title {
display: block;
font-size: 36rpx;
font-weight: bold;
color: #333;
margin-bottom: 10rpx;
}
.desc {
display: block;
font-size: 26rpx;
color: #666;
}
}
.method-section {
background: #fff;
border-radius: 16rpx;
padding: 30rpx;
margin-bottom: 30rpx;
.method-title {
display: block;
font-size: 30rpx;
font-weight: bold;
color: #333;
margin-bottom: 10rpx;
}
.method-desc {
display: block;
font-size: 24rpx;
color: #666;
margin-bottom: 20rpx;
}
.method-btn {
width: 100%;
height: 80rpx;
line-height: 80rpx;
background: #007aff;
color: #fff;
border-radius: 12rpx;
font-size: 28rpx;
border: none;
margin-bottom: 20rpx;
&:active {
background: #0056cc;
}
}
.inline-upload {
margin-bottom: 20rpx;
.upload-area {
width: 100%;
height: 200rpx;
background: #f8f8f8;
border-radius: 12rpx;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 20rpx;
border: 2rpx dashed #ddd;
.upload-placeholder {
text-align: center;
text {
font-size: 28rpx;
color: #999;
}
}
.preview-image {
width: 100%;
height: 100%;
border-radius: 12rpx;
}
}
.upload-btn {
width: 100%;
height: 70rpx;
line-height: 70rpx;
background: #52c41a;
color: #fff;
border-radius: 8rpx;
font-size: 26rpx;
border: none;
&:active {
background: #389e0d;
}
&:disabled {
background: #ccc;
color: #999;
}
}
}
.result-box {
border-top: 1rpx solid #eee;
padding-top: 20rpx;
.result-label {
display: block;
font-size: 26rpx;
font-weight: bold;
color: #333;
margin-bottom: 15rpx;
}
.result-image {
width: 100%;
border-radius: 8rpx;
margin-bottom: 15rpx;
}
.result-url {
display: block;
font-size: 22rpx;
color: #007aff;
word-break: break-all;
line-height: 1.4;
background: #f8f8f8;
padding: 15rpx;
border-radius: 6rpx;
}
}
}
}
</style>