【小程序】766- 一文看懂小程序分享到朋友圈
點(diǎn)擊上方 關(guān)注我們?

作者簡(jiǎn)介
張所勇
轉(zhuǎn)轉(zhuǎn)平臺(tái)運(yùn)營(yíng)中心前端負(fù)責(zé)人,在前端領(lǐng)域有深入研究,包括:sketch一鍵切圖、前端數(shù)據(jù)模型化,小程序基礎(chǔ)能力建設(shè)等多個(gè)方面,10年工作經(jīng)驗(yàn)中,做了2年工程師,5年CEO,3年技術(shù)管理,2018年度掘金優(yōu)秀作者。
背景
近日小程序支持分享到朋友圈的消息可以說(shuō)是小程序開(kāi)發(fā)圈的一個(gè)重磅炸彈,轉(zhuǎn)轉(zhuǎn)小程序團(tuán)隊(duì)也在收到微信邀請(qǐng)后第一時(shí)間進(jìn)行了調(diào)研,并對(duì)轉(zhuǎn)轉(zhuǎn)小程序迅速進(jìn)行了能力支持,本文將全面解讀微信此項(xiàng)能力。
概述
此項(xiàng)能力其實(shí)分成兩個(gè)模塊:
1、小程序分享到朋友圈能力

2、朋友圈打開(kāi)小程序的能力
分享到朋友圈的樣式
朋友圈里面打開(kāi)的樣式
開(kāi)發(fā)
我們也分兩個(gè)模塊來(lái)看:
1、小程序分享到朋友圈能力
在小程序界面顯示分享到朋友圈按鈕的能力,目前要求如下:
1.安卓平臺(tái):
要求微信版本7.0.16及以上,基礎(chǔ)庫(kù)2.11.13及以上,筆者在測(cè)試中發(fā)現(xiàn),此項(xiàng)能力也跟機(jī)型有關(guān),目前發(fā)現(xiàn)OPPO一款機(jī)型無(wú)分享到朋友圈按鈕,小米機(jī)型均有此項(xiàng)能力。
2.IOS平臺(tái):
目前還不支持此項(xiàng)能力,但高版本微信支持朋友圈打開(kāi)小程序能力(下文述)
小程序頁(yè)面默認(rèn)不開(kāi)啟分享到朋友圈按鈕,除非代碼中主動(dòng)設(shè)置:
1.頁(yè)面需設(shè)置允許“發(fā)送給朋友”,代碼示例:
onShareAppMessage()?{
????return?{
??????title:?'買(mǎi)賣(mài)二手,省錢(qián)又賺錢(qián)!轉(zhuǎn)轉(zhuǎn),一個(gè)幫你賺錢(qián)的網(wǎng)站!',
??????path:?'/pages/index/index',
??????imageUrl:'https://pic5.zhuanstatic.com/zhuanzh/n_v2be00a9c4aa4941bf8567f5fd999e2709.png',
????}
}
2.頁(yè)面需設(shè)置允許“分享到朋友圈”,代碼示例:
onShareTimeline()?{
??return?{
????title:?'[小程序]?買(mǎi)賣(mài)二手,省錢(qián)又賺錢(qián)!轉(zhuǎn)轉(zhuǎn),一個(gè)幫你賺錢(qián)的網(wǎng)站!',
????query:?'zzfrom=pyq'
??}
}
3.開(kāi)啟分享菜單中的“分享到朋友圈”按鈕:
wx.showShareMenu({
??????withShareTicket:?true,
??????menus:?['shareAppMessage',?'shareTimeline']
})
這項(xiàng)要求微信在文檔中并沒(méi)有提到,但實(shí)測(cè)發(fā)現(xiàn)必須調(diào)用此方法才能出現(xiàn)分享到朋友圈按鈕
其中:
1.最新版微信開(kāi)發(fā)者工具支持此項(xiàng)能力的模擬調(diào)試?
2.存在 web-view 組件的頁(yè)面不支持發(fā)起分享
3.onShareTimeline是自基礎(chǔ)庫(kù)2.11.3開(kāi)始新增的頁(yè)面生命周期,行為與onShareAppMessage類(lèi)似
4.該生命周期需返回Object,用于自定義分享內(nèi)容,其中:
title:分享標(biāo)題,默認(rèn)去小程序名稱(chēng) query:分享出去的頁(yè)面上攜帶的參數(shù),用于標(biāo)示渠道來(lái)源等 imageUrl:分享圖片,默認(rèn)使用小程序logo
5.特別強(qiáng)調(diào):分享到朋友圈不支持path參數(shù),也就是說(shuō)用戶(hù)在哪個(gè)頁(yè)面發(fā)起分享,分享出去的就是哪個(gè)頁(yè)面,這就要求開(kāi)發(fā)者對(duì)分享頁(yè)面進(jìn)行一些適配,因?yàn)槲覀兎窒淼脚笥讶Φ捻?yè)面,用戶(hù)打開(kāi)時(shí)會(huì)進(jìn)入一個(gè)“單頁(yè)模式”,在此模式下,很多sdk無(wú)法使用。
2、朋友圈打開(kāi)小程序的能力
用戶(hù)在朋友圈打開(kāi)分享的小程序頁(yè)面,并不會(huì)真正打開(kāi)小程序,而是進(jìn)入一個(gè)原本頁(yè)面的“單頁(yè)模式”的頁(yè)面,上文提到,用戶(hù)分享的原始頁(yè)面和朋友圈打開(kāi)的“單頁(yè)模式”頁(yè)面,其實(shí)對(duì)開(kāi)發(fā)者來(lái)講是同一個(gè)頁(yè)面,為了區(qū)分,微信給出了兩個(gè)新的場(chǎng)景值:
1154:朋友圈打開(kāi)小程序,也就是正處在“單頁(yè)模式”,開(kāi)發(fā)者可以根據(jù)這個(gè)場(chǎng)景值進(jìn)行適配,理論上除此場(chǎng)景值外,都是正常模式。
1155:從“單頁(yè)模式”進(jìn)入正常模式,由于此項(xiàng)行為是微信統(tǒng)一行為,開(kāi)發(fā)者無(wú)法進(jìn)行標(biāo)記,如果想對(duì)此項(xiàng)行為進(jìn)行統(tǒng)計(jì),可以使用該場(chǎng)景值。
“單頁(yè)模式”需要適配什么呢?
微信官方對(duì)“單頁(yè)模式”有以下解釋?zhuān)?/p>
1.“單頁(yè)模式”下,頁(yè)面頂部固定有導(dǎo)航欄,標(biāo)題顯示為分享時(shí)的標(biāo)題。底部固定有操作欄,點(diǎn)擊操作欄的“前往小程序”可打開(kāi)小程序的當(dāng)前頁(yè)面。頂部導(dǎo)航欄與底部操作欄均不支持自定義樣式。
樣式參考下圖

