大家好呀,我是你们的老倒霉蛋wangly。
最近项目的积量越来越大,项目的架构也变得非常的糟糕。中心化严重,模块化不明确,导致后续开发变得非常杂乱。所写成一篇文章给自己对中心化概念发发电。还有我也注意到有的前端工作了一年,甚至一年以上都不知道
中心化
,和去中心化
的概念。这种情况是非常不好的,一开始对于项目没有好的理解,那么项目随着体量的发展,项目也会变得越来越混乱。
本篇文章偏理论化,看完如果对你有帮助。不妨点个赞吧。
中心化 & 去中心化
所谓的中心话通俗易懂来讲其实就是以X
为中心,依赖于X
的事物都飞快的往X
身上聚集,我们用一张手图来描述下,中心化是什么样子吧。从图中可以看出,以X
为中心,发散了非常密集的节点。
而去中心化的结构类似于工程化的module
方案,通过子分子的形式将X
发散的节点进行分类。就类似于下面的分叉图。可以看到,节点通过一个主节点进行了规划。

Vue项目结构
用自己五毛的画图之术画了一个比较粗糙的Vue项目的构成,只画了一些常用的结构。
在Vue项目中,都是使用组件化的形式来声明的,将页面分为一个个组件。通过路由的形式来进行加载。那么在这些结构中,随着业务的累计不乏会出现中心化的问题。使得代码堆积难以维护。最容易产生中心化的就是组件和路由模块了。当然Mock和API还有Vuex如果不注意管理也非常容易形成中心化。
如何更好的管理项目,去中心化?
既然产生了问题,那么就需要解决问题。而解决问题的最佳方式就是去中心模块化
。我们来看下糟糕的中心化路由模块是什么样子的。
看上去,是没有什么问题的,可问题是我们页面最少会有
40+
的规模,那么这个模型看起来就会和中心化的图一样,密密麻的非常糟糕。而这个模型渲染到页面中就是将所有的路由声明都写在一个js文件中,然后无论是添加路由还是删除路由,寻找起来都是非常麻烦的一件事情。所以我们需要对项目模块进行去中心化。达到一个多节点多分支的结构。
路由去中心化
上面提到了路由的中心化问题,那么这里就来就来解决下吧。其实对于此类方法,文件声明即注册。webpack中的require.context
很好的解决了这个问题。
官方对于require.context
的描述:点击前往
通过require.context
对文件夹进行导入分析。将其中导出的内容进行拼接最后挂载到路由实例中。那么先来创建两个测试路由文件。
通过
require.context
来看下我们导入的文件
const routerFiles: __WebpackModuleApi.RequireContext = require.context('./module', true, /\.ts$/)
console.log(routerFiles.keys())
获取到了导入文件的上下文,那么尝试获取一下默认的export
是否可以拿到路由,如下图。我们获取了第一个ts文件的导出。
const routerFiles: __WebpackModuleApi.RequireContext = require.context('./module', true, /\.ts$/)
console.log(routerFiles.keys())
console.log(routerFiles(routerFiles.keys()[0]).default)
既然能够拿到。那么我们只需要将所有的文件内容获取到进行拼接就可以获取到完整的路由列表了。如下图,一个路由列表就已经产生出来了。
import { RouteConfig } from 'vue-router'
const routerFiles: __WebpackModuleApi.RequireContext = require.context('./module', true, /\.ts$/)
const routerList: RouteConfig[] = []
routerFiles.keys().forEach((fileName:string) => {
if (routerFiles(fileName).default instanceof Array) {
routerList.concat(routerFiles(fileName).default)
} else {
routerList.push(routerFiles(fileName).default)
}
})
console.log(routerList)

通过上述代码,我们只要在文件夹下面声明路由文件,导出RouteConfig
对象就可以对路由表进行管理。当某个路由需要修改的时候。只需要修改该路由对应的文件对象就可以了。
这是一个非常简单的路由去中心化。代码不多,方便理解。其实,对于路由的管理,Nuxt的约定式路由是让我心动了。也在整这个东西,(●'◡'●)。
Vuex模块化
糟糕的Vuex就是将state
, mutations
, actions
,getters
写在一起。看起来是非常杂乱的。那么对于全局变量管理是非常不友好的。往往会出现变量混杂。不利于管理。对state
和actions
的作用产生一个误会。当Vuex的内容越来越多的时候,中心化的问题也逐步显现。
所以最好是使用Vuex自带的模块化。并且将命名空间开启。那么就可以将Vuex进行模块化。后续使用就可以通过moduleName/xxx
进行使用。
import { MutationTree } from 'vuex'
// Vuex参数接口
export interface IApp {
isShowToolBar: boolean
colorTheme: string
}
// state 状态
const state: IApp = {
isShowToolBar: true,
colorTheme: '#515a6e'
}
// mutations方法
const mutations: MutationTree<any> = {
setShowToolBar: (state: IApp, bool: boolean) => {
state.isShowToolBar = bool
},
setColorTheme: (state: IApp, color: string) => {
state.colorTheme = color
}
}
export default {
namespaced: true,
state,
mutations
}
请求与视图分离。
现如今,还可以看到一些开发者将Network Request
代码放在视图中,这样随着业务代码的增量,接口维护也变得越来越艰难。而将API
请求分离出来做统一管理是一种优雅的方式,你只需要在视图页面中直接获取数据然后将其赋值到页面需要的变量上去。

const { data } = await _api_mock_login(params)
组件去中心化
我们以和路由的同样方式管理页面的组件,下面列出一张项目结构对比。每一个页面都做自己独立的管理。千万不要堆积在自己的项目的根文件。不然页面和组件辨识度非常低。容易给别人接盘的人挖坑。


总结后话
在开发Vue项目中,最好使用模块化管理项目,千万不要造成文件冗余。合理的使用require.context
的特性可以对项目文件做一个声明。对于Vue项目如果管理不好对于开发时是非常难受的事情,你需要在文件中翻来覆去的找东西。因此最好的方式就是,一个模块尽量做当前模块的事情,将其他模块需要做事情抽离出去。尽量降低耦合度。尽量不要让自己的项目堆叠,产生中心化。
如果觉得有用不妨点个赞支持一下。另外找工作。上杭广深都可以。