2025上半年,最新 AI实践都在这!20+ 应用案例,任听一场议题就值回票价 了解详情
写点什么

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

  • 2020-09-28
  • 本文字数:3026 字

    阅读完需:约 10 分钟

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

在 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-09-28 14:073648

评论

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

【Django | allauth】登录_注册_邮箱验证_密码邮箱重置

计算机魔术师

8月月更

【高并发】亿级流量场景下如何为HTTP接口限流?看完我懂了!!

冰河

并发编程 多线程 高并发 协程 异步编程

[JS入门到进阶] 手写裁剪图片的工具,并部署。一键裁剪掘金文章封面

HullQin

CSS JavaScript html 前端 8月月更

HMS Core基于地理位置请求广告,流量变现快人一步

HarmonyOS SDK

广告sdk

悲观锁和乐观锁的区别以及实现方式

浅羽技术

乐观锁 悲观锁 8月月更

云原生(三十) | Kubernetes 篇之应用商店 -Helm 介绍

Lansonli

云原生 8月月更

mysql 的索引分类 B + 和 hash 详解

浅羽技术

MySQL 索引 hash B+树 8月月更

前后端数据接口协作提效实践

百度Geek说

Java 数据 企业号九月金秋榜

Flomesh 发布 Pipy 0.50.0

Flomesh

流支付时代的Zebec,将打开Web3支付的大门?

鳄鱼视界

流支付时代的Zebec,将打开Web3支付的大门?

股市老人

数字藏品app开发:nft数字藏品是什么?怎么制作和出售?

开源直播系统源码

数字藏品 数字藏品软件开发 数字藏品源码出售 数字藏品开发 数字藏品系统

锁分类

TimeFriends

8月月更

京东云PostgreSQL在GIS场景的应用分享

京东科技开发者

postgresql 检索 jieba 京东云 信息检索

阿里云高庆瑞:如何快速搭建低成本高弹性的云上应用

阿里云弹性计算

应用 自动化运维 CloudOps 弹性伸缩

数据仓库与数据中台最大的区别是什么?终于有人讲明白了

雨果

数据中台 数据仓库

流支付时代的Zebec,将打开Web3支付的大门?

西柚子

锁住它,快告诉我乐观锁与悲观锁的区别?

知识浅谈

8月月更

vivo前端智能化实践:机器学习在自动网页布局中的应用

vivo互联网技术

机器学习 前端 网页布局

BaaS助力区块链技术开启下一轮应用热潮

旺链科技

区块链 产业区块链 企业号九月金秋榜 BaaS平台

MQ 的原理以及持久化

浅羽技术

MQ 消息队列 Activemq active 8月月更

列存数据仓库怎样做才能更高效

jiangxl

日拱算法:什么是“煎饼排序”?

掘金安东尼

算法 8月月更

从项目经理过渡到ScrumMaster的三个技巧

ShineScrum

Scrum 敏捷 ScrumMaster 项目经理

【小程序项目开发--京东商城】uni-app之自定义搜索组件(上)-- 组件UI

计算机魔术师

8月月更

【小程序项目开发-- 京东商城】uni-app之自定义搜索组件(中)-- 搜索建议

计算机魔术师

8月月更

mysql的存储引擎详解

浅羽技术

MySQL 存储引擎 MySQL InnoDB memory Store 8月月更

前端高频面试题(二)(附答案)

helloworld1024fd

JavaScript 前端

Mysql安装教程

楠羽

#开源

长安链源码分析启动(6)

长安链

微信小程序转发朋友圈详解_小程序_郝加升_InfoQ精选文章