Nuxt Layers 简单尝试

857 阅读5分钟

在 Web 开发中,效率和灵活性往往相互矛盾,但 Nuxt 3 的 Layers 功能正在改变这一现状。

Nuxt提供了一个强大的系统,可以让您扩展默认文件、配置等多种内容。 Nuxt的核心功能之一是层和扩展支持。您可以扩展默认的Nuxt应用程序,以便重用组件、工具和配置。层结构几乎与标准的Nuxt应用程序相同,这使得它们易于编写和维护。 Article

可能是题外话

我司外包项目时经常会启各种新的项目。 起初是 Vue 基于 @antfu 的 vitessevitesse-lite 模板开发项目,这个两个模板真的非常棒,各种开箱即用的功能,还有 File based routing,Unocss 配置,通常情况下再配上一个 Naive UIPrime Vue 就可以开始复刻设计图,完成交互功能。

而后接触了 Nuxt 框架,开始试着学习和使用 vitesse nuxt3 模板,并对我司情况做了fork,修改了一些预设。 但我司 Web3 类的项目比较多,很多各种链的好用的库都是 React First ,为了开发效率后面又转向了 Next.js,在私有仓库建立了基于 Next.js 的模板。做完一个项目后,无法满足于 Webpack 的编译速度,就做了一个 Vite + React + @tanstack/react-router 的模板在公司内部使用。但我终究无法参透 React。

最近深入逛 Nuxt 文档时,突然发现了 Layers 功能,虽然它本身可能已经存在很久了,但之前看文档的时候把它遗漏掉了。跟着视频简单尝试了下后发现这个功能真的很不错,我就想着做一个模板,能快速的在新项目中使用。简单参悟其功能后,便起草了本篇文章。(Layers 功能并不十分稳定,我简单测试了下,最好不要用于生产环境)

使用

创建一个新的文件夹,用于放 Demo。

$ pwd
/Users/cyenoch/Workspace/demo/nuxt-layers

使用 bun x nuxi@latest init base-layer 借助 Bun 趁文件夹还没热乎快速创建一个Nuxt项目。

再使用 bun x nuxi@latest init my-app 借助 Bun 趁文件夹还没完全热乎快速创建另一个Nuxt项目。

此时文件夹结构如下:

$ tree -L 2
.
├── base-layer
│   ├── README.md
│   ├── app.vue
│   ├── bun.lockb
│   ├── node_modules
│   ├── nuxt.config.ts
│   ├── package.json
│   ├── public
│   ├── server
│   └── tsconfig.json
└── my-app
    ├── README.md
    ├── app.vue
    ├── bun.lockb
    ├── node_modules
    ├── nuxt.config.ts
    ├── package.json
    ├── public
    ├── server
    └── tsconfig.json

创建/修改 Base Layer

修改 ./base-layer/app.vue 内容如下:

<template>
  <div>
    <NuxtRouteAnnouncer />
    <NuxtPage />
  </div>
</template>

创建组件 BaseCounter 在文件 ./base-layer/components/base/counter.vue 内容如下:

<template>
  <div>
    <p>{{count}} from base layer</p>
    <button @click="count ++">+</button>
    <button @click="count --">-</button>
  </div>
</template>

<script setup lang="ts">
const count = ref(0)
</script>

创建页面 base-layer/pages/base/index.vue 内容如下:

<template>
  <div>
    <BaseCounter />
  </div>
</template>

使用 bun x nuxi dev ./base-layer 运行 base-layer

然后进入 localhost:3000/base 就可以看到页面,内容非常的简单:

image.png

然后就可以把刚刚启动的 nuxi 关了

使用 Base Layer

进入 my-app 文件夹,修改 nuxt.config.ts 为:

export default defineNuxtConfig({
  compatibilityDate: '2024-04-03',
  // 通过 `extends` 配置,使用 `base-layer`。
  // 它还支持使用远程仓库,比如: extends: ['github:Cyenoch/vitesse-nuxt3#layer']
  extends: ['../base-layer']
})

使用 bun dev 运行 my-app

duang!

image.png

姨?怎么是 NuxtWelcome??

别急,base layer 的页面文件在其项目目录下的 base/index.vue 所以要进入 localhost:3000/base

image.png

为什么还是 NuxtWelcome??

别急,因为 my-app 已经有了 app.vue ,故 base-layer 中的 app.vue 没有被使用。我们修改 my-appapp.vue 使其使用 NuxtPage 而不是 NuxtWelcome

<template>
  <div>
    <NuxtRouteAnnouncer />
    <NuxtPage />
  </div>
</template>

保存后立即生效,我们能看到页面更新了:

image.png

直接使用 base-layer 的组件?

我们在 my-app 创建一个页面 pages/index.vue 入口页,并写入以下内容:

  <div>
    <h3>MyApp 使用 Base Layer 的 BaseCounter 组件:</h3>
    <BaseCounter />
  </div>
</template>

<script setup lang="ts">
</script>

代码提示?当然是有的!

image.png

然后浏览器修改路径,进入首页:

image.png

base-layer 使用 Nuxt Modules ?

是能使用的, 直接在 base-layer 中安装 module

image.png

my-app 也能有代码提示。

image.png

其功能也能正常使用:

image.png

image.png

应用

那么实际情况中我们能用这个特性做什么呢?

我司之前用过 Ruoyi、ThinkPHP 等框架、权限模板去做系统的后台,对接是真的麻烦,部署也是真的麻烦。

  • 可以做一个基础模板,加入一些常用module和配置。
  • 然后为不同的项目基于基础模板创建一个应用layer,写interface,auth middleware等。
  • 然后用应用layer做 后台管理面板layer,并将路由路径设置在 /admin 下。
  • 再用应用layer做用户端layer
  • 最后创建一个空nuxt项目将它们组合起来,配一个CI,就能一起部署。(想法挺好的,不知道实际效果会咋样。。。反正都是个屎山QAQ)

然鹅

Layers 的功能和稳定性还待继续完善,目前为止最好不要用于生产。