写点什么

微信小程序转发朋友圈详解

2020 年 9 月 28 日

微信小程序转发朋友圈详解

在 2020 年 7 月 7 日微信小程序低调的开放了一个功能,微信小程序“分享到朋友圈”。最近被产品提了相关需求,过程中遇到了一些坑。作者带着踩坑经验,给大家介绍下这个功能,以及其如何实现。


概述

点击右上角分享朋友圈


分享到朋友圈样式


朋友圈打开样式


这个功能目前只支持 Android(在 IOS 高版本微信支持朋友圈打开小程序能力,但不能分享)。


用户打开朋友圈分享的小程序,看到不是真正的小程序,而是原本页面的“单页模式”。


什么是“单页模式”?

以下是微信官方对于“单页模式”的描述:


“单页模式”下,页面顶部固定有导航栏,标题显示为当前页面 JSON 配置的标题。底部固定有操作栏,点击操作栏的“前往小程序”可打开小程序的当前页面。顶部导航栏与底部操作栏均不支持自定义样式。

“单页模式”默认运行的是小程序页面内容,但由于页面固定有顶部导航栏与底部操作栏,很可能会影响小程序页面的布局。因此,请开发者特别注意适配“单页模式”的页面交互,以实现流畅完整的交互体验。


限制

另外,“单页模式”存在着很多限制。以下是官方给出的禁用能力列表:



限制主要包括以下几点:


  1. 页面无登录态,与登录相关的接口,如 wx.login 均不可用

  2. 不允许跳转到其它页面,包括任何跳小程序页面、跳其它小程序、跳微信原生页面

  3. 若页面包含 tabBar,tabBar 不会渲染,包括自定义 tabBar

  4. 本地存储与小程序普通模式不共用


这些限制,让 “单页模式”只适用于内容展示,不适用于有较多交互


配置

针对“单页模式”,新增了单页模式相关配置。目前这个配置里只有一个 navigationBarFit 属性:



navigationBarFit 属性主要是针对原页面设置了 自定义导航栏 的情况。也就是原页面的 json 文件中配置了这个属性:


