# Root 根组件(UpRootView)

Root 用于给所有 .vue 页面注入一层全局容器组件,解决「需要全局共享组件/能力」但又不想在每个页面重复写的问题。

uview-plus 中已内置 libs/root 插件,默认约定:

  • 根文件名:src/App.up.vue
  • 根占位标签:<UpRootView />
  • 注入组件标签:<global-up-root />
  • 页面默认根 refuniUpRoot
  • 自动识别工程类型:CLIsrc 目录)/ HBuilder(项目根目录)
  • 当不存在 App.up.vue 时自动创建默认文件(可关闭)
  • 当不存在 vite.config.ts/js 时自动创建 vite.config.ts(可关闭)

# 致谢

uview-plus 的 Root 能力基于开源项目 @uni-ku/root 思路与实现进行二次开发与改造(命名、工程识别、自动创建等能力)。

感谢原项目作者与贡献者的开源贡献。
项目地址:https://github.com/uni-ku/root (opens new window)

# ku-root 二次开发改动点(请以本节为准)

以下为当前 uview-plus 相对 @uni-ku/root 的关键改动,便于二次开发时快速定位差异:

  1. 页面类型注入范围扩展
    页面注入不再只按 .vue 处理,已支持按真实文件自动识别并注入:

    • .vue
    • .nvue
    • .uvue
  2. 模板偏移边界修复
    当页面 <template> 起始偏移为 0 时,仍能正确注入 <global-up-root>(避免首行模板漏注入)。

  3. 页面 root 引用优先级明确

    • 若页面写了 <template root="xxx">,优先使用页面自定义 ref
    • 否则在 enabledGlobalRef: true 时回退为默认 uniUpRoot
    • enabledGlobalRef: false 且页面未声明 root,则不注入默认 ref
  4. 工程识别与自动创建能力增强

    • 自动识别 CLI(src) / HBuilder(项目根) 两类结构
    • 可自动创建 App.up.vue
    • 可自动创建 vite.config.ts(当项目不存在 vite.config.ts/js 时)
  5. 实际代码位置(用于二开排查)

    • 插件入口:src/uni_modules/uview-plus/libs/root/index.js
    • 页面注入:src/uni_modules/uview-plus/libs/root/page.js
    • 主入口注册与根重写:src/uni_modules/uview-plus/libs/root/root.js
    • pages.json 解析与扩展名识别:src/uni_modules/uview-plus/libs/root/utils.js
    • 全局提示宿主:src/uni_modules/uview-plus/libs/root/root-toast-host.vue
    • 全局 API 注册:src/uni_modules/uview-plus/index.js

# 1. 在 vite.config.ts 启用插件

import { defineConfig } from "vite";
import uni from "@dcloudio/vite-plugin-uni";
import UniUpRoot from "./src/uni_modules/uview-plus/libs/root/index.js";

export default defineConfig({
  plugins: [
    UniUpRoot({
      rootFileName: "App.up",
      autoCreateRootFile: true,
      autoCreateViteConfig: true,
    }),
    uni(),
  ],
});

# 2. 创建 src/App.up.vue(可选)

默认开启 autoCreateRootFile: true,如果文件不存在会自动创建一个最小版本。
如果你需要暴露更多根能力,再手动改成下面这种写法:

<script setup>
import { ref } from 'vue'

const upRootMessage = ref('UpRoot ready')

const showGlobalMessage = (message = 'UpRoot bridge ok') => {
  uni.showToast({ title: message, icon: 'none' })
}

defineExpose({
  upRootMessage,
  showGlobalMessage
})
</script>

<template>
  <UpRootView />
</template>

# 3. 页面中基础使用

给页面模板加上 root 属性后,可以通过 this.$refs.xxx(Options API)或 ref<script setup>)拿到根组件暴露能力。

<template root="uniUpRoot">
  <view>
    <up-button @click="testUpRootBridge">测试 UpRoot</up-button>
  </view>
</template>

<script>
export default {
  methods: {
    testUpRootBridge() {
      const rootRef = this.$refs.uniUpRoot
      rootRef?.showGlobalMessage?.('来自页面的调用')
    }
  }
}
</script>

# 4. 说明

  • 该能力面向页面级模板注入,当前已支持 .vue/.nvue/.uvue
  • 如果需要排除页面,可在插件配置 excludePages 传入页面路径或 glob。
  • rootFileName 支持传 App.upApp.up.vue,内部会自动归一化。
  • autoCreateViteConfig 默认 true,会在项目缺少 vite.config.ts/js 时创建 vite.config.ts
  • 自动识别规则:
    • 优先使用 UNI_INPUT_DIR(且包含 pages.json);
    • 否则优先识别 src/pages.json(CLI);
    • 否则识别项目根的 pages.json(HBuilder)。

# 5. Root 内置全局 Toast / Notify

uview-plus 已在 Root 注入链路中内置全局提示宿主,并自动注册:

  • Toast 组件 refupGlobalToastRef
  • Notify 组件 refupGlobalNotifyRef
  • 全局方法:uni.$u.rootToast(...) / uni.$u.rootNotify(...)

这意味着页面里不再必须手动放置 <up-toast /><up-notify /> 即可全局调用。

// 字符串快捷写法
uni.$u.rootToast('保存成功')
uni.$u.rootNotify('网络已恢复')

// 对象写法
uni.$u.rootToast({
  message: '提交成功',
  type: 'success',
  duration: 2000
})

uni.$u.rootNotify({
  message: '请先登录',
  type: 'warning',
  duration: 3000
})

说明:

  • 若 Root 尚未挂载(极早期调用),会降级为 uni.showToast 文本提示。
  • 该能力依赖 Root 注入,请确保项目启用了 UniUpRoot(...)App.up.vue 中保留 <UpRootView />

# 6. 二开后自检清单

  • 确认 vite.config.tsUniUpRoot(...)uni() 之前注册
  • 确认页面编译产物包含 <global-up-root ...> 包裹
  • .vue.nvue 页面各抽样 1 个做注入验证
  • 若页面需访问根能力,确认模板已配置 root="xxx" 并与代码中 $refs.xxx 一致