Taro下利用Decorator快速實現小程式分享

MasonChow發表於2019-03-04

關於微信分享邏輯

微信小程式下開發轉發有兩個途徑
  1. 在Page的onLoad裡面定義wx.showShareMenu()顯示當前頁面的轉發按鈕
  2. 使用buttonopen-type=share讓使用者點選按鈕觸發轉發

如果需要對當前頁面轉發進行自定義編輯,則需要再當前頁面 Page 中定義 onShareAppMessage 事件處理函式,自定義該頁面的轉發內容。

官方相關文件 轉發 · 小程式

痛點

使用原生微信轉發主要有以下痛點:
  1. 需要轉發的頁面都要寫一次wx.showShareMenu()
  2. 如果分享涉及一些統一的邏輯處理,則要麼要引入一個類似format的函式進行處理,或者每個頁面單獨寫一次
舉個例子

在每次分享的卡片的連結上,都需要帶上當前分享使用者的userId,方便日後對於使用者拉新分析,助力,團購等行為進行處理,這個時候就需要對分享卡片的路徑進行一次處理

解決方式

利用Decorator以及React的高階元件HOC,在willMount的時候往頁面注入wx.showShareMenu(),然後可通過引數或者在當前頁面觸發響應的設定函式進行相應的分享配置設定

程式碼分享

分享修飾器

withShare.js
import Taro from `@tarojs/taro`;
import { connect } from `@tarojs/redux`;
import defaultShareImg from `xxx.jpg`;

function withShare(opts = {}) {
  
  // 設定預設
  const defalutPath = `pages/index/index?`;
  const defalutTitle = `預設標題`;
  const defaultImageUrl = defaultShareImg;

  return function demoComponent(Component) {      
    // redux裡面的使用者資料
    @connect(({ user }) => ({
      userInfo: user.userInfo
    }))
    class WithShare extends Component {
      async componentWillMount() {
        wx.showShareMenu({
          withShareTicket: true
        });

        if (super.componentWillMount) {
          super.componentWillMount();
        }
      }

      // 點選分享的那一刻會進行呼叫
      onShareAppMessage() {
        const { userInfo } = this.props;

        let { title, imageUrl, path = null } = opts;
		
        // 從繼承的元件獲取配置
        if (this.$setSharePath && typeof this.$setSharePath === `function`) {
          path = this.$setSharePath();
        }
		
        // 從繼承的元件獲取配置
        if (this.$setShareTitle && typeof this.$setShareTitle === `function`) {
          title = this.$setShareTitle();
        }

        // 從繼承的元件獲取配置
        if (
          this.$setShareImageUrl &&
          typeof this.$setShareImageUrl === `function`
        ) {
          imageUrl = this.$setShareImageUrl();
        }

        if (!path) {
          path = defalutPath;
        }
		
        // 每條分享都補充使用者的分享id
        // 如果path不帶引數,分享出去後解析的params裡面會帶一個{``: ``}
        const sharePath = `${path}&shareFromUser=${userInfo.shareId}`; 

        return {
          title: title || defalutTitle,
          path: sharePath,
          imageUrl: imageUrl || defaultImageUrl
        };
      }

      render() {
        return super.render();
      }
    }

    return WithShare;
  };
}

export default withShare;

複製程式碼

使用的頁面

pages/xxx/xxx.js
import Taro, { Component } from `@tarojs/taro`;
import { connect } from `@tarojs/redux`;
import { View } from `@tarojs/components`;
import withShare from `./withShare`;

@withShare({
    title: `可設定分享標題`, 
    imageUrl: `可設定分享圖片路徑`, 
    path: `可設定分享路徑`
})
class Index extends Component {
  
  // $setSharePath = () => `可設定分享路徑(優先順序最高)`

  // $setShareTitle = () => `可設定分享標題(優先順序最高)`

  // $setShareImageUrl = () => `可設定分享圖片路徑(優先順序最高)`
  
  render() {
     return <View />
  }
}
複製程式碼

由於是繼承傳入的元件,所以獲取分享配置除了可以從函式的引數獲取,還可以通過定義的一些方法,通過繼承的元件獲取到繼承的引數,這樣可以再某些業務場景下,根據需要動態生成分享引數配置,例如程式碼裡面的this.$setSharePath()等就是從父級元件動態獲取到分享的引數

相關參考資料

對於React高階元件的理解可參考 深入理解 React 高階元件 – 簡書

對於ES7修飾器的理解可參考[使用 ES decorators 構建一致性 API | Taobao FED | 淘寶前端團隊](

相關文章