index.ts 4.4 KB
Newer Older
D
DCloud_LXH 已提交
1
import { invokeArrayFns, isPlainObject } from '@vue/shared'
fxy060608's avatar
fxy060608 已提交
2 3 4 5 6 7 8 9 10 11 12 13
import {
  ComponentInternalInstance,
  ComponentPublicInstance,
  createBlock,
  DefineComponent,
  getCurrentInstance,
  onMounted,
  openBlock,
  onBeforeActivate,
  onBeforeDeactivate,
  onBeforeMount,
} from 'vue'
fxy060608's avatar
fxy060608 已提交
14
import { useRouter } from 'vue-router'
fxy060608's avatar
fxy060608 已提交
15
import { decodedQuery, WEB_INVOKE_APPSERVICE } from '@dcloudio/uni-shared'
fxy060608's avatar
fxy060608 已提交
16 17
import { LayoutComponent } from '../..'
import { initApp } from './app'
fxy060608's avatar
fxy060608 已提交
18
import { initPage, onPageShow, onPageReady } from './page'
fxy060608's avatar
fxy060608 已提交
19
import { usePageMeta, usePageRoute } from './provide'
fxy060608's avatar
fxy060608 已提交
20 21 22

interface SetupComponentOptions {
  init: (vm: ComponentPublicInstance) => void
fxy060608's avatar
fxy060608 已提交
23
  setup: (instance: ComponentInternalInstance) => Record<string, any>
fxy060608's avatar
fxy060608 已提交
24
  before?: (comp: DefineComponent) => void
fxy060608's avatar
fxy060608 已提交
25 26 27 28
}

function wrapperComponentSetup(
  comp: DefineComponent,
fxy060608's avatar
fxy060608 已提交
29
  { init, setup, before }: SetupComponentOptions
fxy060608's avatar
fxy060608 已提交
30
) {
fxy060608's avatar
fxy060608 已提交
31
  before && before(comp)
fxy060608's avatar
fxy060608 已提交
32 33 34 35
  const oldSetup = comp.setup
  comp.setup = (props, ctx) => {
    const instance = getCurrentInstance()!
    init(instance.proxy!)
fxy060608's avatar
fxy060608 已提交
36
    const query = setup(instance)
fxy060608's avatar
fxy060608 已提交
37
    if (oldSetup) {
fxy060608's avatar
fxy060608 已提交
38
      return oldSetup(query, ctx)
fxy060608's avatar
fxy060608 已提交
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
    }
  }
}

function setupComponent(comp: any, options: SetupComponentOptions) {
  if (comp && (comp.__esModule || comp[Symbol.toStringTag] === 'Module')) {
    wrapperComponentSetup(comp.default, options)
  } else {
    wrapperComponentSetup(comp, options)
  }
  return comp
}