{  // ...  "navigationStyle":"custom"  // ...}
复制代码


给大家看一下普通导航栏和自定义导航栏的区别,下图是普通导航栏页面:



下图是自定义导航栏页面,我们在原本的导航栏位置使用了 banner:



"navigationStyle":"custom"这个设置在“单页模式”下也会生效。前文微信官方对“单页模式”的描述有说到“顶部导航栏与底部操作栏均不支持自定义样式”。如果我们在原页面设置了自定义导航栏。那么“单页模式”样式就会变成这样:



通过设置 navigationBarFit 为 squeezed就可以解决这个问题:


{  // ...  "singlePage": {    "navigationBarFit": "squeezed"  }  // ...}
复制代码


设置后的样式:



开发


接下来介绍如何在小程序中实现这个功能。


第一步在需要转发朋友圈的页面中注册用户点击右上角转发功能,这是实现转发朋友圈功能的必要满足条件。


onShareAppMessage: function () {  return {    title: '转发标题',    path: '/pages/home/index',    imageUrl: '自定义图片路径'  }}
复制代码


第二步注册分享朋友圈功能(从基础库 2.11.3 开始支持):


onShareTimeline: function () {  return {    title: '转发标题',    query: 'from=pyq',    imageUrl: '自定义图片路径'  }}
复制代码


注意,这里有个问题,分享朋友圈功能不支持自定义页面路径,意味着 只能转发当前页面 。如果当前页面存在较多“单页模式”限制功能,就可能让我们的页面不能按预期展示。


当页面存在限制功能时,我们存在两个方案,第一个方案,针对“单页模式”做改动,不调用那些限制的功能。第二个方案,另外写一个针对“单页模式”的页面。


这两种方案都需要能判断当前是否正处在小程序“单页模式”。


我们通过判断场景值(场景值用来描述用户进入小程序的路径)是否等于 1154 来判断当前是否正处在小程序“单页模式”。场景值可以在 ApponLaunch 获取。


// app.js
App({ // ... onLaunch(options) { const { scene } = options; this.isSinglePage = scene === 1154; } // ...})
复制代码


我们将是否正处在“单页模式”的 Boolean 值放入 App 实例,方便全局拿到值。


接下来说说两种方案。


第一种方案,在“单页模式”不调用那些限制功能(这是一种不推荐的方案,代码耦合性太强)。举个例子:


const app = getApp();
Page({ // ... onLoad() { if (!app.isSinglePage) { wx.login({ // ... }) } } // ...})
复制代码


第二种方案,针对“单页模式”另写一个页面。因为分享朋友圈功能并不支持自定义页面路径,我们只能另外写一个组件来作为“单页模式”的内容承载。


将 isSinglePage 放入页面的初始数据,方便在 wxml 中拿到:


// pages/home/index.js
const app = getApp();
Page({ data: { isSinglePage: app.isSinglePage, } // ...})
复制代码


home-single-page 就是分享到朋友圈的内容承载组件:


// pages/home/index.json{  // ...  "usingComponents": {    "home-single-page": "components/home-single-page/index"  },}  
复制代码


当“单页模式”时,我们展示 home-single-page组件,否则就展示普通页面内容:


// pages/home/index.wxml
<home-single-page wx:if="{{ isSinglePage }}" /><view wx:else> <!-- 普通页面内容 --></view>
复制代码


样式上虽然搞定了,但是在原本的生命周期中可能会调用一些限制功能,或者跑一些其它“单页模式”用不上的内容。我们得停止原本生命周期函数调用。


建议对传入 Page 的对象进行统一处理,当“单页模式”时,不调用原本的生命周期:


// pages/home/index.jsimport ExtendPage from 'common/extend-page/index'
const app = getApp();
ExtendPage({ data: { isSinglePage: app.isSinglePage, } // ...})
复制代码


ExtendPage 函数针对“单页模式”进行统一处理:


// common/extend-page/index.js
const app = getApp();
const PAGE_LIFE = [ 'onLoad', 'onReady', 'onShow', 'onHide', 'onError', 'onUnload', 'onResize', 'onPullDownRefresh', 'onReachBottom', 'onPageScroll'];
export default function(option) { let newOption = {};
if(app.isSinglePage) { newOption = PAGE_LIFE.reduce((res, lifeKey) => { if (option[lifeKey]) { res[lifeKey] = undefined; } return res; }, {}) }
return Page({ ...option, ...newOption, });}
复制代码


在“单页模式”下,我们将原本的生命周期都停止了调用。这样就能很好的将“单页模式”下的页面和普通页面进行解耦。


如果”单页模式“页面比较复杂,需要使用生命周期。我们也可以添加 singlePageLife属性,当处在“单页模式”下,就调用 singlePageLife内的生命周期:


// pages/home/index.jsimport ExtendPage from 'common/extend-page/index'
const app = getApp();
ExtendPage({ data: { isSinglePage: app.isSinglePage, }, singlePageLife: { onLoad() { // ... }, } // ...})
复制代码


// common/extend-page/index.jsconst app = getApp();
const PAGE_LIFE = [ 'onLoad', 'onReady', 'onShow', 'onHide', 'onError', 'onUnload', 'onResize', 'onPullDownRefresh', 'onReachBottom', 'onPageScroll'];
export default function(option) { let newOption = {};
if(app.isSinglePage) { const { singlePageLife } = option; newOption = PAGE_LIFE.reduce((res, lifeKey) => { if (singlePageLife[lifeKey]) { res[lifeKey] = singlePageLife[lifeKey]; } else if(option[lifeKey]) { res[lifeKey] = undefined; } return res; }, {}) }
return Page({ ...option, ...newOption, });}
复制代码


文章如有疏漏、错误欢迎批评指正。


本文转载自公众号有赞 coder(ID:youzan_coder)。


原文链接


微信小程序转发朋友圈详解


2020 年 9 月 28 日 14:071451

评论

发布
暂无评论
发现更多内容

Java中23种设计模式详解:七大结构型模式详细分析

攻城狮Chova

设计模式 结构化思维 6 月日更

全面赋能泛娱乐社交场景

anyRTC开发者

音视频 WebRTC 实时音视频 泛娱乐社交 音视频解决方案

向996宣战!快乐工作,健康生活的互联网要来了吗?

架构精进之路

话题讨论 话题 996 6 月日更

阿里P9封神之作!RocketMQ核心笔记疯传Ali内网

周老师

Java 编程 程序员 架构 面试

Java程序员:为了跳槽刷完1000道真题,没想到老板直接给我升职了

菜菜山

Java 程序员 架构 面试

一文讲全了Python类和对象内容

华为云开发者社区

Python

重塑价值:新一代ITSM平台的建设、咨询与实施

云智慧技术社区

ITSM 智能运维

校友会小程序开发笔记五:找校友功能模块设计与实现

CC同学

校友录小程序

阿里P8熬了一个月肝出这份32W字Java面试手册,在Github标星31K+

周老师

Java 编程 程序员 架构 面试

第一次见家长送禧大福酒好吗?

Geek_50a546

TcaplusDB软件和硬件环境建议配置

数据人er

数据库 nosql tencentdb TcaplusDB

Linux 中实用但很小众的 11 个炫酷终端命令

学神来啦

云计算 Linux 运维 linux运维 网络运维

ipfs挖矿是怎样赚钱的?ipfs挖矿值得投资吗?

投资矿机v:IPFS1234

IPFS挖矿值得投资吗 IPFS挖矿是怎样赚钱的

ipfs收益是怎么计算的?ipfs矿机一天收益是多少?

投资矿机v:IPFS1234

ipfs收益是怎么计算的 ipfs矿机一天收益是多少

朋友乔迁住新房 禧大福酒竟成为宴席最大赢家

Geek_50a546

技术实践 | 如何基于 Flink 实现通用的聚合指标计算框架

网易云信

框架 flink 执行

TcaplusDB祝天下所有父亲节日快乐!

TcaplusDB

nosql Data tencentdb TcaplusDB

[TcaplusDB]行业新闻汇编(6月17日)

数据人er

数据库 nosql 游戏 tencentdb TcaplusDB

算法导论的道与术、工程师思维奠定能走多远-John 易筋 ARTS 打卡 Week 51

John(易筋)

ARTS 打卡计划

阿里内部“SpringCloudAlibaba学习笔记”来了

菜菜山

Java 程序员 架构 微服务

Java 连接操作 MySQL 数据库(增删查改操作)

若尘

MySQL 数据库 java编程 驱动 六月日更

TcaplusDB小知识之TcaplusDB架构简介

数据人er

数据库 nosql tencentdb TcaplusDB

TcaplusDBx 黎明觉醒|一路相伴,不负期待

TcaplusDB

nosql tencentdb TcaplusDB

YURO空投来袭,这个NFT+IPFS的艺术品平台何方神圣?

区块链小八歌

YURO空投来袭,这个NFT+IPFS的艺术品平台何方神圣?

股市老人币圈新

四面字节跳动Java研发岗,最终拿下Offer,只有努力,方能成功

周老师

Java 编程 程序员 架构 面试

网络研讨会|想弄明白应用安全?我们为你准备了5个锦囊!

鉴释

DevSecOps 安全编码规范 应用安全 静态分析

用 Go struct 不能犯的一个低级错误!

煎鱼

go Go 语言 Go 语言从入门到实践

保姆级教学,22张图揭开ThreadLocal

程序猿阿星

内存泄露 ThreadLocal 线程安全 弱引用 ThreadLocalMap

【TcaplusDB】世界难民日——愿所有人都被温柔以待

TcaplusDB

数据库 nosql tencentdb TcaplusDB

公安情指勤合成作战系统搭建,情报指挥系统搭建

13823153121

技术为帆,纵横四海- Lazada技术东南亚探索和成长之旅

技术为帆,纵横四海- Lazada技术东南亚探索和成长之旅

微信小程序转发朋友圈详解-InfoQ