UniApp Vue3 生成海报并分享到朋友圈
纯前端生成海报 + 保存到相册 + 引导分享朋友圈
核心技术
- uni-canvas(UniApp 官方画布,兼容多端)
- Vue3 + Composition API
- 异步绘制 + 加载等待(解决图片不显示问题)
- 保存到相册 + 引导分享朋友圈
一、核心代码
1. 页面 vue 文件
<template>
<view class="container">
<!-- 生成海报按钮 -->
<button type="primary" @click="createPoster" :loading="loading">
生成分享海报
</button>
<!-- 海报预览弹窗 -->
<view v-if="showPoster" class="modal" @click="showPoster = false">
<view class="poster-box" @click.stop>
<!-- 画布:用于生成海报(隐藏在页面外) -->
<canvas
type="2d"
id="posterCanvas"
canvas-id="posterCanvas"
class="poster-canvas"
/>
<!-- 预览图 -->
<image :src="posterUrl" mode="widthFix" class="poster-img" />
<!-- 操作按钮 -->
<view class="btn-group">
<button type="primary" @click="savePoster">保存海报到相册</button>
<view class="tip">
保存后,打开微信朋友圈 → 从相册选择图片发布
</view>
</view>
</view>
</view>
</view>
</template>
<script setup>
import { ref, onMounted } from 'vue'
// 状态
const loading = ref(false) // 生成中loading
const showPoster = ref(false) // 显示海报弹窗
const posterUrl = ref('') // 生成的海报临时路径
let canvas = null // 画布实例
let ctx = null // 画布上下文
// 页面加载后获取画布
onMounted(() => {
const query = uni.createSelectorQuery().in(getCurrentInstance())
query.select('#posterCanvas')
.fields({ node: true, size: true })
.exec((res) => {
if (!res[0]) return
canvas = res[0].node
ctx = canvas.getContext('2d')
})
})
const createPoster = async () => {
if (!canvas || !ctx) {
uni.showToast({ title: '画布初始化失败', icon: 'none' })
return
}
loading.value = true
uni.showLoading({ title: '海报生成中...' })
// 画布尺寸(海报尺寸)
const dpr = uni.getSystemInfoSync().pixelRatio
canvas.width = 300 * dpr
canvas.height = 400 * dpr
ctx.scale(dpr, dpr)
try {
// 1. 绘制白色背景
ctx.fillStyle = '#ffffff'
ctx.fillRect(0, 0, 300, 400)
// 2. 绘制标题
ctx.fillStyle = '#333'
ctx.font = 'bold 18px sans-serif'
ctx.fillText('我的商品海报', 30, 40)
// 3. 绘制商品图片(替换成你的网络图片/本地图片)
const coverImg = await loadImage('/static/poster.png')
ctx.drawImage(coverImg, 30, 60, 240, 240)
// 4. 绘制价格
ctx.fillStyle = '#ff3333'
ctx.font = '16px sans-serif'
ctx.fillText('¥ 99.00', 30, 330)
// 5. 绘制二维码(替换成你的二维码)
const qrcodeImg = await loadImage('/static/qrcode.png')
ctx.drawImage(qrcodeImg, 180, 310, 60, 60)
// 6. 导出海报图片
await saveCanvasToTempFilePath()
showPoster.value = true
uni.hideLoading()
} catch (err) {
console.error('生成失败:', err)
uni.showToast({ title: '生成失败', icon: 'none' })
uni.hideLoading()
} finally {
loading.value = false
}
}
const loadImage = (src) => {
return new Promise((resolve, reject) => {
const img = canvas.createImage()
img.onload = () => resolve(img)
img.onerror = (e) => reject(e)
img.src = src
})
}
const saveCanvasToTempFilePath = () => {
return new Promise((resolve) => {
setTimeout(() => {
uni.canvasToTempFilePath({
canvas: canvas,
width: 300,
height: 400,
destWidth: 900,
destHeight: 1200,
success: (res) => {
posterUrl.value = res.tempFilePath
resolve()
}
}, getCurrentInstance())
}, 300)
})
}
const savePoster = () => {
if (!posterUrl.value) return
uni.saveImageToPhotosAlbum({
filePath: posterUrl.value,
success: () => {
uni.showModal({
title: '保存成功',
content: '已保存到相册,请到朋友圈发布',
showCancel: false
})
},
fail: () => {
uni.showToast({ title: '保存失败', icon: 'none' })
}
})
}
</script>
<style scoped>
.container { padding: 40rpx;}
/* 弹窗遮罩 */
.modal { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.6); display: flex; align-items: center; justify-content: center; z-index: 999;}
/* 海报容器 */
.poster-box { width: 600rpx; background: #fff; border-radius: 16rpx; padding: 20rpx; position: relative;}
/* 画布:隐藏在页面外,不影响UI */
.poster-canvas { position: absolute; left: -9999rpx; top: 0; width: 300px;height: 400px;}
/* 预览图 */
.poster-img {width: 100%;border-radius: 8rpx;}
/* 按钮组 */
.btn-group {margin-top: 20rpx;text-align: center;}
.tip {font-size: 24rpx;color: #999;margin-top: 16rpx;line-height: 1.5;}
</style>
二、替换商品主图
-
商品主图
loadImage('/static/poster.png')换成你的网络图片或本地图片。
-
二维码图片
loadImage('/static/qrcode.png')把
/static/qrcode.png换成你自己的二维码。 -
文字内容(标题、价格等)可自由修改。
三、微信小程序权限配置
打开项目根目录 manifest.json → 切换到源码视图,添加以下权限:
"mp-weixin": {
"permission": {
"scope.writePhotosAlbum": {
"desc": "需要保存海报到相册"
}
}
}
使用流程
- 点击生成分享海报
- 自动绘制 → 弹出预览图
- 点击保存海报到相册
- 提示保存成功
- 手动打开微信朋友圈 → 从相册选择图片发布