Vue3项目结构该怎么规划才合理?
很多刚接触Vue3的同学,打开项目文件夹时经常一头雾水——src里的assets、components、router这些文件夹分别负责啥?不同功能的代码该往哪放?项目大了怎么避免文件乱糟糟?今天就用问答形式,把Vue3项目结构的规划逻辑、核心文件夹作用、实战优化技巧这些讲明白,帮你理清项目组织的思路~
Vue3项目的核心文件夹都是干啥的?
打开Vue3项目最关键的src
文件夹,里面几个核心文件夹分工很明确:
- assets:存静态资源,比如图片、图标、全局样式(像reset.css)、字体文件,举个例子,项目里通用的logo.png、全局主题色变量文件(如果用Sass,_variables.scss)都丢这。
- components:放「可复用的小组件」,比如按钮组件、弹窗组件、搜索框
,这些组件不属于某个特定页面,多个页面都能调用,所以集中在这管理。 - router:路由配置中心!index.js里写路由规则,比如登录页、首页的路径和对应的页面组件,项目大了还能拆分模块路由(像adminRouter.js、userRouter.js),再合并到主路由里。
- store:状态管理(现在主流用Pinia,以前是Vuex),如果用Pinia,每个业务模块的状态单独写文件,比如userStore.js管用户信息,productStore.js管商品数据,最后在index.js里整合,方便全局调用。
- views:「页面级组件」的家!每个文件对应一个完整页面(比如LoginView.vue、HomeView.vue),和router里的路由配置一一对应,页面里还能嵌套components里的小组件,比如HomeView里用
、。 - utils:工具函数集中营!像时间格式化(formatTime.js)、权限判断(checkPermission.js)、axios请求封装(request.js)这些通用工具,丢这统一管理,避免重复写代码。
项目分层该按功能还是按模块来?
这得看项目规模:
- 中小型项目→按「功能分层」 简单直接!把所有组件丢components,所有工具丢utils,所有页面丢views,好处是结构清晰,新人好上手;缺点是项目大了,找文件要翻遍文件夹,比如想改用户模块的代码,得在components、views、api里来回跳。
- 大型项目→按「模块分层」 更高效!比如做电商项目,拆出user(用户模块)、goods(商品模块)、order(订单模块),每个模块里自己搞components(模块内私有组件)、api(模块接口)、views(模块页面),像user模块里,userComponents放用户专属的
,userApi.js写用户登录、信息修改的接口,userView里放个人中心页面,这样模块内的代码高度内聚,改需求时只动一个模块,不会牵一发动全身。
小项目功能分层快;大项目模块分层稳,后期维护少掉头发~
Pinia状态管理在项目里咋放文件?
用Pinia时,store
文件夹的结构可以这么玩:
- 每个业务模块单独写Store文件:比如用户模块写
userStore.js
,里面定义用户信息的state、修改信息的actions(Pinia里没有mutations,直接改state),代码大概长这样:import { defineStore } from 'pinia' export const useUserStore = defineStore('user', { state: () => ({ name: '', age: 0 }), actions: { setName(newName) { this.name = newName } } })
- 主文件
index.js
整合所有Store:在index.js里创建Pinia实例,再把各个模块的Store导入,方便全局注册。import { createPinia } from 'pinia' import { useUserStore } from './userStore' import { useGoodsStore } from './goodsStore'
const store = createPinia() // 可以把各个Store挂载到store实例上,方便全局访问 store.user = useUserStore(store) store.goods = useGoodsStore(store)
export default store
这样做的好处是,每个模块的状态管理独立,代码解耦,比如要加新模块,直接新建xxxStore.js,再导入到index.js就行,不用动其他文件。
### 四、接口请求(axios)的文件该咋组织?
接口管理乱了,后期改接口地址能把人逼疯!所以得规范:
1. **封装axios基础配置→utils/request.js** 这里做全局配置:设置基础路径(baseURL)、请求拦截器(加token)、响应拦截器(统一处理错误)。
```js
import axios from 'axios'
const request = axios.create({
baseURL: import.meta.env.VITE_API_BASEURL, // 从环境变量拿基础地址
timeout: 5000
})
// 请求拦截器:加token
request.interceptors.request.use(config => {
const token = localStorage.getItem('token')
if (token) config.headers.Authorization = `Bearer ${token}`
return config
})
// 响应拦截器:处理错误
request.interceptors.response.use(
res => res.data,
err => {
if (err.response.status === 401) {
// 跳登录页
}
return Promise.reject(err)
}
)
export default request
- 按模块分接口文件→api文件夹 比如用户模块的接口放
api/userApi.js
,商品模块放api/goodsApi.js
,每个文件里用request封装请求函数:// userApi.js import request from '@/utils/request' export function login(data) { return request.post('/user/login', data) } export function getUserInfo() { return request.get('/user/info') }
// goodsApi.js import request from '@/utils/request' export function getGoodsList(params) { return request.get('/goods/list', { params }) }
这样写的好处是,调用接口时超级清晰:<code>import { login } from '@/api/userApi'</code>,后期改接口路径只需要动api文件夹里的文件,不用满项目找axios请求~
### 五、路由文件怎么拆分更清晰?
路由配置乱了,页面跳转容易404!拆分思路参考这两种:
- **基础版:单文件管理→router/index.js** 适合小项目,所有路由规则写在index.js里。
```js
import { createRouter, createWebHistory } from 'vue-router'
import HomeView from '@/views/HomeView.vue'
import LoginView from '@/views/LoginView.vue'
const routes = [
{ path: '/', name: 'home', component: HomeView },
{ path: '/login', name: 'login', component: LoginView }
]
const router = createRouter({
history: createWebHistory(),
routes
})
export default router
- 进阶版:按模块拆分路由→router/模块路由.js 大项目里,把管理员路由、用户路由拆成单独文件,比如
router/adminRouter.js
:import AdminDashboard from '@/views/admin/AdminDashboard.vue' import AdminUserManage from '@/views/admin/AdminUserManage.vue'
export const adminRoutes = [ { path: '/admin/dashboard', component: AdminDashboard }, { path: '/admin/user-manage', component: AdminUserManage } ]
然后在<code>router/index.js</code>里合并:
```js
import { createRouter, createWebHistory } from 'vue-router'
import { adminRoutes } from './adminRouter'
import HomeView from '@/views/HomeView.vue'
const routes = [
{ path: '/', component: HomeView },
...adminRoutes // 展开管理员路由
]
const router = createRouter({...})
export default router
嵌套路由(比如页面里的 tabs)也可以在对应页面的路由配置里用children
,比如HomeView里有个个人中心子页面:
{ path: '/home', component: HomeView, children: [ { path: 'profile', component: HomeProfile.vue } ] }
这样拆分后,路由和页面结构一一对应,找路由配置和改权限(比如管理员路由加导航守卫)都更方便~
样式文件该和组件放一起还是集中管理?
样式管理分两种场景:
- 组件私有样式→单文件组件里的 每个.vue文件里的