export function setupPage(comp: any) {
  return setupComponent(comp, {
    init: initPage,
    setup(instance) {
fxy060608's avatar
fxy060608 已提交
56
      instance.root = instance // 组件root指向页面
fxy060608's avatar
fxy060608 已提交
57
      const route = usePageRoute()
fxy060608's avatar
fxy060608 已提交
58 59 60 61 62
      // node环境不触发Page生命周期
      if (__NODE_JS__) {
        return route.query
      }

fxy060608's avatar
fxy060608 已提交
63
      const pageMeta = usePageMeta()
fxy060608's avatar
fxy060608 已提交
64

fxy060608's avatar
fxy060608 已提交
65
      onBeforeMount(() => {
fxy060608's avatar
fxy060608 已提交
66
        onPageShow(instance, pageMeta)
fxy060608's avatar
fxy060608 已提交
67
        const { onLoad, onShow } = instance
fxy060608's avatar
fxy060608 已提交
68
        onLoad && invokeArrayFns(onLoad, decodedQuery(route.query))
fxy060608's avatar
fxy060608 已提交
69 70 71 72
        instance.__isVisible = true
        onShow && invokeArrayFns(onShow)
      })
      onMounted(() => {
fxy060608's avatar
fxy060608 已提交
73
        onPageReady(instance)
fxy060608's avatar
fxy060608 已提交
74 75 76 77 78
        const { onReady } = instance
        onReady && invokeArrayFns(onReady)
      })
      onBeforeActivate(() => {
        if (!instance.__isVisible) {
fxy060608's avatar
fxy060608 已提交
79
          onPageShow(instance, pageMeta)
fxy060608's avatar
fxy060608 已提交
80 81 82 83 84 85 86 87 88 89 90 91
          instance.__isVisible = true
          const { onShow } = instance
          onShow && invokeArrayFns(onShow)
        }
      })
      onBeforeDeactivate(() => {
        if (instance.__isVisible && !instance.__isUnload) {
          instance.__isVisible = false
          const { onHide } = instance
          onHide && invokeArrayFns(onHide)
        }
      })
fxy060608's avatar
fxy060608 已提交
92

fxy060608's avatar
fxy060608 已提交
93
      return route.query
fxy060608's avatar
fxy060608 已提交
94 95 96 97 98 99 100 101
    },
  })
}

export function setupApp(comp: any) {
  return setupComponent(comp, {
    init: initApp,
    setup(instance) {
fxy060608's avatar
fxy060608 已提交
102
      const route = usePageRoute()
fxy060608's avatar
fxy060608 已提交
103 104 105 106
      // node环境不触发App生命周期
      if (__NODE_JS__) {
        return route.query
      }
fxy060608's avatar
fxy060608 已提交
107
      const onLaunch = () => {
fxy060608's avatar
fxy060608 已提交
108
        const { onLaunch, onShow } = instance
fxy060608's avatar
fxy060608 已提交
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
        const path = route.path.substr(1)
        const launchOptions = {
          path: path || __uniRoutes[0].meta.route,
          query: decodedQuery(route.query),
          scene: 1001,
        }
        onLaunch && invokeArrayFns(onLaunch, launchOptions)
        onShow && invokeArrayFns(onShow, launchOptions)
      }
      if (__UNI_FEATURE_PAGES__) {
        // 等待ready后,再onLaunch,可以顺利获取到正确的path和query
        useRouter().isReady().then(onLaunch)
      } else {
        onBeforeMount(onLaunch)
      }
fxy060608's avatar
fxy060608 已提交
124
      onMounted(() => {
D
DCloud_LXH 已提交
125 126 127 128 129 130 131
        window.addEventListener(
          'message',
          function (evt: {
            data?: { type: string; data: any; pageId: number }
          }) {
            if (
              isPlainObject(evt.data) &&
fxy060608's avatar
fxy060608 已提交
132
              evt.data.type === WEB_INVOKE_APPSERVICE
D
DCloud_LXH 已提交
133 134 135 136 137 138 139 140 141
            ) {
              UniServiceJSBridge.emit(
                'onWebInvokeAppService',
                evt.data.data,
                evt.data.pageId
              )
            }
          }
        )
fxy060608's avatar
fxy060608 已提交
142 143 144 145 146 147 148 149
        document.addEventListener('visibilitychange', function () {
          if (document.visibilityState === 'visible') {
            UniServiceJSBridge.emit('onAppEnterForeground')
          } else {
            UniServiceJSBridge.emit('onAppEnterBackground')
          }
        })
      })
fxy060608's avatar
fxy060608 已提交
150
      return route.query
fxy060608's avatar
fxy060608 已提交
151
    },
fxy060608's avatar
fxy060608 已提交
152
    before(comp) {
fxy060608's avatar
fxy060608 已提交
153
      comp.mpType = 'app'
fxy060608's avatar
fxy060608 已提交
154 155 156
      comp.setup = () => () => {
        return openBlock(), createBlock(LayoutComponent)
      }
fxy060608's avatar
fxy060608 已提交
157 158 159
    },
  })
}