Root 提供了多种强大功能,帮助 Uniapp 开发者解决无法使用根部组件的问题。本文档将详细介绍这些功能及其使用方法。
默认情况下,Root 使用 App.ku.vue
作为虚拟根组件的文件名。但您可以根据项目需求自定义这个名称,提高项目的灵活性和可维护性。
在 vite.config.(js|ts)
中通过 rootFileName
选项进行配置:
// vite.config.(js|ts)
import Uni from '@dcloudio/vite-plugin-uni'
import UniKuRoot from '@uni-ku/root'
import { defineConfig } from 'vite'
export default defineConfig({
plugins: [
UniKuRoot({
// 默认含后缀 .vue,直接设置命名即可
rootFileName: 'KuRoot',
}),
// ...other plugins
]
})
- 配置文件名:在
vite.config.(js|ts)
中设置 rootFileName
选项 - 创建对应文件:创建与配置名称对应的 Vue 文件(如
KuRoot.vue
) - 使用视图标签:在新文件中使用
<KuRootView />
指定视图位置
<!-- KuRoot.vue (替代默认的 App.ku.vue) -->
<script setup lang="ts">
import { ref } from 'vue'
const customRootMessage = ref('Hello from Custom Root!')
</script>
<template>
<div class="custom-root">
<h1>{{ customRootMessage }}</h1>
<!-- 视图标签 -->
<KuRootView />
</div>
</template>
<style scoped>
.custom-root {
padding: 20px;
background-color: #f5f5f5;
}
</style>
- 文件名不需要包含
.vue
后缀,Root 会自动添加 - 修改文件名后,原有的
App.ku.vue
将不再生效 - 确保项目中的所有引用都使用新的文件名
Root 提供了两种方式获取虚拟根组件实例:局部启用和全局启用。这使得您可以在页面中直接调用根组件的方法和访问其数据。
局部启用方式适用于只需要在特定页面中访问根组件实例的场景。
- 在根组件中暴露方法和数据
<!-- src/App.ku.vue | App.ku.vue -->
<script setup lang="ts">
import { ref } from 'vue'
const helloKuRoot = ref('Hello AppKuVue')
const exposeRef = ref('this is from app.Ku.vue')
// 定义方法
function showMessage(message: string) {
console.log('Message from root:', message)
return `Root received: ${message}`
}
// 暴露给页面使用
defineExpose({
exposeRef,
showMessage
})
</script>
<template>
<div>
<div>{{ helloKuRoot }}</div>
<KuRootView />
</div>
</template>
- 在页面中获取引用
<!-- src/pages/*.vue -->
<script setup lang="ts">
import { ref, onMounted } from 'vue'
// 创建 ref 对象,名称需与模板中的 root 属性值一致
const uniKuRoot = ref()
const message = ref('')
onMounted(() => {
// 通过 ref 访问根组件暴露的方法和数据
if (uniKuRoot.value) {
message.value = uniKuRoot.value.exposeRef
}
})
function callRootMethod() {
if (uniKuRoot.value) {
const result = uniKuRoot.value.showMessage('Hello from page!')
console.log(result)
}
}
</script>
<!-- 使用 root 属性指定 ref 名称 -->
<template root="uniKuRoot">
<view>
<text>Exposed value: {{ message }}</text>
<button @click="callRootMethod">Call Root Method</button>
</view>
</template>
全局启用方式适用于需要在多个页面中访问根组件实例的场景。
- 启用全局自动注入
// vite.config.(js|ts)
import Uni from '@dcloudio/vite-plugin-uni'
import UniKuRoot from '@uni-ku/root'
import { defineConfig } from 'vite'
export default defineConfig({
plugins: [
UniKuRoot({
enabledGlobalRef: true
}),
Uni()
]
})
- 在根组件中暴露方法和数据
<!-- src/App.ku.vue | App.ku.vue -->
<script setup lang="ts">
import { ref } from 'vue'
const helloKuRoot = ref('Hello AppKuVue')
const globalCounter = ref(0)
function incrementCounter() {
globalCounter.value++
return globalCounter.value
}
defineExpose({
helloKuRoot,
globalCounter,
incrementCounter
})
</script>
<template>
<div>
<div>{{ helloKuRoot }}</div>
<KuRootView />
</div>
</template>
- 在页面中获取实例
<!-- src/pages/*.vue -->
<script setup lang="ts">
import { ref, onMounted } from 'vue'
const uniKuRoot = ref()
const counter = ref(0)
onMounted(() => {
// 通过 getCurrentPages() 获取根组件实例
const pagesStack = getCurrentPages()
if (pagesStack.length > 0) {
uniKuRoot.value = pagesStack[pagesStack.length - 1].$vm.$refs.uniKuRoot
counter.value = uniKuRoot.value?.globalCounter || 0
}
})
function increment() {
if (uniKuRoot.value) {
counter.value = uniKuRoot.value.incrementCounter()
}
}
</script>
<template>
<view>
<text>Global Counter: {{ counter }}</text>
<button @click="increment">Increment</button>
</view>
</template>
特性 | 局部启用 | 全局启用 |
---|
配置复杂度 | 简单,只需在模板中添加属性 | 需要在 vite.config 中配置 |
使用范围 | 仅限当前页面 | 所有页面均可使用 |
性能影响 | 最小,按需加载 | 略高,全局注入 |
适用场景 | 少量页面需要访问根组件 | 多个页面需要访问根组件 |
代码简洁性 | 需要在每个页面定义 ref | 一次配置,多处使用 |
在某些情况下,您可能希望某些页面不使用根组件,例如登录页、错误页等特殊页面。Root 提供了 excludePages
选项来满足这一需求。
在 vite.config.(js|ts)
中通过 excludePages
选项进行配置:
// vite.config.(js|ts)
import Uni from '@dcloudio/vite-plugin-uni'
import UniKuRoot from '@uni-ku/root'
import { defineConfig } from 'vite'
export default defineConfig({
plugins: [
UniKuRoot({
// 排除不需要根组件的页面
excludePages: [
'src/exclude.vue',
'src/exclude/**/*.vue',
'src/pages/login.vue',
'src/pages/error/**/*.vue'
],
}),
Uni()
]
})
excludePages
选项支持使用 Glob 模式进行灵活匹配:
模式 | 描述 | 示例 |
---|
*.vue | 匹配当前目录下所有 Vue 文件 | pages/*.vue |
**/*.vue | 匹配所有子目录中的 Vue 文件 | pages/**/*.vue |
src/login.vue | 匹配特定文件 | src/login.vue |
src/auth/** | 匹配特定目录下的所有文件 | src/auth/** |
// vite.config.(js|ts)
UniKuRoot({
excludePages: [
'src/pages/login.vue',
'src/pages/register.vue',
'src/pages/forgot-password.vue'
]
})
// vite.config.(js|ts)
UniKuRoot({
excludePages: [
'src/error-pages/**'
]
})
// vite.config.(js|ts)
UniKuRoot({
excludePages: [
'src/pages/modal-*.vue',
'src/pages/**/popup-*.vue'
]
})
- 路径是相对于项目根目录的
- 使用 Glob 模式时,确保路径匹配准确,避免意外排除需要的页面
- 排除的页面将不会应用根组件,也不会包含
<KuRootView />
标签 - 如果页面中使用了根组件暴露的方法或数据,需要确保这些页面不被排除
Root 提供了完整的 TypeScript 支持,帮助开发者获得更好的类型检查和代码提示。
Root 提供了以下类型定义:
// 根组件实例类型
interface UniKuRootInstance {
// 用户在根组件中暴露的任何方法和数据
[key: string]: any
}
// 配置选项类型
interface UniKuRootOptions {
rootFileName?: string
enabledGlobalRef?: boolean
excludePages?: string[]
}
- 配置 vite.config.ts
// vite.config.ts
import Uni from '@dcloudio/vite-plugin-uni'
import UniKuRoot, { UniKuRootOptions } from '@uni-ku/root'
import { defineConfig } from 'vite'
const options: UniKuRootOptions = {
rootFileName: 'KuRoot',
enabledGlobalRef: true,
excludePages: [
'src/pages/login.vue'
]
}
export default defineConfig({
plugins: [
UniKuRoot(options),
Uni()
]
})
- 在页面中使用类型
<!-- src/pages/*.vue -->
<script setup lang="ts">
import { ref, onMounted } from 'vue'
// 定义根组件暴露的类型
interface RootComponentExposed {
helloKuRoot: string
globalCounter: number
incrementCounter: () => number
}
const uniKuRoot = ref<RootComponentExposed>()
const counter = ref(0)
onMounted(() => {
const pagesStack = getCurrentPages()
if (pagesStack.length > 0) {
uniKuRoot.value = pagesStack[pagesStack.length - 1].$vm.$refs.uniKuRoot as RootComponentExposed
counter.value = uniKuRoot.value?.globalCounter || 0
}
})
function increment() {
if (uniKuRoot.value) {
// 现在有了类型提示和检查
counter.value = uniKuRoot.value.incrementCounter()
}
}
</script>
<template>
<view>
<text>Global Counter: {{ counter }}</text>
<button @click="increment">Increment</button>
</view>
</template>
使用 TypeScript 带来的好处包括:
- 代码提示:编辑器会提供根组件暴露的方法和属性的自动补全
- 类型检查:在编译时发现类型错误,减少运行时错误
- 更好的文档:类型定义本身就是一种文档,清晰地说明了可用的方法和属性
- 重构支持:当根组件的 API 发生变化时,TypeScript 会帮助找到所有需要更新的地方
Root 与 Uniapp 的生命周期完美集成,确保根组件和页面组件的生命周期事件能够正确触发。
当使用 Root 时,生命周期事件的执行顺序如下:
- 根组件的
onLaunch
/ created
- 根组件的
onLoad
- 页面组件的
onLoad
- 根组件的
onShow
- 页面组件的
onShow
- 根组件的
onReady
- 页面组件的
onReady
<!-- src/App.ku.vue -->
<script setup lang="ts">
import { ref, onLaunch, onLoad, onShow, onReady } from '@dcloudio/uni-app'
const appData = ref('')
onLaunch(() => {
console.log('Root onLaunch')
appData.value = 'App initialized'
})
onLoad(() => {
console.log('Root onLoad')
})
onShow(() => {
console.log('Root onShow')
})
onReady(() => {
console.log('Root onReady')
})
</script>
<template>
<div>
<div>{{ appData }}</div>
<KuRootView />
</div>
</template>
- 根组件的生命周期事件会在所有页面对应的生命周期事件之前触发
- 如果页面被
excludePages
排除,则不会触发根组件的生命周期事件 - 确保在根组件中不要执行过多的初始化逻辑,以免影响页面加载性能
除了默认的 <KuRootView />
标签,Root 还允许您自定义视图标签的名称,以更好地适应项目命名规范。
在 vite.config.(js|ts)
中通过 viewTagName
选项进行配置:
// vite.config.(js|ts)
import Uni from '@dcloudio/vite-plugin-uni'
import UniKuRoot from '@uni-ku/root'
import { defineConfig } from 'vite'
export default defineConfig({
plugins: [
UniKuRoot({
// 自定义视图标签名称
viewTagName: 'AppView',
}),
Uni()
]
})
<!-- src/App.ku.vue -->
<script setup lang="ts">
import { ref } from 'vue'
const message = ref('Hello from Root with custom view tag!')
</script>
<template>
<div class="root-container">
<h1>{{ message }}</h1>
<!-- 使用自定义视图标签 -->
<AppView />
</div>
</template>
<style scoped>
.root-container {
padding: 20px;
background-color: #f0f0f0;
}
</style>
- 自定义标签名称不需要包含
<
和 >
,Root 会自动处理 - 确保自定义标签名称不与现有组件或 HTML 元素冲突
- 修改视图标签名称后,项目中所有使用该标签的地方都需要更新
Root 提供了调试模式,帮助开发者更好地理解和调试根组件的行为。
在 vite.config.(js|ts)
中通过 debug
选项进行配置:
// vite.config.(js|ts)
import Uni from '@dcloudio/vite-plugin-uni'
import UniKuRoot from '@uni-ku/root'
import { defineConfig } from 'vite'
export default defineConfig({
plugins: [
UniKuRoot({
// 启用调试模式
debug: true,
}),
Uni()
]
})
启用调试模式后,Root 会在控制台输出以下信息:
- 根组件的创建和挂载过程
- 页面组件的创建和挂载过程
- 生命周期事件的触发顺序
- 组件实例的引用信息
- 排除页面的处理情况
[UniKuRoot Debug] Creating root component: App.ku.vue
[UniKuRoot Debug] Root component mounted
[UniKuRoot Debug] Processing page: src/pages/index.vue
[UniKuRoot Debug] Page component mounted
[UniKuRoot Debug] Root ref injected: uniKuRoot
[UniKuRoot Debug] Excluded page: src/pages/login.vue
- 调试模式仅建议在开发环境中使用,生产环境应关闭
- 调试信息可能会影响性能,特别是在页面数量较多的项目中
- 可以结合浏览器的开发者工具,更好地理解 Root 的工作原理
Root 提供了丰富的功能特性,帮助 Uniapp 开发者解决无法使用根部组件的问题。通过自定义虚拟根组件名称、使用虚拟根组件实例、过滤不需要根组件的页面、TypeScript 支持、生命周期集成、自定义视图标签和调试模式等功能,开发者可以构建更加灵活、可维护的 Uniapp 应用。
在实际项目中,根据具体需求选择合适的功能组合,可以充分发挥 Root 的优势,提升开发效率和用户体验。