Skip to content

Commit

Permalink
feat(mp): 新增 miniProgramBus
Browse files Browse the repository at this point in the history
  • Loading branch information
fjc0k committed Aug 26, 2020
1 parent ed28ce6 commit 9538763
Show file tree
Hide file tree
Showing 3 changed files with 286 additions and 12 deletions.
1 change: 1 addition & 0 deletions src/mp/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export * from './getCurrentPagePath'
export * from './getCurrentPageQuery'
export * from './getCurrentPageUrl'
export * from './getTopBarInfo'
export * from './miniProgramBus'
export * from './miniProgramConfig'
export * from './navigatePageBack'
export * from './navigatePageTo'
Expand Down
126 changes: 126 additions & 0 deletions src/mp/miniProgramBus.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
/// <reference types="miniprogram-api-typings" />
import { Defined } from '../types'
import {
EventBus,
EventBusBeforeEmit,
EventBusBeforeOn,
EventBusListener,
} from '../utils'
import { patchMiniProgram } from './patchMiniProgram'

export interface MiniProgramBusListeners {
appLaunch: Defined<WechatMiniprogram.App.Options<{}>['onLaunch']>
appShow: Defined<WechatMiniprogram.App.Options<{}>['onShow']>
appHide: Defined<WechatMiniprogram.App.Options<{}>['onHide']>
appError: Defined<WechatMiniprogram.App.Options<{}>['onError']>
appThemeChange: Defined<WechatMiniprogram.App.Options<{}>['onThemeChange']>
appUnhandledRejectionThrow: Defined<
WechatMiniprogram.App.Options<{}>['onUnhandledRejection']
>
pageNotFound: Defined<WechatMiniprogram.App.Options<{}>['onPageNotFound']>
pageLoad: Defined<WechatMiniprogram.Page.Options<{}, {}>['onLoad']>
pageShow: Defined<WechatMiniprogram.Page.Options<{}, {}>['onShow']>
pageHide: Defined<WechatMiniprogram.Page.Options<{}, {}>['onHide']>
pageReady: Defined<WechatMiniprogram.Page.Options<{}, {}>['onReady']>
pageUnload: Defined<WechatMiniprogram.Page.Options<{}, {}>['onUnload']>
pagePullDownRefresh: Defined<
WechatMiniprogram.Page.Options<{}, {}>['onPullDownRefresh']
>
pageReachBottom: Defined<
WechatMiniprogram.Page.Options<{}, {}>['onReachBottom']
>
pageShareAppMessage: Defined<
WechatMiniprogram.Page.Options<{}, {}>['onShareAppMessage']
>
pageShareTimeline: Defined<
// @ts-ignore
WechatMiniprogram.Page.Options<{}, {}>['onShareTimeline']
>
pageAddToFavorites: Defined<
WechatMiniprogram.Page.Options<{}, {}>['onAddToFavorites']
>
// 影响性能,暂不支持
// pageScroll: Defined<WechatMiniprogram.Page.Options<{}, {}>['onPageScroll']>
pageResize: Defined<WechatMiniprogram.Page.Options<{}, {}>['onResize']>
pageTabItemTap: Defined<
WechatMiniprogram.Page.Options<{}, {}>['onTabItemTap']
>
currentPageShow: Defined<WechatMiniprogram.Page.Options<{}, {}>['onShow']>
currentPageHide: Defined<WechatMiniprogram.Page.Options<{}, {}>['onHide']>
currentPageReady: Defined<WechatMiniprogram.Page.Options<{}, {}>['onReady']>
currentPageUnload: Defined<WechatMiniprogram.Page.Options<{}, {}>['onUnload']>
currentPagePullDownRefresh: Defined<
WechatMiniprogram.Page.Options<{}, {}>['onPullDownRefresh']
>
currentPageReachBottom: Defined<
WechatMiniprogram.Page.Options<{}, {}>['onReachBottom']
>
currentPageShareAppMessage: Defined<
WechatMiniprogram.Page.Options<{}, {}>['onShareAppMessage']
>
currentPageShareTimeline: Defined<
// @ts-ignore
WechatMiniprogram.Page.Options<{}, {}>['onShareTimeline']
>
currentPageAddToFavorites: Defined<
WechatMiniprogram.Page.Options<{}, {}>['onAddToFavorites']
>
// 影响性能,暂不支持
// currentPageScroll: Defined<WechatMiniprogram.Page.Options<{}, {}>['onPageScroll']>
currentPageResize: Defined<WechatMiniprogram.Page.Options<{}, {}>['onResize']>
currentPageTabItemTap: Defined<
WechatMiniprogram.Page.Options<{}, {}>['onTabItemTap']
>
}

