功能介绍
在微信小程序中,我们经常需要实现分享给好友和分享到朋友圈的功能。本文将介绍如何在 uniapp Vue3 项目中优雅地实现这两种分享方式。
1. 创建共享逻辑组合式函数
首先,我们在 src/composables 目录下创建 useShare.ts 文件,使用 Vue3 的组合式函数来封装分享逻辑
interface ShareConfig {
title?: string;
path?: string;
friendImageUrl?: string;
timelineImageUrl?: string;
}
export function useShare(config: ShareConfig = {}) {
const defaultConfig = {
title: '来玩骰子和转盘游戏吧!',
path: '/pages/index/index',
friendImageUrl: '/static/shareFriend.jpg', // 5:4 尺寸图片 (500x400)
timelineImageUrl: '/static/shareTimeline.jpg' // 1:1 尺寸图片 (400x400)
}
// 合并默认配置和自定义配置
const finalConfig = { ...defaultConfig, ...config }
return {
onShareAppMessage() {
return {
title: finalConfig.title,
path: finalConfig.path,
imageUrl: finalConfig.friendImageUrl
}
},
onShareTimeline() {
return {
title: defaultConfig.title,
imageUrl: finalConfig.timelineImageUrl
}
}
}
}
2. 功能说明
- ShareConfig 接口定义了分享配置的类型,包含:
- title: 分享标题
- path: 分享路径
- ( 确保图片资源已放入 static 目录下,并且路径正确 )
- friendImageUrl: 分享给好友时的图片
- 建议图片格式 jpg、 5:4 尺寸图片 (500x400) 大小128KB以内
- timelineImageUrl: 分享到朋友圈时的图片 ()
- 建议图片格式 jpg、1:1 尺寸图片 (400x400)!!!!! 大小128KB以内
- useShare 函数接收一个可选的配置对象,并返回两个分享方法:
- onShareAppMessage: 分享给好友的处理函数
- onShareTimeline: 分享到朋友圈的处理函数
- 需要注意的是 只有引入该文件的Vue的页面才能实现分享功能 没有引入的是不生效的
- 我采取的方案是 在 main.ts 文件内全局引入 ,只做朋友圈和分享好友两种状态
- 分享给好友也是同理 不写入该代码 分享也是不生效
重要提示
定义配置后(路径、图片、名称等), 如果发现分享后的自定义配置没有生效
那就需要引入 @dcloudio/uni-app
import { onShareAppMessage, onShareTimeline } from "@dcloudio/uni-app";
- 图片资源优化
-
1. 图片大小规范
- 背景图片建议大小:不超过 200KB
- 按钮图片(如 go-back、wheelGo 等):建议不超过 50KB
- 结果展示按钮图片:建议不超过 30KB
- 所有图片建议使用 jpg 格式,需要透明效果的使用 PNG 格式
-
2. 图片压缩
- 使用 TinyPNG 进行图片压缩
- 支持 WebP、PNG 和 JPEG 格式
- 智能压缩,几乎无损画质
- 可批量处理
- 支持透明度保持
-
3. 图片存放规范
- 所有图片资源统一放在 static 目录下
- 图片命名语义化
- 保持文件目录结构清晰
-
3. 实现全局引用需要借助Vue3的 mixin()
import { useShare } from "@/composables/useShare";
// 全局混入分享功能
export function setupGlobalShare(app: any) {
// #ifdef MP-WEIXIN
// 全局分享配置
const shareConfig = useShare();
app.mixin({
onShareAppMessage: shareConfig.onShareAppMessage,
onShareTimeline: shareConfig.onShareTimeline,
});
}
4. main.ts 引入
import { createSSRApp } from 'vue';
import * as Pinia from 'pinia';
import "@/static/fonts/stylesheet.css";
import App from './App.vue';
import { setupGlobalShare } from './utils/globalShare'
export function createApp() {
const app = createSSRApp(App);
const pinia = Pinia.createPinia();
setupGlobalShare(app) // 全局分享配置
app.use(pinia);
return {
app,
Pinia
};
}
5.分享后如何携带参数?
url拼接
6.如何取参数?
import { onLoad } from "@dcloudio/uni-app";
// 页面加载
onLoad(async (options) => {
// 获取openId
await getOpenId();
if (options?.roomId) {
roomId.value = options.roomId;
}
});
附言
上述代码讲的是如何让右上角的胶囊可以点击分享
如果你的需求是点击页面中某个按钮实现分享 需要使用原生 button 按钮
并设置 open-type="share" 属性 并设置你需求的相应样式
<button class="share-button" @click="handleShare" open-type="share">
<image src="/static/share.png" class="share-icon" />
</button>
.share-button {
width: 690rpx;
height: 104rpx;
background: #f7be4f;
border-radius: 7rpx;
display: flex;
justify-content: center;
align-items: center;
.share-icon {
width: 376.87rpx;
height: 42.1rpx;
}
}
再次强调:分享的自定义配置不生效 需要引入如下代码
分别对应 : onShareAppMessage :分享微信好友 onShareTimeline:分享朋友圈
import { onShareAppMessage, onShareTimeline } from "@dcloudio/uni-app";
如何跳转其它微信小程序?
uni.navigateToMiniProgram({
appId: '你的另一个微信小程序的appId',
fail: (err) => {
console.error("Navigation to mini program failed:", err);
uni.showToast({
title: '跳转失败',
icon: 'none'
});
}
});
uniapp 震动功能实现详解
功能介绍
在移动应用中,震动反馈是提升用户体验的重要方式。uniapp 提供了两种震动方式:
- 短震动:轻微的触感反馈
- 长震动:较强的震动反馈
技术实现
1. 创建震动工具函数
首先,我们在 src/composables 目录下创建 useVibrate.ts 文件
/**
* 震动工具函数
*/
export function useVibrate() {
// 短震动
const vibrateShort = () => {
uni.vibrateShort({
success: () => {
console.log('短震动成功')
},
fail: (err) => {
console.error('短震动失败:', err)
}
})
}
// 长震动
const vibrateLong = () => {
uni.vibrateLong({
success: () => {
console.log('长震动成功')
},
fail: (err) => {
console.error('长震动失败:', err)
}
})
}
return {
vibrateShort,
vibrateLong
}
}
<template>
<view class="container">
<button @click="handleShortVibrate">短震动</button>
<button @click="handleLongVibrate">长震动</button>
</view>
</template>
<script setup lang="ts">
import { useVibrate } from '@/composables/useVibrate'
const { vibrateShort, vibrateLong } = useVibrate()
const handleShortVibrate = () => {
vibrateShort()
}
const handleLongVibrate = () => {
vibrateLong()
}
</script>
API 说明
1. 短震动 (uni.vibrateShort)
- 作用:触发较短时间的震动
- 震动时长:约 15ms
- 适用场景:按钮点击、操作反馈等轻量级交互
uni.vibrateShort(options: UniNamespace.VibrateShortOptions)
参数说明:
interface VibrateShortOptions {
success?: () => void // 接口调用成功的回调函数
fail?: (err: any) => void // 接口调用失败的回调函数
complete?: () => void // 接口调用结束的回调函数(调用成功、失败都会执行)
}
2. 长震动 (uni.vibrateLong)
- 作用:触发较长时间的震动
- 震动时长:约 400ms
- 适用场景:游戏结束、重要提示等需要明显震动反馈的场合
uni.vibrateLong(options: UniNamespace.VibrateLongOptions)
参数说明:
interface VibrateLongOptions {
success?: () => void // 接口调用成功的回调函数
fail?: (err: any) => void // 接口调用失败的回调函数
complete?: () => void // 接口调用结束的回调函数(调用成功、失败都会执行)
}
平台差异说明
| API | App | H5 | 微信小程序 | 支付宝小程序 | 百度小程序 |
|-----|-----|----| ---------- | ------------ | ---------- |
| vibrateShort | √ | x | √ | √ | √ |
| vibrateLong | √ | x | √ | √ | √ |
注意事项
- 权限要求:
- App 平台需要在 manifest.json 中配置 vibrate 权限
- 部分平台可能需要用户授权
- 使用场景:
- 短震动适合用于轻量级的交互反馈
- 长震动建议用于重要提示,避免过度使用影响用户体验
- 兼容性处理:
- 建议添加错误处理逻辑
- 在不支持的平台上需要提供替代方案
最佳实践
1. 合理使用:
// 例如在游戏中点击骰子
const handleDiceClick = () => {
vibrateShort() // 给予即时反馈
}
// 游戏结束时
const handleGameOver = () => {
vibrateLong() // 给予明显提示
}
2. 错误处理:
const vibrateWithFallback = () => {
uni.vibrateShort({
fail: (err) => {
console.error('震动失败,提供其他反馈方式', err)
// 可以使用其他方式提供反馈,如视觉提示
}
})
}
总结
震动功能是提升应用交互体验的重要手段。通过 uniapp 提供的震动 API,我们可以轻松实现短震动和长震动效果。在实际应用中,需要注意:
- 根据交互场景选择合适的震动类型
- 注意平台差异和权限要求
- 适当添加错误处理
- 避免过度使用震动,以免影响用户体验
基于 uni-app + Vue3 实现微信小程序抽奖大转盘
效果预览
我自定义配置内容包含:转盘、三角区域背景色、指针、名称
大转盘文档链接 : 100px.net | 基于 Js / TS / Vue / React / 微信小程序 / uni-app / Taro 的【大转盘 & 九宫格 & 老虎机】抽奖插件
技术栈
- uni-app (跨平台开发框架)
- Vue 3 (Composition API)
- TypeScript
- lucky-canvas (抽奖插件的 uni-app 版本 配置较全)
- Pinia (状态管理)
<LuckyWheel
class="lucky-wheel"
ref="myLucky"
width="680rpx"
height="680rpx"
:blocks="blocks"
:prizes="prizes"
:buttons="buttons"
:defaultStyle="defaultStyle"
@start="startCallBack"
@end="endCallBack"
:defaultConfig="defaultConfig"
/>
JavaScript 部分详解
1. 基础配置和引用
// 引入必要的 Vue 组合式 API
import { ref, shallowRef, onUnmounted, onMounted } from "vue";
// 引入随机数生成库
import random from "random";
// 引入转盘组件
import LuckyWheel from "@lucky-canvas/uni/lucky-wheel";
// 引入状态管理
import { useSettingsStore } from "@/stores/settings";
// 使用 shallowRef 创建转盘实例引用,优化性能
const myLucky = shallowRef<LuckyWheel | null>(null);
2. 转盘配置详解
blocks(转盘外观配置)
const blocks = [
{
padding: "20px", // 内边距
imgs: [
{
src: "/static/wheelRotate.png", // 转盘背景图
width: "680rpx",
height: "680rpx",
},
],
},
];
1. prizes(奖品配置)
const buttons = [
{ radius: "50px", background: "#617df2" }, // 外圈按钮
{ radius: "45px", background: "#afc8ff" }, // 中圈按钮
{
radius: "40px", // 内圈按钮(开始按钮)
background: "#869cfa",
pointer: false, // 是否显示指针
imgs: [
{
src: "/static/wheelGo.png", // 开始按钮图片
width: "180.7rpx",
height: "256.7rpx",
top: "-168rpx",
},
],
},
];
2. 样式和配置
// 默认样式配置
const defaultStyle = {
fontSize: "28rpx",
lengthLimit: 0, // 文字长度限制
fontFamily: "zihunbiantaoti",
};
// 转盘动画配置
const defaultConfig = {
accelerationTime: 1000, // 加速时间
decelerationTime: 1000, // 减速时间
};
3. 响应式状态
const resultText = ref(""); // 结果文本
const isHiding = ref(false); // 控制结果框隐藏动画
const actionImage = ref(""); // 动作按钮图片
const currentPunishType = ref(""); // 当前惩罚类型
const spinTimer = ref<number | null>(null); // 转盘定时器
const hideTimer = ref<number | null>(null); // 隐藏动画定时器
4. 开始按钮回调 实现随机抽取奖品
const startCallBack = () => {
console.log("startCallBack");
actionImage.value = "";
isHiding.value = true;
// 添加震动效果
settingsStore.vibrate("long");
// 先停止之前可能正在播放的音效
settingsStore.stopSound();
// 然后开始播放转盘音效
settingsStore.playSound("WHEEL_SPIN");
hideTimer.value = setTimeout(() => {
resultText.value = "";
isHiding.value = false;
}, 300);
myLucky.value.play();
spinTimer.value = setTimeout(() => {
const index = random.int(0, prizes.length - 1);
myLucky.value.stop(index);
}, 3000);
};
5.结果处理
const endCallBack = (prize: any) => {
// 播放结果音效
setTimeout(() => {
settingsStore.stopSound();
settingsStore.playSound("WHEEL_RESULT");
}, 100);
// 显示结果
resultText.value = prize.fonts[0].text;
// 根据结果显示对应按钮
// ... 处理不同类型的结果
};
6. 生命周期处理
onUnmounted(() => {
// 清理定时器
if (spinTimer.value) clearTimeout(spinTimer.value);
if (hideTimer.value) clearTimeout(hideTimer.value);
// 停止音效
settingsStore.stopSound();
});
注意事项
1. 页面返回处理
- 在用户点击返回按钮时,需要立即清理所有定时器
- 停止转盘动画
- 停止音效播放
- 避免在页面销毁后继续执行回调导致报错
2. 生命周期处理
- 在 onUnmounted 中确保所有资源正确清理
- 转盘正在转动时退出页面要特别处理
- 防止内存泄漏和页面报错
这个实现提供了完整的抽奖功能,包含必要的用户交互反馈,同时注意了资源管理和异常处理,确保在各种情况下都能正常运行。