大型Vue项目中如何组织mixins、filters和directives的引入
大型Vue项目 Mixins、Filters、Directives 组织引入规范
统一目录分层约定
首先把三类公共能力从零散的业务代码里抽出来,统一收敛到独立目录下管理,避免散落在各个组件文件夹里难以查找维护:
src/ ├── shared/ # 存放全项目通用轻量能力 │ ├── mixins/ # 公共mixins集合 │ ├── filters/ # 公共filters集合 │ └── directives/ # 公共指令集合 ├── views/ # 页面级业务代码 ├── components/ # 可复用业务组件 └── main.js
Mixins 引入逻辑规则
- 严格按单一职责拆分mixin文件:每个mixin只解决一类通用问题,比如处理分页列表逻辑的
pageList.js、处理按钮权限的authControl.js、处理表单通用校验规则的formRule.js,坚决不写一个大而全的globalMixin塞所有逻辑,避免后期改一个逻辑引发全项目连锁问题 - 全局注册白名单机制:只有全项目所有页面100%需要复用的逻辑才允许走全局注册,比如统一的错误上报埋点、全局的路由跳转拦截逻辑。这类mixin统一在
shared/mixins/index.js中导出,在main.js中通过实例方法注册,每个全局注册的mixin必须写清楚作用、使用注意事项,禁止把业务逻辑的mixin挂到全局 - 业务侧一律按需局部引入:除了白名单里的全局mixin,其他场景用到的mixin直接在对应组件/页面里导入挂载,比如某个列表页需要分页逻辑,就直接在组件配置中
import pageList from '@/shared/mixins/pageList',通过mixins: [pageList]挂载,不要为了开发方便把所有mixin都全局注册,减少组件初始化时的无用逻辑加载 - 迭代过程做版本隔离:如果某个公共mixin需要调整核心逻辑,不要直接修改原文件影响存量业务,而是新建版本迭代文件比如
pageListV2.js供新页面使用,等存量页面逐步迁移完成后再删除旧版本,避免改动引发线上故障
Filters 引入逻辑规则
- 纯函数约束:所有filter实现必须是无状态的纯函数,只做入参转输出的格式化操作,禁止在filter里写异步请求、DOM操作、修改全局状态这类带副作用的逻辑,保证同一个输入永远能得到同一个可预测的输出
- 全局注册批量处理:所有通用filter统一在
shared/filters/index.js中导出为对象,在main.js中通过循环批量注册,不要在main.js里一个个单独import注册,减少冗余样板代码,示例如下:// shared/filters/index.js import formatDate from './formatDate' import formatMoney from './formatMoney' export default { formatDate, formatMoney } // main.js import * as filters from '@/shared/filters' Object.keys(filters).forEach(key => { app.config.globalProperties.$filters[key] = filters[key] }) - 局部小逻辑不强行抽公共:如果某个格式化逻辑只有单个组件用到,直接在组件内部写方法或者computed实现就行,不要为了“看起来规范”就把这类小逻辑抽成公共filter放到全局,不然全局filter列表会越来越庞杂,后期没人记得哪些是无引用的废弃逻辑
- 定期做冗余清理:每个迭代周期遍历一遍所有filter的引用情况,把没有任何页面使用的filter直接删除,避免项目代码持续膨胀
Directives 引入逻辑规则
- 按功能拆分独立指令文件:每个指令只实现一类可复用的DOM操作逻辑,比如控制按钮显隐的
v-permission、实现点击复制的v-copy、处理图片懒加载的v-lazy,不要把所有指令逻辑都塞在一个超大文件里 - 全局指令统一入口注册:所有需要全局使用的指令,统一在
shared/directives/index.js中导出,循环注册到Vue实例上,避免在main.js里写一堆零散的注册代码,示例如下:// shared/directives/index.js import permission from './permission' import copy from './copy' export default [permission, copy] // main.js import directives from '@/shared/directives' directives.forEach(directive => { app.directive(directive.name, directive) }) - 专用指令局部注册:如果某个指令是特定组件专属的,比如复杂表格组件用到的拖拽排序指令,直接在那个组件内部局部注册就行,不要把这类非通用指令放到全局,避免污染全局API列表
- 全局指令准入要求:所有要注册为全局的指令,必须经过代码评审确认是全项目通用能力,团队成员不能随便把自己临时写的脚本逻辑挂到全局指令里
通用避坑约定
- 三类公共能力里禁止写强业务耦合的逻辑:比如mixin里硬编码某个特定页面的接口请求、filter里直接读取全局状态的特定字段、指令里直接处理路由跳转逻辑,不然这些公共能力会和业务绑死,完全失去复用价值
- 统一能力使用边界:比如时间格式化的逻辑,统一用filter或者工具函数实现,不要在mixin里再重复写一套相同逻辑,避免同个功能存在多份实现,后期修改时漏改引发问题
- 定期做废弃代码清理:每季度梳理一次三类公共能力的引用情况,删掉没有任何场景使用的废弃文件,降低新人接手的理解成本
内容的提问来源于stack exchange,提问作者Bro From Space
相关产品推荐
相关产品推荐