// @ts-ignore
export const miniProgramBus = new EventBus<MiniProgramBusListeners>({
beforeOn: ([
'currentPageShow',
'currentPageHide',
'currentPageReady',
'currentPageUnload',
'currentPagePullDownRefresh',
'currentPageReachBottom',
'currentPageShareAppMessage',
'currentPageShareTimeline',
'currentPageAddToFavorites',
'currentPageResize',
'currentPageTabItemTap',
] as Array<keyof MiniProgramBusListeners>).reduce<
// @ts-ignore
EventBusBeforeOn<MiniProgramBusListeners>
>((res, name) => {
res[name] = function (cb: any) {
;(cb as EventBusListener).__EVENT_BUS_TAG__ =
patchMiniProgram.__CURRENT_PAGE_ID__
return cb
}
return res
}, {}),
beforeEmit: ([
'pageShow',
'pageHide',
'pageReady',
'pageUnload',
'pagePullDownRefresh',
'pageReachBottom',
'pageShareAppMessage',
'pageShareTimeline',
'pageAddToFavorites',
'pageResize',
'pageTabItemTap',
] as Array<keyof MiniProgramBusListeners>).reduce<
// @ts-ignore
EventBusBeforeEmit<MiniProgramBusListeners>
>((res, name) => {
res[name] = function (ctx) {
this.emit({
name: `current${name[0].toLocaleLowerCase()}${name.slice(1)}` as any,
context: ctx,
tag: ctx.__PAGE_ID__,
})
}
return res
}, {}),
})
171 changes: 159 additions & 12 deletions src/mp/patchMiniProgram.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,168 @@
import { ensureInMiniProgram } from './ensureInMiniProgram'
import { MiniProgramApi } from '../utils'
import { miniProgramBus } from './miniProgramBus'

function patchAppOptions(
mp: MiniProgramApi,
appOptions: WechatMiniprogram.App.Options<{}>,
) {
const onLaunch = appOptions.onLaunch
appOptions.onLaunch = function (launchOptions) {
miniProgramBus.emit({ name: 'appLaunch', context: this }, launchOptions)
return onLaunch?.call(this, launchOptions)
}

const onShow = appOptions.onShow
appOptions.onShow = function (showOptions) {
miniProgramBus.emit({ name: 'appShow', context: this }, showOptions)
return onShow?.call(this, showOptions)
}

const onHide = appOptions.onHide
appOptions.onHide = function () {
miniProgramBus.emit({ name: 'appHide', context: this })
return onHide?.call(this)
}

const onError = appOptions.onError
appOptions.onError = function (error) {
miniProgramBus.emit({ name: 'appError', context: this }, error)
return onError?.call(this, error)
}

const onPageNotFound = appOptions.onPageNotFound
appOptions.onPageNotFound = function (payload) {
miniProgramBus.emit({ name: 'pageNotFound', context: this }, payload)
return onPageNotFound?.call(this, payload)
}

const onUnhandledRejection = appOptions.onUnhandledRejection
appOptions.onUnhandledRejection = function (payload) {
miniProgramBus.emit(
{ name: 'appUnhandledRejectionThrow', context: this },
payload,
)
return onUnhandledRejection?.call(this, payload)
}

const onThemeChange = appOptions.onThemeChange
appOptions.onThemeChange = function (payload) {
miniProgramBus.emit({ name: 'appThemeChange', context: this }, payload)
return onThemeChange?.call(this, payload)
}
}

