Skip to content

层简介

为什么需要层?

想象你在开发多个 Nuxt 项目(公司官网、管理后台、客户门户),它们共享相同的导航栏、布局、主题配置和工具函数。不用层,你需要手动复制这些文件到每个项目,改一处就要改多处——维护成本极高。层让你定义一次,到处复用,子项目还能按需覆盖。

什么是层?

层(Layer)是一个拥有 nuxt.config.ts 的 Nuxt 项目片段,可以被其他项目继承。类似于"模板"或"主题"的概念。

与模块不同,层不仅可以提供功能,还能提供完整的页面、布局、组件等 UI 资源,并且子项目可以覆盖层中的任何文件。

层能做什么?

能力说明
共享页面多个项目共用相同的页面
共享布局统一的布局模板
共享组件通用组件库
共享组合式函数公共业务逻辑
共享服务端逻辑API 路由、中间件
共享配置统一的构建和运行时配置
文件覆盖子项目可以覆盖层中的任何文件

使用场景

场景说明
主题系统多个项目共用 UI 主题(颜色、字体、布局)
Monorepo多个应用共享组件和逻辑
SaaS 产品基础功能 + 客户定制层
内部工具公司统一的组件库和规范
多租户核心层 + 租户特定层
开源主题发布可复用的 Nuxt 主题

层与模块的区别

特性LayerModule
代码共享组件、页面、布局功能、插件、组合式函数
配置继承✅ 完整继承 nuxt.config❌ 仅配置项
文件覆盖✅ 子项目可覆盖层文件❌ 不支持覆盖
UI 资源✅ 页面、布局、样式❌ 通常不提供
安装方式extends 或 layers/ 目录modules 数组
适用场景UI 和结构复用功能扩展
发布方式npm 包或 Git 仓库npm 包

TIP

简单记法:模块提供功能 层提供结构。如果需要共享 UI 模板,用层;如果需要集成第三方服务,用模块

它们可以一起用

层中可以声明模块依赖,模块也可以引用层。比如一个"管理后台层"可能依赖 @nuxt/ui 模块。

两种使用方式

1. layers/ 目录(自动注册)

text
my-app/
├── layers/
│   └── admin/
│       ├── nuxt.config.ts     # 必须存在(即使为空)
│       ├── app/
│       │   ├── pages/         # 管理后台页面
│       │   ├── components/    # 管理后台组件
│       │   └── layouts/       # 管理后台布局
│       └── server/
│           └── api/           # 管理后台 API
└── nuxt.config.ts

layers/ 目录下的层会被自动注册,无需手动配置。

TIP

层目录名就是层名 如 layers/admin/ 的层名为 admin

2. extends 配置

ts
// nuxt.config.ts
export default defineNuxtConfig({
  extends: [
    '../shared-layer',                     // 本地路径
    '@myorg/nuxt-layer',                   // npm 包
    'github:myorg/nuxt-layer#v1.0.0',      // GitHub 仓库
  ],
})
来源语法说明
本地路径'../shared'相对路径,开发方便
npm 包'@myorg/layer'发布到 npm 的层
GitHub'github:user/repo#branch'直接从 Git 引用

两种方式的选择

项目内的层用 layers/ 目录(简单、自动注册),跨项目共享的层用 extends(更灵活、支持远程)。

层的优先级

从高到低:

  1. 项目自身文件(最高优先级)— 总是优先于层中的同名文件
  2. layers/ 目录中的层 — 按字母排序,Z > A
  3. extends 中的层 — 第一个 > 最后一个
ts
// 示例:admin 层的组件可覆盖 base 层的同名组件
export default defineNuxtConfig({
  extends: [
    '../base-layer',     // 优先级低
    '../admin-layer',    // 优先级高(可覆盖 base)
  ],
})

为什么这样设计?

项目自身文件优先 = 你始终拥有最终控制权。后声明的层优先 = 后面的层可以"定制"前面的层。这遵循了"控制反转"原则——基础层提供默认实现,项目按需覆盖。

完整示例:同文件覆盖

bash
# 层中的文件
base-layer/app/pages/about.vue 层版本

# 项目中的文件(优先使用)
my-app/app/pages/about.vue 项目版本

访问 /about 时,使用的是项目中的 about.vue,层中的版本被覆盖。

常见问题

问题原因解决方案
层不生效忘记创建 nuxt.config.ts层根目录必须有 nuxt.config.ts,即使为空
层的组件没被自动注册组件目录结构不对确保组件在 app/components/
多层覆盖同一文件不确定最终使用哪个nuxt info 查看层的加载顺序
layers/ 中层的优先级不符预期按字母排序,不是按需要用数字前缀控制顺序(1.base2.theme

基于 Nuxt 4 官方文档整理编写