当前位置: 首页 > Web前端 > vue.js

Vue微信开发优雅实现微信分享

时间:2023-03-31 15:15:15 vue.js

前言微信分享主要是把我们做的网页分享给朋友或者分享到朋友圈。发送给好友时,显示的消息不是丑陋的URL,而是带有图文描述的特殊模板消息。很多具有较强通信属性的网页都会利用这个特性来提高通信性能。要实现这个功能,我们需要接入微信的JS-SDK。什么是JS-SDK?官方文档如下:WeChatJS-SDK是微信公众平台为Web开发者提供的基于微信的Web开发工具包。通过使用微信JS-SDK,Web开发者可以通过微信高效使用手机系统的拍照、选图、语音、定位等能力,同时直接使用微信独有的分享、扫一扫、优惠券和付款。,为微信用户提供更好的网络体验。可以看到,JS-SDK可以做的事情很多,那么今天,我们就来聊一聊微信分享的细节。如果还需要实现微信授权登录相关的功能,可以查看作者的分享:Vue微信开发优雅实现授权登录准备第一步。不用说,先看官方文档也是很有必要的。文档地址如下:微信开发JS-SDK使用手册这里需要特别说明的是,开发前需要先登录微信公众平台,进入“公众号设置”的“功能设置”,填写“JS接口安全域名”。这个任务不能忘记,必须牢记。使用JS-SDK还有一个关键环节,就是通过config接口注入权限验证配置,而配置中有一个签名参数需要从服务端获取,所以我们还是要跪舔一个一波后端小伙伴在开发的时候给它。支持(全栈评委只当我没说)。看过文档的读者应该能理清我们接入微信分享的具体过程。笔者整理如下:介绍JS-SDK;通过调用后端接口获取签名,签名算法见本页;调用wx.config方法注入相关配置;调用相关的分享API,传入相应的分享信息;这里笔者以一个微信漂流瓶功能的实现为例,分享一下编码过程;技术栈采用Vue3+typescript,Vue2的开发者也请根据情况适当调整。导入JS-SDK官方文档的描述是导入js-sdk文件,也就是通过脚本的方式,但是我们现在是一个Vue应用,是否可以通过npm仓库安装,通过ESModule导入方法?当然可以,安装命令如下://js版本yarnaddweixin-js-sdk//ts版本yarnaddweixin-js-sdk-ts笔者这里安装的是ts版本,安装后会显示在package.json中,本着功能解耦和方便复用的原则,作者决定单独创建一个文件来封装js-sdk相关的功能。在vue3中当然是封装成hook了。因此,我们在hooks目录下新建了一个useWxSDK.ts文件;然后,我们开始封装第一个方法,即wx.config/***初始化设置*/functioninitConfig(configInfo){returnnewPromise((resolve)=>{wx.config({debug:false,appId:configInfo.appId,时间戳:configInfo.timestamp,nonceStr:configInfo.no??nceStr,签名:configInfo.signature,jsApiList:configInfo.jsApiList??['chooseImage','uploadImage','previewImage','onMenuShareTimeline','onMenuShareAppMessage','chooseWXPay',],openTagList:[],})wx.ready(()=>{resolve(true)})})}这里解释wx。config方法,为什么要封装成Promise?其实我们可以看到JS-SDK的API设计还是比较原始的。我们需要通过wx.ready注册配置成功后的回调函数。作者在这里用Promise进行了封装。在回调函数中调用Promise.resolve,那么我们在使用的时候,可以使用优雅的then语法实现配置成功后的操作!接下来封装分享好友和微信朋友圈的方法:/**设置微信分享*/functionsetShareInfo(shareInfo,onSuccess,onCancel){wx.onMenuShareTimeline({title:shareInfo.title,//分享标题link:shareInfo.link,//分享链接,可能不是当前页面,链接连接的域名或路径必须与当前页面对应的公众号JS安全域名一致imgUrl:shareInfo.imgUrl,success:function(){//用户确认分享后回调函数onSuccess()},cancel:function(){onCancel()//用户取消分享后执行的回调函数},})wx.onMenuShareAppMessage({title:shareInfo.title,//分享标题desc:shareInfo.desc,link:shareInfo.link,//分享链接,可以不是当前页面,链接域名或路径必须与当前页面对应的公众号JS安全域名一致imgUrl:shareInfo.imgUrl,type:'link',//分享type,music,videoorlink,不填默认为链接success:function(){//用户确认分享后执行的回调函数onSuccess()},cancel:function(){//onCancel回调函数()在用户取消分享后执行},})}接下来开始构建考虑shar的操作ing,积木会在多个页面复用,所以需要抽象一个分享方法,这样在需要微信分享的地方可以直接调用这个方法。因此,作者新建了一个useWxShare.ts文件import{getJsSDKConfigApi}from"@/api/wechat";import{useWxSDK}from"@/hooks/useWxSDK";exportfunctionuseWxShare(shareConfig:{title:string;imgUrl:string;desc:string;}){const{initConfig,setShareInfo}=useWxSDK();constshareUrl=window.location.href.split("#")[0];getJsSDKConfigApi(shareUrl).then((config)=>{//调用后端接口获取config相关信息initConfig(config).then(()=>{//成功注入wx.config后,设置微信分享相关setShareInfo({...shareConfig,link:shareUrl,});});});}至此,封装就完成了,接下来,我们到页面组件中,在挂载的函数中调用这个方法,然后坑修到此结束?当然不是,这里有一个大坑,笔者在之前的博客中也分享过,就是如果我们的页面以VueRouter的历史模式路由,在某些情况下,在iOS设备上分享会失败的问题.举个栗子。假设我们都是通过http://domain.com进入,然后跳转到路由为/share的页面,需要用到jssdk,那么js-sdk进行验签时实际得到的页面url在ios和ios之间是不一样的andrioid是的,安卓上没有问题,js-sdk验证的url就是当前页面的url,就是http://domain.com/share。在iOS上,js-sdk验证的url是我们第一次进入页面时的url,是http://domain.com,但是我们后台签名使用的是当前页面的url,这就导致了iOS,签名验证没有成功。那么如何处理呢?笔者这里采用的方法是在入口文件或者根组件中记录当前页面的URL。页面组件创建完成后,ios获取记录的url进行签名,android获取当前路由。所以填坑如下:{name:'App',setup(){const{isiOSWechat}=useWxSDK()//如果检测到ios微信,则在store中记录入口页面地址if(isiOSWechat()){consturl=window.location.href.split('#')[0]commonStore.saveVisitUrl(url)}},})@/hooks/useWxSDK.ts/**是否是ios微信*/functionisiOSWechat(){return(任何窗口).__wxjs_is_wkwebview}@/hooks/useWxShare.tsimport{getJsSDKConfigApi}from'@/api/wechat'import{useWxSDK}from'@/common/hooks/useWxSDK'import{commonStore}from'@/store/modules/common'exportfunctionuseWxShare(shareConfig:{title:string;imgUrl:string;desc:string}){const{initConfig,setShareInfo,isiOSWechat}=useWxSDK()constshareUrl=window.location.href.split('#')[0]//对签名进行特殊判断urlconstsignatureUrl=isiOSWechat()?commonStore.commonState.visitUrl:shareUrlgetJsSDKConfigApi(signatureUrl).then((config)=>{initConfig(config).then(()=>{setShareInfo({...shareConfig,link:shareUrl,})})})复制代码}@/store/modules/common.tsimport{Module,VuexModule,Mutation,getModule}from'vuex-module-decorators'importstorefrom'@/store'import{initialUnencryptedStorage}from'../globals'interfaceCommonState{/**ios微信,访问时记录页面url*/visitUrl:string}constNAME='common'@Module({namespaced:true,name:NAME,dynamic:true,store,preserveState:Boolean(initialUnencryptedStorage[NAME]),})导出类CommonextendsVuexModule{commonState:CommonState={visitUrl:'',}@MutationsaveVisitUrl(url:string):void{this.commonState.visitUrl=url}}exportconstcommonStore=getModule(Common)看效果首先我们用微信开发工具看一下效果。首先,输入我们项目的地址并打开它。可以看到获取config信息的请求已经成功发送并返回。然后看控制台。控制台显示wx.config的配置日志和settingsharing的日志,这个意思就是我如果我们的分享配置成功,点击右上角的分享。如果我们配置的分享标题可以显示,那就没有问题。最后还是得在真机上试试。真机分享后效果如下:需要体验的朋友可以微信扫描下方二维码。同时,作者在Github上托管了该项目的代码。欢迎各位朋友点击此链接获取摘要。其实微信分享的功能比较简单。难点在于如何正确处理JS-SDK在单页应用中的一些陷阱。另外就是代码组织和封装的问题。看过很多项目,但对代码复用和抽象的关注度不高。结果整个项目全是复制粘贴的重复代码,看起来非常臃肿。作者这样抽象解耦后,调用层只需要一个简单的函数,是不是格外优雅?写在最后,最近有点闲。打算用Vue3+ts+vant从零开始完成一个公众号应用,分享一下开发过程。也算是一种激励自己继续学习的方式。如果您有想法和建议,欢迎和我一起讨论。同时,为了方便大家更好的讨论微信公众号开发相关技术,笔者还建立了一个微信群,欢迎加入,与大家一起学习成长。微信扫描下方二维码申请入群。