function patchPageOptions(
mp: MiniProgramApi,
pageOptions: WechatMiniprogram.Page.Options<{}, {}>,
) {
const onLoad = pageOptions.onLoad
pageOptions.onLoad = function (pageQuery) {
if (mp.$brand === '支付宝') {
// 支持通过 options 获取页面参数
;(this as any).options = pageQuery
}
;(this as any).__PAGE_ID__ = ++patchMiniProgram.__CURRENT_PAGE_ID__
miniProgramBus.emit({ name: 'pageLoad', context: this }, pageQuery)
return onLoad?.call(this, pageQuery)
}

const onShow = pageOptions.onShow
pageOptions.onShow = function () {
miniProgramBus.emit({ name: 'pageShow', context: this })
return onShow?.call(this)
}

const onReady = pageOptions.onReady
pageOptions.onReady = function () {
miniProgramBus.emit({ name: 'pageReady', context: this })
return onReady?.call(this)
}

const onHide = pageOptions.onHide
pageOptions.onHide = function () {
miniProgramBus.emit({ name: 'pageHide', context: this })
return onHide?.call(this)
}

const onUnload = pageOptions.onUnload
pageOptions.onUnload = function () {
miniProgramBus.emit({ name: 'pageUnload', context: this })
return onUnload?.call(this)
}

const onPullDownRefresh = pageOptions.onPullDownRefresh
pageOptions.onPullDownRefresh = function () {
miniProgramBus.emit({ name: 'pagePullDownRefresh', context: this })
return onPullDownRefresh?.call(this)
}

const onReachBottom = pageOptions.onReachBottom
pageOptions.onReachBottom = function () {
miniProgramBus.emit({ name: 'pageReachBottom', context: this })
return onReachBottom?.call(this)
}

const onShareAppMessage = pageOptions.onShareAppMessage
pageOptions.onShareAppMessage = function (payload) {
miniProgramBus.emit({ name: 'pageShareAppMessage', context: this }, payload)
return onShareAppMessage?.call(this, payload)
}

// @ts-ignore
const onShareTimeline = pageOptions.onShareTimeline
// @ts-ignore
pageOptions.onShareTimeline = function (payload) {
miniProgramBus.emit({ name: 'pageShareTimeline', context: this }, payload)
return onShareTimeline?.call(this, payload)
}

const onAddToFavorites = pageOptions.onAddToFavorites
pageOptions.onAddToFavorites = function (payload) {
miniProgramBus.emit({ name: 'pageAddToFavorites', context: this }, payload)
return onAddToFavorites?.call(this, payload) || {}
}

const onResize = pageOptions.onResize
pageOptions.onResize = function (payload) {
miniProgramBus.emit({ name: 'pageResize', context: this }, payload)
return onResize?.call(this, payload)
}

const onTabItemTap = pageOptions.onTabItemTap
pageOptions.onTabItemTap = function (payload) {
miniProgramBus.emit({ name: 'pageTabItemTap', context: this }, payload)
return onTabItemTap?.call(this, payload)
}
}

/**
* 给各个品牌小程序打补丁以期行为与微信保持一致
* 打补丁
*/
export function patchMiniProgram() {
ensureInMiniProgram(mp => {
if (mp.$brand === '支付宝') {
// 支持通过 options 获取页面参数
const originalPage = Page
Page = function (options) {
const onLoad = options.onLoad
options.onLoad = function (query) {
;(this as any).options = query
onLoad && onLoad.call(this, query)
}
originalPage(options)
}
// 重写 App
const originalApp = App
App = function (appOptions) {
patchAppOptions(mp, appOptions)
return originalApp(appOptions)
}

// 重写 Page
const originalPage = Page
Page = function (pageOptions) {
patchPageOptions(mp, pageOptions)
return originalPage(pageOptions)
}

// 重写 Component
const originalComponent = Component
Component = function (componentOptions) {
componentOptions.methods = componentOptions.methods || ({} as any)
patchPageOptions(mp, componentOptions.methods as any)
return originalComponent(componentOptions)
}
})
}

patchMiniProgram.__CURRENT_PAGE_ID__ = 0

0 comments on commit 9538763

Please sign in to comment.