CSCCockroach 2020-09-15
本文转载自公众号“读芯术”(ID:AI_Discovery)。
作为基于JavaScript的框架,Vue.js最近几年中发展迅速,原因很多,包括框架的简单性、易于集成性、用户友好性以及限制较少等等,这些特性也帮助Vue.js在与Angular和React竞争时有一战之力。
但在搜索Vue的局限性时,我发现很多人都提到了它对大型项目缺乏支持这一现象。不过在深入了解之后,我可以自信地说并非如此。因此,本文将讨论4种可用于组织大型Vue.js项目的优秀实践。
1. 使用Vue Slots使代码易于理解
父子关系是组件之间相互连接的最常用方法之一,但有时这可能并不是最佳选择。想象一下,如果出现在单个父组件中有大量子组件的情况,那么可能就不得不使用大量道具和发出事件来处理这些子组件,很快一切会变得一团糟。
这就是在大型项目中将要面临的真实情况,不过,Vue.js可以提供针对此问题的现场解决方案。
我们可以在Vue.js中使用slots来提供表示父子关系的另一种方法,slots提供了将内容放置在新位置的渠道。slots的基本操作示例如下所示:
<div> <slot></slot> </div>
当上面的组件呈现的标签将被demo-content替换时:
<demo-content> <h2>Hi!</h2> <class-name name="Welcome toVue!"></class-name> </demo-content>
你可以在Vue项目中使用多种不同类型的slots。但最重要的一点是,当slots在增多时,项目也会随之受到巨大的影响,slots可以使得整个项目中的代码维持完整且易于理解。
2. 建立并共享独立的组件
AddyOsmani:“有效构建‘大型'事物的秘诀通常是避免从一开始就抱着直接构建大型事物的想法。相反,可以用更小、更集中的作品来构成大型事物。这样一来,就更容易看到小的事物是如何组成大的事物的了。”
你可以遵循F.I.R.S.T原则,将自己的组件构建为:专注的、独立的、可重复使用的以及小型且可测试的。
还可以使用Bit(Github)之类的工具对每个项目的组件进行独立式源代码管理,并将其共享给Bit的组件中心。共享的组件、自动生成的文档和实时示例将一起显示在Bit的组件中心上。可以使用NPM进行安装或使用Bit对其进行“克隆”和修改,这会使查找、使用和维护组件变得更加容易(因此,也更易于维护项目)。
Vue components shared on Bit.dev
3. 维护良好的VUEX仓库
Vuex是Vue.js中的状态管理模式,它负责应用程序中所有组件的集中存储功能。我看到有些评论说:“Vuex限制了开发人员根据需要构造项目”。但事实是,Vuex可以通过使用一组原则来帮助开发人员以更有条理的方式组织他们的项目。
在了解这些原理之前,首先应该先了解以下4个Vuex仓库中的主要组件:
那么接下来看看需要遵循的原则:
遵循这三个原则,项目就可以被顺利地组织出来,并且如果你觉得存储文件越来越大,可以将它们拆分成单独的文件。示例项目结构如下所示:
├── index.html ├── main.js ├── api ├── components └── store ├── index.js ├── actions.js ├── mutations.js └── modules
模块化VUEX仓库
图源:unsplash
本文中讨论的是大型项目,此类项目中的项目文件会非常大而复杂。你需要以自己的方式管理仓库,并且需要避免商店仓库,因此最好以易于他人理解的方式对Vuex仓库进行模块化。
在此我们没有定义项目中模块的定义方法,有些开发人员会根据功能进行模块化,有些则根据数据模型进行模块化。关于模块化的最终决定完全取决于你自己,这将对个人和团队有长期帮助。
store/ ├── index.js └── modules/ ├── module1.store.js ├── module2.store.js ├── module3.store.js ├── module4.store.js └── module5.store.js
使用助手来简化代码
前文提到了Vuex仓库中使用的4个组件。假设如果出现需要访问这些states、getters或需要调用actions或组件中的mutations的情况,那么无需创建多个计算属性或方法,就可以轻松使用辅助方法(mapState, mapGetters, mapMutations 和 mapActions)来减少代码。
来看看这四个辅助工具:
(1) mapState
如果需要在一个组件中调用多个存储状态属性或getters,就可以使用mapState帮助生成一个getter函数,这将大大减少代码行的数量。
import { mapState } from 'vuex'export default { computed: mapState({ count: state => state.count, countAlias: 'count', countPlusLocalState (state) { return state.count +this.localCount } })}
(2) mapGetters
mapGetters可帮助将仓库getters映射到本地计算属性。
import { mapGetters } from 'vuex'export default { computed: { ...mapGetters([ 'count1', 'getter1', ]) }}
(3) mapMutations
mapMutations可以用于帮助提交组件中的mutations,它将组件方法映射到store.commit调用。同样,也可以使用mapMutations传递有效载荷。
import { mapMutations } from 'vuex'export default { methods: { ...mapMutations({ cal: 'calculate' // map`this.cal()` to `this.$store.commit('calculate')` }) }}
(4) mapActions
可以用于帮助在组件中分派操作,并将组件方法映射到store.dispatch调用。
import { mapActions } from 'vuex'export default { methods: { ...mapActions({ cal: 'calculate' // map`this.cal()` to `this.$store.dispatch('calculate')` }) }}
4. 不要忘记编写单元测试
测试在任何项目中都很重要。作为开发人员,无论项目的重要性或规模如何,我们都必须测试开发的内容。尤其是在涉及大型项目中,往往有成千上万的小型功能,因此我们有责任测试每个功能。
这就是单元测试的必要性,它可以使开发人员测试单个代码单元。单元测试不仅可以避免错误,而且每当开发人员进行更改时,修改的结果也可以提升开发团队对其工作的信心。随着项目的进行,开发人员可以从项目的开始就遵循良好的单元测试机制来添加新功能,不必担心会破坏其他功能。
在Vue.js中进行的单元测试与所有其他框架的单元测试方法大同小异,你可以轻松地将Jest,Karma或Mocha与Vue.js结合使用。尽管有测试框架,但是在编写单元测试时,还是有些需要记住的一般性事项:
图源:unsplash
通过从项目开始就遵循这些步骤的方法,随着项目结构的发展,开发人员可以大大减少调试和手动测试所花费的时间。
除了单元测试之外,Vue.js与其他任何框架一样都支持E2E测试和集成测试。因此,你也可以将这些也结合到项目中。通常,路由部分不会使用单元测试进行测试,并且通过端到端测试进行覆盖。Vue仓库是最难测试的部分,对states,actions或getters的单独测试往往被认为是无用的,我推荐的方法是集成测试。