index.ts 3.9 KB
Newer Older
fxy060608's avatar
fxy060608 已提交
1
import { invokeArrayFns } 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 15
import { useRouter } from 'vue-router'
import { decodedQuery } 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 25 26 27 28 29 30 31 32 33 34
  after?: (comp: DefineComponent) => void
}

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

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.__isPage = true // 标记当前组件是页面
fxy060608's avatar
fxy060608 已提交
57
      instance.root = instance // 组件root指向页面
fxy060608's avatar
fxy060608 已提交
58
      const route = usePageRoute()
fxy060608's avatar
fxy060608 已提交
59 60 61 62
      if (route.meta.isTabBar) {
        //初始化时,状态肯定是激活
        instance.__isActive = true
      }
fxy060608's avatar
fxy060608 已提交
63
      const pageMeta = usePageMeta()
fxy060608's avatar
fxy060608 已提交
64
      onBeforeMount(() => {
fxy060608's avatar
fxy060608 已提交
65
        onPageShow(instance, pageMeta)
fxy060608's avatar
fxy060608 已提交
66
        const { onLoad, onShow } = instance
fxy060608's avatar
fxy060608 已提交
67
        onLoad && invokeArrayFns(onLoad, decodedQuery(route.query))
fxy060608's avatar
fxy060608 已提交
68 69 70 71
        instance.__isVisible = true
        onShow && invokeArrayFns(onShow)
      })
      onMounted(() => {
fxy060608's avatar
fxy060608 已提交
72
        onPageReady(instance)
fxy060608's avatar
fxy060608 已提交
73 74 75 76 77
        const { onReady } = instance
        onReady && invokeArrayFns(onReady)
      })
      onBeforeActivate(() => {
        if (!instance.__isVisible) {
fxy060608's avatar
fxy060608 已提交
78
          onPageShow(instance, pageMeta)
fxy060608's avatar
fxy060608 已提交
79 80 81 82 83 84 85 86 87 88 89 90
          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 已提交
91
      return route.query
fxy060608's avatar
fxy060608 已提交
92 93 94 95 96 97 98 99
    },
  })
}

export function setupApp(comp: any) {
  return setupComponent(comp, {
    init: initApp,
    setup(instance) {
fxy060608's avatar
fxy060608 已提交
100
      const route = usePageRoute()
fxy060608's avatar
fxy060608 已提交
101
      const onLaunch = () => {
fxy060608's avatar
fxy060608 已提交
102
        const { onLaunch, onShow } = instance
fxy060608's avatar
fxy060608 已提交
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
        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 已提交
118 119 120 121 122 123 124 125 126
      onMounted(() => {
        document.addEventListener('visibilitychange', function () {
          if (document.visibilityState === 'visible') {
            UniServiceJSBridge.emit('onAppEnterForeground')
          } else {
            UniServiceJSBridge.emit('onAppEnterBackground')
          }
        })
      })
fxy060608's avatar
fxy060608 已提交
127
      return route.query
fxy060608's avatar
fxy060608 已提交
128 129 130 131 132 133 134
    },
    after(comp) {
      comp.mpType = 'app'
      comp.render = () => (openBlock(), createBlock(LayoutComponent))
    },
  })
}