前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >微信小程序转发朋友圈详解

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

作者头像
有赞coder
发布2020-09-27 10:36:58
3.8K0
发布2020-09-27 10:36:58
举报

作者:郝加升

部门:增长中心-前端

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

概述

点击右上角分享朋友圈

分享到朋友圈样式

朋友圈打开样式

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

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

什么是“单页模式”?

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

“单页模式”下,页面顶部固定有导航栏,标题显示为当前页面 JSON 配置的标题。底部固定有操作栏,点击操作栏的“前往小程序”可打开小程序的当前页面。顶部导航栏与底部操作栏均不支持自定义样式。 “单页模式”默认运行的是小程序页面内容,但由于页面固定有顶部导航栏与底部操作栏,很可能会影响小程序页面的布局。因此,请开发者特别注意适配“单页模式”的页面交互,以实现流畅完整的交互体验。

限制

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

限制主要包括以下几点:

  1. 页面无登录态,与登录相关的接口,如 wx.login 均不可用
  2. 不允许跳转到其它页面,包括任何跳小程序页面、跳其它小程序、跳微信原生页面
  3. 若页面包含 tabBar,tabBar 不会渲染,包括自定义 tabBar
  4. 本地存储与小程序普通模式不共用

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

配置

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

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

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

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

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

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

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

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

设置后的样式:

开发

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

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

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

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

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

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

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

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

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

代码语言:javascript
复制
// app.js

App({
  // ...
  onLaunch(options) {
    const { scene } = options;
    this.isSinglePage = scene === 1154;
  }
  // ...
})

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

接下来说说两种方案。

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

代码语言:javascript
复制
const app = getApp();

Page({
  // ...
  onLoad() {
    if (!app.isSinglePage) {
      wx.login({
        // ...
      })
    }
  }
  // ...
})

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

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

代码语言:javascript
复制
// pages/home/index.js

const app = getApp();

Page({
  data: {
    isSinglePage: app.isSinglePage,
  }
  // ...
})

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

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

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

代码语言:javascript
复制
// pages/home/index.wxml

<home-single-page wx:if="{{ isSinglePage }}" />
<view wx:else>
  <!-- 普通页面内容 -->
</view>

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

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

代码语言:javascript
复制
// pages/home/index.js
import ExtendPage from 'common/extend-page/index'

const app = getApp();

ExtendPage({
  data: {
    isSinglePage: app.isSinglePage,
  }
  // ...
})

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

代码语言:javascript
复制
// 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内的生命周期:

代码语言:javascript
复制
// pages/home/index.js
import ExtendPage from 'common/extend-page/index'

const app = getApp();

ExtendPage({
  data: {
    isSinglePage: app.isSinglePage,
  },
  singlePageLife: {
    onLoad() {
      // ...
    },
  }
  // ...
})
代码语言:javascript
复制
// 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) {
    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,
  });
}

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

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-09-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 有赞coder 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 概述
    • 点击右上角分享朋友圈
      • 分享到朋友圈样式
        • 朋友圈打开样式
        • 什么是“单页模式”?
          • 限制
            • 配置
            相关产品与服务
            云开发 CloudBase
            云开发(Tencent CloudBase,TCB)是腾讯云提供的云原生一体化开发环境和工具平台,为200万+企业和开发者提供高可用、自动弹性扩缩的后端云服务,可用于云端一体化开发多种端应用(小程序、公众号、Web 应用等),避免了应用开发过程中繁琐的服务器搭建及运维,开发者可以专注于业务逻辑的实现,开发门槛更低,效率更高。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档