uniapp Vue3 写微信小程序实现分享并传参、震动、转盘、跳转其他小程序功能

功能介绍

        在微信小程序中,我们经常需要实现分享给好友和分享到朋友圈的功能。本文将介绍如何在 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 中确保所有资源正确清理
  • 转盘正在转动时退出页面要特别处理
  • 防止内存泄漏和页面报错

这个实现提供了完整的抽奖功能,包含必要的用户交互反馈,同时注意了资源管理和异常处理,确保在各种情况下都能正常运行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端切图仔001

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值