1.5 项目结构与目录规范


1.5 项目结构与目录规范

本节导读:环境就绪后,本节摊开工程的目录结构,讲清每个约定目录在编译时扮演的角色,以及 easycom 约定式注册如何改变组件的组织方式。目录规范是团队协作的第一道公约,也是排查"文件没被编译"类问题的地图。

本章主线案例推进到这一站时,商城团队已经把环境跑通,接下来是立规矩:什么代码放哪里、谁负责维护哪一块。uni-app 的目录约定并不复杂,但每一条约定背后都连着编译器的某种行为——放错位置的文件不是"不好看",而是干脆不参与编译。先看一张标准的工程目录图。

my-shop/ ├── pages/ # 页面目录:每个页面一个文件夹,必须在 pages.json 登记 │ ├── index/index.vue # 首页 │ └── goods/detail.vue # 商品详情 ├── static/ # 静态资源:图片、字体,原样拷贝进产物,不参与编译 ├── store/ # 全局状态(Pinia 或 Vuex),第 5 章展开 ├── utils/ # 工具函数:请求封装、格式化等纯逻辑 ├── components/ # 自定义组件(非 easycom 命名的需手动引入) ├── uni_modules/ # 插件与组件库的标准形态,easycom 自动扫描 ├── App.vue # 应用生命周期:启动逻辑、全局样式在此引入 ├── main.js # 入口:创建应用实例、挂载全局插件 ├── manifest.json # 应用配置:appid、各端专属配置(含条件编译) ├── pages.json # 页面路由与窗口表现:全局样式、tabBar、分包 └── uni.scss # 全局样式变量:编译期注入每个页面的样式

约定目录背后的编译行为

pages 目录与 pages.json 是强绑定的:json 里没登记的页面文件不会被编译成可跳转的页面,这是"新增页面打不开"问题的头号原因。static 目录的行为相反——原样拷贝,不加工,所以放超大图片会直接撑爆小程序主包;业务上推荐的分界线是"会随代码更新的资源进 static 并控制体积,大素材放网络"。uni.scss 特殊在编译期注入:在里面定义的变量不需要 import 就能在任何页面的样式里使用,但也因此别把具体样式值写进去,只放变量与混入。manifest.json 与 pages.json 都支持条件编译,某个端专属的配置(比如 App 端的模块声明、小程序的专属属性)就写在这里,第 4 章会反复回到这两个文件。

App.vue 与 main.js 的分工常被混用,给出一条可执行的判断标准:与"页面渲染"无关的一次性逻辑进 App.vue 的应用生命周期,需要拿到应用实例或注册插件的进 main.js

// main.js(Vue3 项目) import App from './App'; import { createSSRApp } from 'vue'; import * as Pinia from 'pinia'; export function createApp() { const app = createSSRApp(App); app.use(Pinia.createPinia()); // 请求封装等纯逻辑不要在这里初始化,放 utils 里按需引入 return { app, Pinia }; }
<!-- App.vue --> <script> export default { onLaunch() { // 应用启动一次性的逻辑:读取更新配置、初始化埋点 console.log('应用启动'); }, onShow() { // 从后台切回前台:适合做角标清理、会话续期 } }; </script> <style> /* 全局公共样式写在这里,等效于每个页面都引入 */ page { background-color: #f6f7fb; } </style>

特殊目录与它们的编译命运

公约之外还有几个特殊成员,各有各的编译规则。static 的平台子目录:在 static 下按平台标识建子目录(比如 static 下建 mp-weixin 目录),里面的资源只进对应端的产物,用来放平台专属的分享图、审核素材之类,是目录层面的"条件编译"。uni_modules 的内部分工:每个插件自带独立的目录声明,编译器按声明决定把哪部分送进哪端产物,这也是它比裸 components 目录更适合分发的原因。hybrid 与 nativeplugins:前者放本地 html 页面(App 端可用 plus 打开),后者放原生插件包,两者都只在 App 端有意义,其他端编译时直接无视。挑重点画成一张图:

static/ ├── logo.png # 全端共有:每端产物都带 └── mp-weixin/ └── share-card.png # 平台专属:只进微信小程序产物 uni_modules/ └── ht-share/ # 每个插件自带声明,编译器按声明分发 ├── changelog.md └── ...

把资源"按端归档"的思路记住,后面遇到"这张图只想在小程序里展示"之类的要求,第一反应应该是目录分流,而不是在业务代码里写一堆平台判断。目录能解决的分叉,就不劳条件编译出手——这是两条分叉通道的分工边界。

easycom:约定优于配置的组件管理

传统写法里,每个页面要用组件都得先 import 再注册,页面头部堆满重复声明。easycom 改变这一点:只要组件放在规范路径下(components 目录下"组件名目录/组件名.vue",或 uni_modules 插件内),模板里直接写标签即可,编译器按约定自动引入,没有用到的组件不会被打包。这让"组件库即装即用"成为可能,也是第 3 章 UI 框架集成的前提。

// pages.json 中可自定义 easycom 匹配规则(默认规则已覆盖常用场景) { "easycom": { "autoscan": true, "custom": { "^ht-(.*)": "@/components/ht-$1/ht-$1.vue" } } }

配置后,模板里写 <ht-badge text="NEW" />,编译器会自动到 components 目录下找 ht-badge 组件并注入。规则的正则匹配发生在编译期,所以这条链路同样吃条件编译——某端独享的组件可以配合 #ifdef 放在对应平台的产物里。

一份可直接落地的目录公约

把上面的机制翻译成团队公约:页面进 pages 且同步登记路由;纯逻辑进 utils、不依赖任何界面对象;全局可复用的展示单元进 components 并按 easycom 命名;第三方能力优先找 uni_modules 形态的插件;静态资源进 static 并设体积上限;全局状态进 store 并按业务域拆模块。公约的价值在多端项目里被放大——目录即编译边界,边界清晰,条件编译的落点才能清晰。

本节要点回顾

  • 目录约定连着编译行为:pages 需登记、static 原样拷贝、uni.scss 编译期注入,放错位置等于不存在;
  • App.vue 管应用生命周期与全局样式,main.js 管实例创建与插件注册,按"是否碰渲染"划界;
  • easycom 把组件注册下沉到路径约定,是组件库即装即用的机制基础;
  • 目录即编译边界,先立公约再写业务,多端项目的条件编译才有的放矢。

第 1 章到此收束。下一章进入语言层:同一套 Vue 语法在 uni-app 里的方言与边界。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U