第一页上方启动
在 <RouterView> 上方保留启动画面,以便第一个原生页面可以安装在其下方。删除覆盖层会显示同一页面,而无需在导航历史记录中添加启动条目。
如果splash是一条路线,则调用replace()会在splash退出时创建目的地。在 Android 上,该工作可以与 UI 线程上的退出动画竞争。覆盖可以让页面创建在退出动画开始之前完成;它不会将初始化工作移出 UI 线程。
保持 RouterView 安装
正常路由器安装后,将其保存为App.vue,将下一个组件保存为Splash.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。如果初始化抛出异常或初始 导航守卫 没有留下目的地,它会保持可见并显示错误消息:
<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 通过实际的应用程序历史记录返回,并且不会带回启动画面。