這兩處的樣式是無(wú)法自定義的。
其中,用戶(hù)只能通過(guò)下方“前往小程序”按鈕進(jìn)入正常模式。
如果小程序使用了自定義導(dǎo)航頭部,則需要進(jìn)行一定的適配,比如我司小程序,頂部使用了自定義背景,適配前是這樣:

由于頂部title欄微信有固定樣式,因此我們?cè)陬^部加了一個(gè)灰色背景進(jìn)行遮擋。

2.“單頁(yè)模式”默認(rèn)運(yùn)行的是小程序頁(yè)面內(nèi)容,但由于頁(yè)面固定有頂部導(dǎo)航欄與底部操作欄,很可能會(huì)影響小程序頁(yè)面的布局。因此,請(qǐng)開(kāi)發(fā)者特別注意適配“單頁(yè)模式”的頁(yè)面交互,以實(shí)現(xiàn)流暢完整的交互體驗(yàn)。
在app.json中新增了對(duì)單頁(yè)模式的配置項(xiàng):
"singlePage"?:?{
??"navigationBarFit"?:?""?//float或squeezed
}
該項(xiàng)配置可以設(shè)置頂部默認(rèn)title欄的表現(xiàn),其中:
默認(rèn)值:
如果頁(yè)面使用了自定義導(dǎo)航欄模式,則此項(xiàng)默認(rèn)為:float,意為導(dǎo)航欄浮在頁(yè)面上,不對(duì)原本頁(yè)面布局產(chǎn)生影響(但可能遮擋原本頁(yè)面部分元素) 如果否則默認(rèn)為:squeezed,表示頁(yè)面被導(dǎo)航欄擠壓,與頁(yè)面不相交,也就是在頁(yè)面頂部留出固定空間放微信的導(dǎo)航欄,原本頁(yè)面將往下移動(dòng)
當(dāng)然這兩個(gè)值也可以根據(jù)頁(yè)面需要而設(shè)置不同值。
還有一點(diǎn)需要注意:
單頁(yè)模式下,wx.getSystemInfo 接口返回的 safeArea 為整個(gè)屏幕空間,例如:
在iPhone6下,屏幕尺寸為375x667
在單頁(yè)模式下,safeArea的高度為:667 在正常模式下,safeArea的高度為:647
如果有依賴(lài)safeArea布局的頁(yè)面需要進(jìn)行適配。
3.“單頁(yè)模式”下,一些組件或接口存在一定限制
這一點(diǎn)是單頁(yè)模式適配最麻煩的地方,我們先看哪些組件和接口無(wú)法使用
(可跳過(guò)直接看下面總結(jié))
| 分類(lèi) | 功能點(diǎn) |
|---|---|
| 組件 | button open-type 、 camera 、 editor 、 form 、 functional-page-navigator 、 live-pusher 、 navigator 、 navigation-bar 、 official-account 、 open-data 、 web-view |
| 路由 | wx.redirectTo 、 wx.reLaunch 、 wx.navigateTo 、 wx.switchTab 、 wx.navigateBack |
| 界面 | 導(dǎo)航欄 、 Tab Bar |
| 網(wǎng)絡(luò) | mDNS 、 UDP 通信 |
| 界面 | 導(dǎo)航欄 、 Tab Bar |
| 數(shù)據(jù)緩存 | 周期性更新 |
| 媒體 | VoIP 、 wx.chooseMedia 、 wx.chooseImage 、 wx.saveImageToPhotosAlbum 、 wx.chooseVideo 、 wx.saveVideoToPhotosAlbum 、 wx.getVideoInfo 、 wx.compressVideo |
| 位置 | wx.openLocation 、 wx.chooseLocation 、 wx.startLocationUpdateBackground 、 wx.startLocationUpdate |
| 轉(zhuǎn)發(fā) | wx.getShareInfo 、 wx.showShareMenu 、 wx.hideShareMenu 、 wx.updateShareMenu |
| 文件 | wx.openDocument |
| 開(kāi)放接口 | 登錄 、 小程序跳轉(zhuǎn) 、 用戶(hù)信息 、 支付 、 授權(quán) 、 設(shè)置 、 收貨地址 、 卡券 、 發(fā)票 、 生物認(rèn)證 、 微信運(yùn)動(dòng) 、 微信紅包 |
| 設(shè)備 | 藍(lán)牙 、 iBeacon 、 Wi-Fi 、 NFC 、 聯(lián)系人 、 剪貼板 、 電話(huà) 、 掃碼 |
| 廣告 | ad 、 wx.createRewardedVideoAd 、 wx.createInterstitialAd |
在單頁(yè)模式下禁用的能力非常多,我們可以理解為:單頁(yè)模式下僅允許內(nèi)容展示和UI交互,不允許任何互動(dòng)或操作
其中,給我們影響最大的有:
登錄
在單頁(yè)模式下調(diào)用wx.login將不會(huì)成功,也就是說(shuō)我們的頁(yè)面需要支持非登錄態(tài)下的展示(即便是靜默登錄也不支持)
對(duì)此,轉(zhuǎn)轉(zhuǎn)小程序在改造時(shí)比較簡(jiǎn)單:
if(this.scene?==?1154)?{
??this.$httpWithLogin?=?this.$http
}
即直接在單頁(yè)模式下,將所有接口請(qǐng)求方法改寫(xiě)為無(wú)需登錄態(tài)的請(qǐng)求方式。
對(duì)于此項(xiàng)限制,不同的小程序頁(yè)面需要進(jìn)行針對(duì)性處理。
跳轉(zhuǎn)
單頁(yè)模式下,不支持任何頁(yè)面跳轉(zhuǎn)方法,也就是說(shuō),用戶(hù)無(wú)法離開(kāi)當(dāng)前頁(yè),除非點(diǎn)擊“前往小程序”按鈕,回到正常模式。
其他
微信提供此項(xiàng)能力的初衷就是希望能在朋友圈展示更多內(nèi)容,而不希望用戶(hù)直接進(jìn)入小程序,但單頁(yè)模式下的限制太多了,無(wú)法一一進(jìn)行改造,筆者的建議是,解決阻礙頁(yè)面正常顯示的問(wèn)題和阻礙核心頁(yè)面流程的問(wèn)題即可,在使用不支持的能力時(shí),微信會(huì)進(jìn)行如下處理:
如果用戶(hù)有點(diǎn)擊行為,則微信會(huì)統(tǒng)一toast:‘請(qǐng)前往小程序使用完整服務(wù)’
如果沒(méi)有點(diǎn)擊行為,該方法會(huì)進(jìn)入調(diào)用失敗邏輯:

