我所理解的代码风格最佳实践(3):Nuxt 页面、目录与自动导入
- JavaScript 代码怎样从调用点读下去
- Vue 组件与 composable 的职责边界
- Nuxt 页面、目录与自动导入(当前)
- 哪些项目约定值得写成 Lint
接手一个 Nuxt 页面,我通常从 URL 找路由文件,再从模板找页面组件,最后去看谁负责数据。以 Nuxt 4 的 /me 为例,如果这条路能走通,修改个人主页的一张资料卡就不必先理解整个账号模块。
目录已经表达的名字,文件只写一遍
app/
pages/
me/
index.vue
components/
me/
profile-card.vue
common/
search-box.vue
composables/
useMePage.ts
app/pages/me/index.vue 是路由入口,负责页面组装、路由输入和页面 meta。资料卡的展示由 app/components/me/profile-card.vue 承担,页面请求、派生数据和需要协调的交互可以放在 useMePage.ts。这套结构下,app/pages 里的文件一眼就能认作路由的一部分。
按默认组件扫描约定,me/profile-card.vue 可以在模板里写成 <MeProfileCard>。目录已经提供 Me,文件只写 profile-card。如果之后有多个页面共用一个组件,先问它是否仍属于个人主页。通用搜索框可以归到 common/search-box.vue。跨页面使用、仍带账号业务规则的组件,可以移到更准确的业务域。若项目自定义了 pathPrefix、扫描目录或前缀,最终名字以项目生成的组件声明为准。Nuxt 组件目录文档
app/composables 的默认扫描范围与组件目录不同。页面入口放顶层时,useMePage.ts 可以按约定被发现。需要嵌套组织时,可以从顶层入口重导出,或者明确配置扫描范围。我倾向先保留单个可发现的公开入口,让内部 helper 跟着自己的模块走。路由、组件和 composable 虽然都由框架发现,查找规则各有自己的边界。Nuxt composables 扫描说明
自动导入要划定范围
在 Nuxt 页面里,ref、computed 和 <MeProfileCard> 可以按框架约定使用。我会先看这些名字从哪里来。明确在 Nuxt 扫描范围里、名字能由约定推导出来的本地组件,以及框架会补齐的 Vue 运行时 API,可以交给自动导入。组件名有冲突、组件要显式作为值使用,或者团队需要在该处标明来源时,显式导入也很合理。Nuxt 为此提供 #components 和 #imports 入口。Nuxt 自动导入文档
类型依赖应单独判断。import type { Ref } from 'vue' 表达的是类型来源。要求自动导入 Vue 运行时 API 的项目规则,应该区分类型与值,也应该限定在经过 Nuxt 转换的文件。共享包、独立 Node.js 脚本和直接运行的测试文件各有自己的执行环境,按它们实际能解析的依赖来写。
修改扫描配置或移动组件以后,我会先看 .nuxt/components.d.ts 和生成的导入声明,确认名字指向预期文件。再打开真实页面验证组件是否渲染、路由是否正常,涉及 SSR 时还要看首次请求与客户端接管。Lint 可以验证路径、名字和导入形式。框架最后识别到了哪个组件,仍要看生成和运行结果。组件名推导、混合 type/value import 和规则测试可以放在一起看。Nuxt 自动导入的 ESLint 护栏
从目录归属继续追到运行时
页面域能解释代码归谁,运行时还要回答状态何时可读、依赖何时就绪。Header 如果等页面渲染后反向写入自己的初始状态,首屏与客户端接管就可能对不上。插件如果在依赖的 Pinia 实例就绪前调用 store,也可能让启动流程直接失败。这两类问题都适合保留完整的排查过程。