当前位置: 首页 > news >正文

『uniapp』uni-share 分享功能 使用例子(保姆级图文)

目录

    • 打包自定义基座后的预览效果
    • 启用share模块
    • 准备好分享按钮图标文件
    • 具体功能实现
      • uni-image-menu.js
      • uni-share.js
    • 功能演示页面
      • 导入依赖
      • onBackPress 方法
      • `uniShare.show` 配置说明
        • `content`: 定义了分享的基本内容,包括:
        • `menus`: 定义了分享目标平台的配置。每个菜单项包括:
        • `cancelText`: 设置分享取消按钮的文字。
        • 回调函数:
      • 完整代码
    • 总结


欢迎关注 『uniapp』 专栏,持续更新中
欢迎关注 『uniapp』 专栏,持续更新中

打包自定义基座后的预览效果

  • 分享内容
    在这里插入图片描述

  • 点击更多后调用系统的分享
    在这里插入图片描述

  • 取消分享的回调
    在这里插入图片描述

  • 分享给QQ
    在这里插入图片描述

启用share模块

启用后会自动给你加入对应的分享权限

这里面的个汇总appid或是key可以随便填,如果你没有申请的话,不影响功能测试
在这里插入图片描述


准备好分享按钮图标文件

你可以用自己的图片
在这里插入图片描述


具体功能实现

新建utils文件夹

uni-image-menu.js