注意:
在單頁(yè)模式下,依然支持不離開(kāi)頁(yè)面的各種交互,比如tab、幻燈片等 在單頁(yè)模式下,只有底部“前往小程序”按鈕可以進(jìn)入到正常小程序 在單頁(yè)模式下,支持再次被分享到朋友圈,也支持發(fā)送給朋友(同小程序卡片,打開(kāi)會(huì)進(jìn)入正常小程序) 云開(kāi)發(fā)資源需開(kāi)啟未登錄訪(fǎng)問(wèn)方可在單頁(yè)模式下使用:
默認(rèn)情況下云開(kāi)發(fā)資源不允許未登錄訪(fǎng)問(wèn),需要在云控制臺(tái) - 設(shè)置 - 全局設(shè)置中手動(dòng)為云環(huán)境開(kāi)啟允許未登錄訪(fǎng)問(wèn)。
并且在未登錄模式下,C 端權(quán)限控制必須使用安全規(guī)則,即云函數(shù)、數(shù)據(jù)庫(kù)和文件存儲(chǔ)的訪(fǎng)問(wèn)都必須通過(guò)安全規(guī)則,因此控制臺(tái)設(shè)置時(shí)除了開(kāi)啟允許未登錄訪(fǎng)問(wèn)云環(huán)境外,還必須在云函數(shù)、數(shù)據(jù)庫(kù)和文件存儲(chǔ)分別的權(quán)限設(shè)置中選擇安全規(guī)則并配置。未登錄用戶(hù)訪(fǎng)問(wèn)時(shí),安全規(guī)則的 auth 字段為空,可以此判斷請(qǐng)求來(lái)自未登錄用戶(hù)的訪(fǎng)問(wèn)。
不允許橫屏使用 若頁(yè)面包含 tabBar,tabBar 不會(huì)渲染,包括自定義 tabBar 本地存儲(chǔ)與小程序普通模式不共用,這一點(diǎn)決定了單頁(yè)模式和正常模式,互通的唯一途徑就是1155這個(gè)場(chǎng)景值
低版本兼容
分享到朋友圈按鈕:低版本微信目前無(wú)法出現(xiàn)該按鈕
朋友圈打開(kāi)小程序:低版本微信打開(kāi)朋友圈會(huì)進(jìn)入一個(gè)升級(jí)提示頁(yè),不過(guò)這是一個(gè)基礎(chǔ)庫(kù)逐漸覆蓋的過(guò)程,據(jù)發(fā)稿時(shí),實(shí)測(cè)發(fā)現(xiàn)iOS微信7.0.14版本即可正常顯示單頁(yè)模式。
常見(jiàn)問(wèn)題
1、按照文檔設(shè)置了,但并沒(méi)有出現(xiàn)分享到朋友圈按鈕
可能的解決方案有:
調(diào)用wx.showShareMenu方法開(kāi)啟菜單 更換調(diào)試設(shè)備
2、單頁(yè)模式無(wú)法正常打開(kāi)
首先建議使用真機(jī)調(diào)試對(duì)單頁(yè)模式進(jìn)行調(diào)試
其次檢查是否有關(guān)鍵流程被限制的sdk能力阻斷
最后檢查頁(yè)面報(bào)錯(cuò)
3、shareImageMessage錯(cuò)誤

