下面是我在开发大型 Vue 项目时的最佳实践。这些技巧将帮助你开发更高效、更易于维护和共享的代码。
今年做自由职业的时候,我有机会开发了一些大型 Vue 应用程序。我所说的这些项目,Vuex store 超过十个,包含大量的组件(有时候几百个)和视图页面。对我来说这是个很有益的经验,因为我发现了很多有意思的模式,可以让代码拥有更好的伸缩性。我还必须修正一些导致著名的意大利面条式代码困境的错误实践。
因此,今天我将与你分享10个最佳实践,如果你正在处理大型代码库,我建议你参考这些方法。
1. 使用 slot, 让组件更强大,也更容易理解
最近我写了篇关于 Vue.js slot 的文章,它强调了 slot 如何使组件更易于重用和维护,以及为什么应该使用它们。
但是这与 Vue.js 大型项目有什么关系呢?一张图片通常胜过千言万语,所以我要给你描绘一幅关于我第一次后悔没有使用它们的画面。
有一天,我要创建一个 popup。乍一看并没有什么复杂的东西,只是包含了一个标题,一个描述和一些按钮。所以我所做的就是把一切配置一股脑当做 props 传进去。最终我定义了三个 prop,用于自定义组件,当用户单击按钮时将发送一个事件。So easy !
但是,随着项目的发展,团队要求我们在其中展示更多其他的新内容:表单字段、不同的按钮(取决于它显示在哪个页面上)、卡片、页脚,以及列表。我以为,如果继续使用 prop 来迭代这个组件也没啥问题。但是我滴个神哪,我是大错特错!组件很快变得非常复杂,难以理解,因为它包含了无数的子组件,用了太多的 prop,并发送了一堆的事件。我开始体验到了可怕的情况,当你做出一点改动,其他页面的某个地方就会崩溃!我仿佛造了一个 Frankenstein 怪人,而不是一个可维护的组件!🤖
然而,如果我从一开始就依赖 slot,情况可能会好多了。最后我重构了所有东西,得到了这个小组件:更容易维护,理解起来更快,更好扩展!
<template> <div> <div v-if="$slot.header"> <slot> </div> <div v-if="$slot.subheader"> <slot> </div> <div> <h1>{{ title }}</h1> <p v-if="description">{{ description }}</p> </div> <div v-if="$slot.actions"> <slot> </div> <div v-if="$slot.footer"> <slot> </div> </div> </template> <script> export default { props: { description: { type: String, default: null }, title: { type: String, required: true } } } </script>
我的观点是,从经验来看,那些知道何时使用 slot 的开发人员所构建的项目确实会对其未来的可维护性产生很大的影响。由于发送的事件更少,代码更容易理解,而且提供了更大的灵活性,可以在其中显示任何组件。
敲黑板:根据经验,当你开始在父组件中复制子组件的 prop 时,你就应该考虑使用 slot 了。
2. 合理组织 Vuex Store
通常,Vue.js 新手开始了解Vuex,因为他们刚好碰到了这两个问题:
组件树结构中相隔太远的组件之间访问数据
组件销毁后需要持久化数据
这个时候他们就会创建第一个 Vuex store,学习模块并开始在应用程序中组织它们。
问题在于,创建模块时没有单一的模式可以遵循。然而,我强烈建议你仔细考虑如何组织它们。据我所见,大多数开发人员更喜欢根据功能来组织它们。例如:
Auth.
Blog.
Inbox.
Settings.
就我来说,我发现根据从 API 获取的数据模型来组织它们更容易理解。例如:
Users
Teams
Messages
Widgets
Articles
如何选择取决于你自己。唯一需要记住的是,从长远来看,一个组织良好的 Vuex store 会造就一个更高效的团队。它还将使新人在加入团队时更容易将他们的想法围绕在你的代码基础上。
3. 使用 action 发起 API 调用和提交数据
我的大部分 API 调用(如果不是全部)是在Vuex action 里面完成的。你可能会问:为什么要这么做? 🤨
♀️ 简单来说,它们中的大多数获取的数据需要提交到 store里去。另外,它们还提供了一层封装和可重用性,我很喜欢用。还有一些原因如下:
如果我需要在两个地方(假设是博客页面和首页)获取文章的第一页,我只需要用正确的参数调用合适的 dispatcher 就行了。除了 dispatcher 调用,无需重复代码就可以完成数据的获取,commit 到 store 和返回。
如果我需要写一些避免重复获取第一页的逻辑,我就可以在一个地方完成。这样做除了会减轻服务器负载,还会增强我对代码的信心。