模块划分
- 业务模块:按照业务功能划分,例如用户模块(包含登录、注册、个人信息管理等)、订单模块(下单、订单查询、订单管理等)、商品模块(商品展示、搜索、详情等)。每个业务模块独立开发,拥有自己的组件、路由、状态管理等,降低模块间的耦合度。
- 基础模块:包括网络请求模块(封装Axios等库,统一处理请求拦截、响应拦截等)、工具模块(如日期处理、字符串处理等通用工具函数)、UI 组件库模块(可复用的基础 UI 组件,如按钮、表单等)。这些基础模块为业务模块提供支持,避免在多个业务模块中重复编写代码。
代码组织
- 组件目录结构:每个业务模块下创建 components 目录,存放该模块内的组件。组件按照功能或展示类型进一步细分目录,如 atoms(原子组件,最基础的不可再分的组件,如按钮)、molecules(分子组件,由原子组件组合而成,如表单)、organisms(有机体组件,由分子组件组合而成,实现特定业务功能的复杂组件,如商品列表)。
- 路由文件:在每个业务模块下创建 router 目录,存放该模块的路由配置。在项目根目录的 router 文件夹中,通过
import()
异步导入各个业务模块的路由配置,实现路由的异步加载。例如:
const userRouter = () => import('@/modules/user/router');
const orderRouter = () => import('@/modules/order/router');
const routes = [
{
path: '/user',
name: 'User',
component: () => import('@/modules/user/views/User.vue'),
children: userRouter.routes
},
{
path: '/order',
name: 'Order',
component: () => import('@/modules/order/views/Order.vue'),
children: orderRouter.routes
}
];
- 状态管理:采用 Vuex 进行状态管理,每个业务模块可以有自己的 store 模块,在项目根目录的 store 文件夹中通过
import()
异步导入各个业务模块的 store 模块,实现状态管理的模块化。例如:
const userStore = () => import('@/modules/user/store');
const orderStore = () => import('@/modules/order/store');
const store = new Vuex.Store({
modules: {
user: userStore,
order: orderStore
}
});
加载策略
- 路由懒加载:使用 Vue 的异步组件结合路由进行懒加载,如上述路由配置中的
component: () => import('@/modules/user/views/User.vue')
方式,只有当路由被访问时才会加载对应的组件,减少初始加载的代码量。
- 动态导入优化:对于一些体积较大的模块,可以通过 Webpack 的
splitChunks
配置进行代码分割,将公共代码提取出来,避免重复加载。例如:
module.exports = {
optimization: {
splitChunks: {
chunks: 'all',
minSize: 30000,
maxSize: 0,
minChunks: 1,
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'all'
},
common: {
name: 'common',
minChunks: 2,
chunks: 'initial'
}
}
}
}
};
- 预加载:对于一些预计用户可能会访问的页面,可以使用
<router - link>
的 prefetch
属性进行预加载,例如 <router - link to="/order" prefetch>订单</router - link>
,这样在用户点击链接前,浏览器就会提前加载对应的组件,提高用户体验。
- 按需加载第三方库:对于一些体积较大的第三方库,如图表库等,如果不是在首页立即使用,可以在需要使用的组件中动态导入,而不是在入口文件全局导入。例如:
export default {
methods: {
async generateChart() {
const echarts = await import('echarts');
// 使用 echarts 生成图表的代码
}
}
};