該錯(cuò)誤的是因?yàn)槲⑿旁趩雾?yè)模式下新增了一個(gè)內(nèi)部方法:wx.shareImageMessage,并且微信禁止了該方法的讀取/枚舉權(quán)限,否則就會(huì)直接報(bào)錯(cuò),社區(qū)里面很多開(kāi)發(fā)者遇到了這個(gè)錯(cuò)誤,轉(zhuǎn)轉(zhuǎn)小程序也遇到了,核心原因都是在于:
頁(yè)面代碼或者第三方框架/插件中含有對(duì)wx拷貝的操作,類(lèi)似:
Object.assign({},wx)
我們需要找到此類(lèi)代碼并進(jìn)行兼容,示例如下:
//先將報(bào)錯(cuò)方法設(shè)置為不可枚舉
for?(let?key?in?wx)?{
????try?{
??????if(wx[key])?{}
????}catch(e)?{
??????Object.defineProperty(wx,key,{
????????enumerable:false
??????});
????}
}
Object.assign({},wx)
當(dāng)用戶(hù)短時(shí)間內(nèi)第二次進(jìn)入朋友圈分享的小程序單頁(yè)時(shí),會(huì)存在一定的緩存(也可以說(shuō)該單頁(yè)實(shí)例還駐留在內(nèi)存里):
我們定義的一些變量值被緩存下來(lái)了,但依然會(huì)觸發(fā)Page的各個(gè)生命周期。
這會(huì)導(dǎo)致一些問(wèn)題,比如我們通過(guò)一個(gè)在Page方法外的普通變量來(lái)記錄頁(yè)面吸頂狀態(tài):
let?isSticky?=?false
Page({
??onShow(){
????//第二次進(jìn)入時(shí),isSticky?==?true
????if(!isSticky){
??????//do?sth
??????isSticky?=?true
????}
??}
})
以上就是關(guān)于小程序分享到朋友圈這項(xiàng)能力開(kāi)發(fā)上的經(jīng)驗(yàn)和解讀,期望能夠幫助到各位讀者朋友。
筆者看法
最后,筆者也想談?wù)剬?duì)這項(xiàng)能力的看法。
微信提供這項(xiàng)能力,可以解決目前小程序從朋友圈回流效果差的問(wèn)題,之前小程序想分享到朋友圈,幾乎唯一的方式是生成一個(gè)圖片二維碼并分享出去,不過(guò)以筆者經(jīng)驗(yàn),這種方式回流效果越來(lái)越差,這極大限制了小程序在朋友圈的傳播能力,微信想解決這個(gè)問(wèn)題,但又非常克制,微信不希望用戶(hù)從朋友圈直接進(jìn)入小程序,而是提供的單頁(yè)模式,旨在期望給用戶(hù)更多的內(nèi)容展示,通過(guò)內(nèi)容吸引用戶(hù)進(jìn)入小程序,雖然與我們的期待有一些落差,但這項(xiàng)能力確實(shí)對(duì)小程序在朋友圈的傳播會(huì)有很大的促進(jìn)作用,相信會(huì)有越來(lái)越多的小程序支持此項(xiàng)能力。
點(diǎn)擊體驗(yàn):
【前端1分鐘】本視頻通過(guò) 1分鐘動(dòng)畫(huà),帶你了解 Axios 攔截器實(shí)現(xiàn)原理。?
原創(chuàng)不易,如果覺(jué)有對(duì)你有幫助,還請(qǐng)點(diǎn)擊“點(diǎn)贊”和“看一看”,分享給更多小伙伴~?

回復(fù)“加群”與大佬們一起交流學(xué)習(xí)~
點(diǎn)擊“閱讀原文”查看 80+ 篇原創(chuàng)文章