var nvMask, nvImageMenu;
class NvImageMenu {constructor(arg) {this.isShow = false}show({list,cancelText}, callback) {if (!list) {list = [{"img": "/static/sharemenu/wechatfriend.png","text": "图标文字"}]}//以下为计算菜单的nview绘制布局,为固定算法,使用者无关关心var screenWidth = plus.screen.resolutionWidth//以360px宽度屏幕为例,上下左右边距及2排按钮边距留25像素,图标宽度55像素,同行图标间的间距在360宽的屏幕是30px,但需要动态计算,以此原则计算4列图标分别的left位置//图标下的按钮文字距离图标5像素,文字大小12像素//底部取消按钮高度固定为44px//TODO 未处理横屏和pad,这些情况6个图标应该一排即可var margin = 20,iconWidth = 60,icontextSpace = 5,textHeight = 12var left1 = margin / 360 * screenWidthvar iconSpace = (screenWidth - (left1 * 2) - (iconWidth * 4)) / 3 //屏幕宽度减去左右留白间距,再减去4个图标的宽度,就是3个同行图标的间距if (iconSpace <= 5) { //屏幕过窄时,缩小边距和图标大小,再算一次margin = 15iconWidth = 40left1 = margin / 360 * screenWidthiconSpace = (screenWidth - (left1 * 2) - (iconWidth * 4)) / 3 //屏幕宽度减去左右留白间距,再减去4个图标的宽度,就是3个同行图标的间距}var left2 = left1 + iconWidth + iconSpacevar left3 = left1 + (iconWidth + iconSpace) * 2var left4 = left1 + (iconWidth + iconSpace) * 3var top1 = left1var top2 = top1 + iconWidth + icontextSpace + textHeight + left1const TOP = {top1,top2},LEFT = {left1,left2,left3,left4};nvMask = new plus.nativeObj.View("nvMask", { //先创建遮罩层top: '0px',left: '0px',height: '100%',width: '100%',backgroundColor: 'rgba(0,0,0,0.2)'});nvImageMenu = new plus.nativeObj.View("nvImageMenu", { //创建底部图标菜单bottom: '0px',left: '0px',height: (iconWidth + textHeight + 2 * margin) * Math.ceil(list.length / 4) + 44 +'px', //'264px',width: '100%',backgroundColor: 'rgb(255,255,255)'});nvMask.addEventListener("click", () => { //处理遮罩层点击// console.log('处理遮罩层点击');this.hide()callback({event: "clickMask"})})let myList = []list.forEach((item, i) => {myList.push({tag: 'img',src: item.img,position: {top: TOP['top' + (parseInt(i / 4) + 1)],left: LEFT['left' + (1 + i % 4)],width: iconWidth,height: iconWidth}})myList.push({tag: 'font',text: item.text,textStyles: {size: textHeight},position: {top: TOP['top' + (parseInt(i / 4) + 1)] + iconWidth + icontextSpace,left: LEFT['left' + (1 + i % 4)],width: iconWidth,height: textHeight}})})//绘制底部图标菜单的内容nvImageMenu.draw([{tag: 'rect', //菜单顶部的分割灰线color: '#e7e7e7',position: {top: '0px',height: '1px'}},{tag: 'font',text: cancelText, //底部取消按钮的文字textStyles: {size: '14px'},position: {bottom: '0px',height: '44px'}},{tag: 'rect', //底部取消按钮的顶部边线color: '#e7e7e7',position: {bottom: '45px',height: '1px'}},...myList])nvMask.show()nvImageMenu.show()// 开始动画/*plus.nativeObj.View.startAnimation({type: 'slide-in-bottom',duration: 300}, nvImageMenu, {}, function() {console.log('plus.nativeObj.View.startAnimation动画结束');// 关闭原生动画plus.nativeObj.View.clearAnimation();nvImageMenu.show()});*/this.isShow = truenvImageMenu.addEventListener("click", e => { //处理底部图标菜单的点击事件,根据点击位置触发不同的逻辑// console.log("click menu"+JSON.stringify(e));if (e.screenY > plus.screen.resolutionHeight - 44) { //点击了底部取消按钮// callback({event:"clickCancelButton"})this.hide()} else if (e.clientX < 5 || e.clientX > screenWidth - 5 || e.clientY < 5) {//屏幕左右边缘5像素及菜单顶部5像素不处理点击} else { //点击了图标按钮var iClickIndex = -1 //点击的图标按钮序号,第一个图标按钮的index为0var iRow = e.clientY < (top2 - (left1 / 2)) ? 0 : 1var iCol = -1if (e.clientX < (left2 - (iconSpace / 2))) {iCol = 0} else if (e.clientX < (left3 - (iconSpace / 2))) {iCol = 1} else if (e.clientX < (left4 - (iconSpace / 2))) {iCol = 2} else {iCol = 3}if (iRow == 0) {iClickIndex = iCol} else {iClickIndex = iCol + 4}// console.log("点击按钮的序号: " + iClickIndex);// if (iClickIndex >= 0 && iClickIndex <= 5) { //处理具体的点击逻辑,此处也可以自行定义逻辑。如果增减了按钮,此处也需要跟着修改// }callback({event: "clickMenu",index: iClickIndex})}})/* nvImageMenu.addEventListener("touchstart", function(e) {if (e.screenY > (plus.screen.resolutionHeight - 44)) {//TODO 这里可以处理按下背景变灰的效果}})nvImageMenu.addEventListener("touchmove", function(e) {//TODO 这里可以处理按下背景变灰的效果if (e.screenY > plus.screen.resolutionHeight - 44) {}})nvImageMenu.addEventListener("touchend", function(e) {//TODO 这里可以处理释放背景恢复的效果})*/}hide() {nvMask.hide()nvImageMenu.hide()this.isShow = false}
}export default NvImageMenu

uni-share.js

import UniImageMenu from './uni-image-menu.js';
class UniShare extends UniImageMenu{constructor(arg) {super()this.isShow = super.isShow}async show(param, callback){var menus = []plus.share.getServices(services => { //只显示有服务的项目services = services.filter(item => item.nativeClient)let servicesList = services.map(e => e.id)param.menus.forEach(item => {if (servicesList.includes(item.share.provider) || typeof(item.share) == 'string') {menus.push(item)}})super.show({list: menus,cancelText: param.cancelText}, e => {callback(e)if(e.event == 'clickMenu'){if (typeof(menus[e.index]['share']) == 'string') {this[menus[e.index]['share']](param)} else {uni.share({...param.content,...menus[e.index].share,success: res=> {console.log("success:" + JSON.stringify(res));super.hide()},fail: function(err) {console.log("fail:" + JSON.stringify(err));uni.showModal({content: JSON.stringify(err),showCancel: false,confirmText: "知道了"});}})}}})}, err => {uni.showModal({title: '获取服务供应商失败:' + JSON.stringify(err),showCancel: false,confirmText: '知道了'});console.error('获取服务供应商失败:' + JSON.stringify(err));})}hide(){super.hide()}copyurl(param) {console.log('copyurl',param);uni.setClipboardData({data: param.content.href,success: ()=>{console.log('success');uni.hideToast() //关闭自带的toastuni.showToast({title: '复制成功',icon: 'none'});super.hide();},fail: (err) => {uni.showModal({content: JSON.stringify(err),showCancel: false});}});}// 使用系统分享发送分享消息 shareSystem(param) {console.log('shareSystem',param);plus.share.sendWithSystem({type: 'text',content: param.content.title + param.content.summary || '',href: param.content.href,}, (e)=> {console.log('分享成功');super.hide()}, (err)=> {console.log('分享失败:' + JSON.stringify(err));uni.showModal({title: '获取服务供应商失败:' + JSON.stringify(err),showCancel: false,confirmText: '知道了'});});}
}
export default UniShare

功能演示页面

导入依赖

  • 通过 import 语句从 utils/uni-share.js 文件导入了一个名为 UniShare 的类。
  • 然后创建了一个 UniShare 的实例 uniShare,通过这个实例来调用分享功能。
import UniShare from 'utils/uni-share.js';
const uniShare = new UniShare();

onBackPress 方法

  • onBackPress 是一个自定义方法,可能用来处理用户按下返回按钮时的行为。
  • from 是一个参数,表示返回操作的来源(比如是否是系统的返回按钮)。
  • 如果 from 等于 ‘backbutton’,表示是从设备的返回按钮触发的返回事件。
  • 通过 this.$nextTick() 延迟执行 uniShare.hide(),隐藏分享界面(这是在返回时进行的UI更新)。
  • 最后返回 uniShare.isShow,这是一个布尔值,表示分享界面是否可见。
onBackPress({ from }) {console.log(from);if (from == 'backbutton') {this.$nextTick(function() {uniShare.hide()})return uniShare.isShow;}
}

uniShare.show 配置说明

content: 定义了分享的基本内容,包括:
  • type: 分享类型,0 可能表示常规的链接分享。
  • href: 分享的目标链接。
  • title: 分享内容的标题。
  • summary: 分享内容的描述。
  • imageUrl: 分享的缩略图,要求是在线的图片URL。

在这里插入图片描述

menus: 定义了分享目标平台的配置。每个菜单项包括:
  • img: 该平台的图标(路径)。
  • text: 平台名称(显示的文字)。
  • share: 配置该平台的具体分享参数:
    • provider: 平台提供者,比如 weixinsinaweiboqq 等。
    • scene: 分享的场景(如 WXSceneSession 表示微信好友,WXSceneTimeline 表示微信朋友圈)。

对于微信小程序的分享,配置了 type: 5 以及 miniProgram 的详细信息,如小程序ID、路径、Web URL等。

cancelText: 设置分享取消按钮的文字。

回调函数:
e => { console.log(uniShare.isShow); console.log(e); 
}

完整代码

pages/index/index.vue

<template><button type="default" @click="uniShare">分享给好友</button>
</template>
<script>import UniShare from 'utils/uni-share.js';const uniShare = new UniShare();export default {onBackPress({ from }) {console.log(from);if (from == 'backbutton') {this.$nextTick(function() {uniShare.hide()})return uniShare.isShow;}},methods: {uniShare() {uniShare.show({content: { //公共的分享参数配置  类型(type)、链接(herf)、标题(title)、summary(描述)、imageUrl(缩略图)type: 0,href: 'https://blog.csdn.net/u011027547',title: '分享内容标题',summary: '分享内容~~~~~',// imageUrl: 必须是在线的url  本地文件没有成功imageUrl: 'https://img-cdn-aliyun.dcloud.net.cn/stream/icon/__UNI__HelloUniApp.png'},menus: [{"img": "/static/app-plus/sharemenu/wechatfriend.png","text": "微信好友","share": { //当前项的分享参数配置。可覆盖公共的配置如下:分享到微信小程序,配置了type=5"provider": "weixin","scene": "WXSceneSession"}},{"img": "/static/app-plus/sharemenu/wechatmoments.png","text": "微信朋友圈","share": {"provider": "weixin","scene": "WXSceneTimeline"}},{"img": "/static/app-plus/sharemenu/mp_weixin.png","text": "微信小程序","share": {provider: "weixin",scene: "WXSceneSession",type: 5,miniProgram: {id: '123',path: '/pages/list/detail',webUrl: '/#/pages/list/detail',type: 0},}},{"img": "/static/app-plus/sharemenu/weibo.png","text": "微博","share": {"provider": "sinaweibo"}},{"img": "/static/app-plus/sharemenu/qq.png","text": "QQ","share": {"provider": "qq"}},{"img": "/static/app-plus/sharemenu/copyurl.png","text": "复制","share": "copyurl"},{"img": "/static/app-plus/sharemenu/more.png","text": "更多","share": "shareSystem"}],cancelText: "取消分享",},e => { //callbackconsole.log(uniShare.isShow);console.log(e);})}}}
</script>

总结

大家喜欢的话,给个👍,点个关注!给大家分享更多计算机专业学生的求学之路!

版权声明:

发现你走远了@mzh原创作品,转载必须标注原文链接

Copyright 2024 mzh

Crated:2024-4-1

欢迎关注 『uniapp』 专栏,持续更新中
欢迎关注 『uniapp』 专栏,持续更新中
『未完待续』


http://www.xdnf.cn/news/627787.html

相关文章:

  • STM32上配置图像处理库时常见错误总结
  • 【IEEE 2025】低光增强KANT(使用KAN代替MLP)----论文详解与代码解析
  • Java——设计模式(Design Pattern)
  • DAY 35
  • Shell三剑客之awk
  • 全球化 2.0 | 云轴科技ZStack助力中东智慧城市高性能智能安防云平台
  • TypeScript小技巧使用as const:让类型推断更精准。
  • exti line2 interrupt 如何写中断回调
  • 数据库中表的设计规范
  • 【软考】【信息系统项目管理师】2025年5月24日考试回忆版,祝明天考试的兄弟们顺利
  • maxkey单点登录系统
  • Neo4j(二) - 使用Cypher操作Neo4j
  • iOS 直播特殊礼物特效实现方案(Swift实现,超详细!)
  • STM32F446主时钟失效时DAC输出异常现象解析与解决方案
  • AtCoder AT_abc407_d [ABC407D] Domino Covering XOR
  • 【Web前端】jQuery入门与基础(二)
  • 免费PDF工具-PDF24V9.16.0【win7专用版】
  • TypeScript基础数据类型详解总结
  • 常见的图像生成模型
  • 嵌入式开发学习日志(linux系统编程--进程(1))Day27
  • winsever2016Web服务器平台安装与配置
  • python训练营day34
  • TIT-2014《Randomized Dimensionality Reduction for $k$-means Clustering》
  • 第十天的尝试
  • 快速排序算法的C++和C语言对比
  • Python实用工具:文件批量重命名器
  • Unity3D仿星露谷物语开发49之创建云杉树
  • 常见算法题目3 -反转字符串
  • 2025年—ComfyUI_最新插件推荐及使用(实时更新)
  • 保姆式一步一步制作B端左侧菜单栏