Skip to content

第一页上方启动 ​

在 <RouterView> 上方保留启动画面,以便第一个原生页面可以安装在其下方。删除覆盖层会显示同一页面,而无需在导航历史记录中添加启动条目。

如果splash是一条路线,则调用replace()会在splash退出时创建目的地。在 Android 上,该工作可以与 UI 线程上的退出动画竞争。覆盖可以让页面创建在退出动画开始之前完成;它不会将初始化工作移出 UI 线程。

保持 RouterView 安装 ​

正常路由器安装后,将其保存为App.vue,将下一个组件保存为Splash.vue,保存在同一目录中:

vue
<script setup lang="ts">
import { ref } from 'nativescript-vue'
import { RouterView } from 'vue-router-ns'
import Splash from './Splash.vue'

const showSplash = ref(true)
</script>

<template>
  <GridLayout>
    <GridLayout :isUserInteractionEnabled="!showSplash" :accessibilityHidden="showSplash">
      <RouterView />
    </GridLayout>
    <Splash v-if="showSplash" @done="showSplash = false" />
  </GridLayout>
</template>

两个孩子占据相同的GridLayout单元。水花最后出现,位于路由器上方。包装器使覆盖的页面脱离接触交互和可访问性遍历,直到飞溅被移除。

只有覆盖层有 v-if。不要将 <RouterView> 放在 v-if="!showSplash" 后面:这会推迟页面创建,直到启动画面消失。也不要在 createApp(App).use(router).start() 之前等待 router.isReady():路由器需要首先安装其视图。

显示页面 ​

该组件等待初始导航,淡出覆盖层并发出 done。如果初始化抛出异常或初始 导航守卫 没有留下目的地,它会保持可见并显示错误消息:

vue
<script setup lang="ts">
import type { EventData, View } from '@nativescript/core'
import { onBeforeUnmount, ref } from 'nativescript-vue'
import { useRouter } from 'vue-router-ns'

const props = withDefaults(defineProps<{ fade?: boolean }>(), { fade: true })
const emit = defineEmits<{ done: [] }>()
const router = useRouter()
const failed = ref(false)
let started = false
let active = true

onBeforeUnmount(() => {
  active = false
})

async function reveal({ object }: EventData) {
  if (started) return
  started = true
  try {
    await router.isReady()
    if (!active) return
    // A guard can cancel initial navigation without throwing an error.
    if (!router.currentRoute.value.matched.length) {
      failed.value = true
      return
    }
  } catch (error) {
    if (active) failed.value = true
    console.error('Initial navigation failed', error)
    return
  }

  try {
    if (props.fade) await (object as View).animate({ opacity: 0, duration: 250 })
  } catch {
    // A cancelled animation must not leave a ready app behind the splash.
  }
  if (active) emit('done')
}
</script>

<template>
  <GridLayout backgroundColor="#0f172a" iosOverflowSafeArea="true" @loaded="reveal">
    <StackLayout verticalAlignment="middle" padding="32">
      <Label text="My app" color="white" fontSize="32" textAlignment="center" />
      <Label
        v-if="failed"
        text="Unable to open the first page. Please restart the app."
        color="white"
        textAlignment="center"
        textWrap="true"
      />
    </StackLayout>
  </GridLayout>
</template>

淡入淡出是一个应用程序动画。当您的应用程序的简化动作首选项启用时,绑定 :fade="false";路由器的 运动策略 控制路由过渡,而不是此自定义动画。

isReady() 等待初始导航,而不是每个隐藏选项卡或页面自己的网络请求。将任何所需的应用程序初始化添加到就绪条件中。对于新手入门,请在用户完成新手入门时发出 done ;保持 <RouterView> 始终安装。

匹配iOS启动屏幕 ​

在叠加层的根布局上设置 iosOverflowSafeArea="true",使其背景延伸到安全区域之外。使用与 App_Resources/iOS/LaunchScreen.storyboard 相同的背景、图稿、大小和位置,以避免 iOS 移交给正在运行的应用程序时出现明显的跳跃。检查您支持的 iPhone 和 iPad 尺寸的对齐情况。

NativeScript 启动后出现此覆盖。它补充了操作系统的启动屏幕;它不能取代 JavaScript 运行之前显示的屏幕。 iosOverflowSafeArea 特定于 iOS。

警卫仍在下面奔跑 ​

初始导航、重定向和 导航守卫 在启动画面可见时照常运行。它在视觉上隐藏了页面;它不会延迟身份验证或绕过 导航守卫。将未经身份验证的初始访问重定向到可用的登录页面。飞溅不是访问控制边界。

无需更改路由器 API、额外路由、push() 或 replace() 即可删除覆盖。 Back 通过实际的应用程序历史记录返回,并且不会带回启动画面。

基于 MIT 许可证发布。