这是我在使用大型代码库进行 Vue 项目时开发的最佳实践。这些技巧将帮助您开发更有效的代码,更易于维护和共享。
今年的自由职业生涯中,我有机会从事一些大型Vue应用程序的工作。我所谈论的项目有超过12个Vuex 存储,大量组件(有时数百个)和许多视图(页面)。实际上,这对我来说是非常有意义的经历,因为我发现了许多有趣的模式来使代码可扩展。我还必须修复一些导致著名的意大利面条代码难题的错误做法。
因此,今天,我将与您分享10个最佳实践,如果您要处理大量的代码库,我建议您遵循这些最佳实践。
我最近写了一篇文章,介绍有关Vue.js中的插槽您需要了解的一些重要事项。它着重说明插槽如何使您的组件更可重用且更易于维护,以及为什么要使用它们。
但是,这与大型Vue.js项目有什么关系?一图胜千言,所以我将为您画一张图片,这是我第一次后悔不使用它们。
有一天,我只需要创建一个弹出窗口。乍一看,没有什么真正复杂的,只是包括标题,描述和一些按钮。所以我要做的就是把所有东西都当作属性。最后,我用了三个属性来定制组件,当人们单击按钮时会发出一个事件。十分简单!
但是,随着项目的不断发展,团队要求我们在其中显示许多其他新内容:表单字段,不同的按钮(取决于显示在哪个页面上),卡片,页脚和列表。我发现,如果我继续使用属性来使这个组件不断扩展,似乎也可以。但是上帝,我错了!该组件很快变得太复杂了,以至于无法理解,因为它包含了无数的子组件,使用了太多的属性并发出了大量事件。我经历了一种可怕的情况,当您在某处进行更改时,它最终以某种方式破坏了另一页上的其他内容。我搞了个科学怪人的怪物,而不是一个可维护的组件!
但是,如果我从一开始就依赖插槽,情况可能会更好。最后,我重构了所有东西以提供这个小组件。易于维护,更快地理解并且可扩展性更高!
<template>
<div class="c-base-popup">
<div v-if="$slots.header" class="c-base-popup__header">
<slot name="header">
</div>
<div v-if="$slots.subheader" class="c-base-popup__subheader">
<slot name="subheader">
</div>
<div class="c-base-popup__body">
<h1>{{ title }}</h1>
<p v-if="description">{{ description }}</p>
</div>
<div v-if="$slots.actions" class="c-base-popup__actions">
<slot name="actions">
</div>
<div v-if="$slots.footer" class="c-base-popup__footer">
<slot name="footer">
</div>
</div>
</template>
<script> export default {
props: {
description: {
type: String,
default: null
},
title: {
type: String,
required: true
}
}
} </script>
我的观点是,根据经验,由知道何时使用插槽的开发人员构建的项目确实对其未来的可维护性有很大的影响。这样就可以减少发出事件的次数,使代码更易于理解,并且可以在内部显示所需的任何组件时提供更大的灵活性。
⚠️作为一个经验法则,请记住,当最终在子组件的父组件中复制子组件的属性时,应该从这一点开始使用插槽。
通常,新的 Vue.js 开发人员开始学习 Vuex,因为他们偶然发现了以下两个问题:
那是他们创建第一个 Vuex 存储,了解模块并开始在应用程序中进行组织的时候。
问题是创建模块时没有单一模式可以遵循。但是,我强烈建议您考虑如何组织它们。据我了解,大多数开发人员都喜欢按功能组织它们。例如:
就我而言,我发现根据它们从API提取的数据模型来组织它们时更容易理解。例如:
您选择哪一个取决于您。唯一要记住的是,从长远来看,组织良好的 Vuex 存储将使团队更具生产力。这也将使新来者更容易在加入您的团队时就将您的想法围绕您的代码库。
我的大多数API调用(如果不是全部)都在我的 Vuex 操作(vuex actions)中进行。您可能想知道:为什么这里调用更好?
仅仅因为它们中的大多数都提取了我需要在存储(vuex store)中提交的数据。此外,它们提供了我真正喜欢的封装性和可重用性。我这样做还有其他一些原因:
译注:Mixpanel 是一家数据跟踪和分析公司,允许开发者跟踪各种用户行为,比如用户浏览的页面数,iPhone 应用分析,Facebook 应用互动情况,以及 Email 分析。类似Firebase一样的埋点分析工具。
当您只需要访问state/getter或在组件内部调用action/mutation时,通常无需创建多个计算属性或方法。使用mapState
,mapGetters
,mapMutations
和mapActions
可以帮助你缩短你的代码,通过分组来化繁为简,从你存储里模块一个地方就能掌握全局。
// NPM
import { mapState, mapGetters, mapActions, mapMutations } from "vuex";
export default {
computed: {
// Accessing root properties
...mapState("my_module", ["property"]),
// Accessing getters
...mapGetters("my_module", ["property"]),
// Accessing non-root properties
...mapState("my_module", {
property: state => state.object.nested.property
})
},
methods: {
// Accessing actions
...mapActions("my_module", ["myAction"]),
// Accessing mutations
...mapMutations("my_module", ["myMutation"])
}
};
Vuex官方文档中提供了您在这些便捷帮助器上所需的所有信息。
我通常喜欢创建一个this.$api
可以在任何地方调用以获取API端点的助手。在项目的根目录下,我有一个api
包含所有类的文件夹(请参阅下面的其中一个)。
api
├── auth.js
├── notifications.js
└── teams.js
每个节点都将其类别的所有端点分组。这是我在 Nuxt 应用程序中使用插件初始化此模式的方式(这与标准 Vue 应用程序中的过程非常相似)。
// PROJECT: API
import Auth from "@/api/auth";
import Teams from "@/api/teams";
import Notifications from "@/api/notifications";
export default (context, inject) => {
if (process.client) {
const token = localStorage.getItem("token");
// Set token when defined
if (token) {
context.$axios.setToken(token, "Bearer");
}
}
// Initialize API repositories
const repositories = {
auth: Auth(context.$axios),
teams: Teams(context.$axios),
notifications: Notifications(context.$axios)
};
inject("api", repositories);
};
的JavaScript
export default $axios => ({
forgotPassword(email) {
return $axios.$post("/auth/password/forgot", { email });
},
login(email, password) {
return $axios.$post("/auth/login", { email, password });
},
logout() {
return $axios.$get("/auth/logout");
},
register(payload) {
return $axios.$post("/auth/register", payload);
}
});
的JavaScript
现在,我可以简单地在我的组件或 Vuex 操作中调用它们,如下所示:
export default {
methods: {
onSubmit() {
try {
this.$api.auth.login(this.email, this.password);
} catch (error) {
console.error(error);
}
}
}
};
的JavaScript
您的项目可能在某些文件中定义了一些全局配置变量:
config
├── development.json
└── production.json
我喜欢通过this.$config
助手快速访问它们,尤其是当我在模板中时。与往常一样,扩展Vue对象非常容易:
// NPM
import Vue from "vue";
// PROJECT: COMMONS
import development from "@/config/development.json";
import production from "@/config/production.json";
if (process.env.NODE_ENV === "production") {
Vue.prototype.$config = Object.freeze(production);
} else {
Vue.prototype.$config = Object.freeze(development);
}
随着项目的发展,您将需要定期浏览组件的提交历史记录。如果您的团队没有遵循相同的约定来书写他们的提交说明,那么将很难理解每个团队成员的行为。
我总是使用并推荐Angular commit消息准则。在我从事的每个项目中,我都会遵循它,在许多情况下,其他团队成员也会很快发现遵循它也更好。
遵循这些准则会导致更具可读性的消息,从而在查看项目历史记录时更易于跟踪提交。简而言之,这是它的工作方式:
git commit -am "<type>(<scope>): <subject>"
# Here are some samples
git commit -am "docs(changelog): update changelog to beta.5"
git commit -am "fix(release): need to depend on latest rxjs and zone.js"
看看他们的README文件以了解更多约定。
我知道...所有软件包都应遵循语义版本控制规则。但实际情况是,其中一些并非如此。
为避免因您的一个依赖项在半夜醒来破坏了整个项目,锁定所有软件包的版本会使您的早晨工作压力减轻。
它的意思很简单:避免使用以^
开头的版本:
{
"name": "my project",
"version": "1.0.0",
"private": true,
"dependencies": {
"axios": "0.19.0",
"imagemin-mozjpeg": "8.0.0",
"imagemin-pngquant": "8.0.0",
"imagemin-svgo": "7.0.0",
"nuxt": "2.8.1",
},
"devDependencies": {
"autoprefixer": "9.6.1",
"babel-eslint": "10.0.2",
"eslint": "6.1.0",
"eslint-friendly-formatter": "4.0.1",
"eslint-loader": "2.2.1",
"eslint-plugin-vue": "5.2.3"
}
}
当您需要在给定页面中显示很多行或需要循环访问大量数据时,您可能已经注意到该页面的呈现速度很快。要解决此问题,可以使用vue-virtual-scoller。
npm install vue-virtual-scroller
它将仅渲染列表中的可见项,并重用组件和dom元素,以使其尽可能高效。它真的很容易使用,顺滑得很!✨
<template>
<RecycleScroller
class="scroller"
:items="list"
:item-size="32"
key-field="id"
v-slot="{ item }"
>
<div class="user">
{{ item.name }}
</div>
</RecycleScroller>
</template>
的HTML
当很多人在同一个项目中工作时,如果没有人关注它们,那么已安装软件包的数量会迅速增加,令人难以置信。为了避免您的应用程序变慢(尤其是在移动网络变慢的情况下),我在Visual Studio Code中使用了导入费用包。这样,我可以从编辑器中直接看到导入的模块库有多大,并且可以查看导入的模块库过大时出了什么问题。
例如,在最近的项目中,导入了整个 lodash 库(压缩后大约24kB)。问题在于,项目里仅仅使用cloneDeep 一个方法。通过在导入费用包中识别此问题后,我们通过以下方式解决了该问题:
npm remove lodash
npm install lodash.clonedeep
然后可以在需要的地方导入clonedeep函数:
import cloneDeep from "lodash.clonedeep";
的 JavaScript
为了进一步优化,您还可以使用Webpack Bundle Analyzer软件包通过交互式可缩放树状图来可视化Webpack输出文件的大小。
处理大型Vue代码库时,您还有其他最佳实践吗?请在下面的评论中告诉我,或者在Twitter @RifkiNada上与我联系。
本文由哈喽比特于3年以前收录,如有侵权请联系我们。
文章来源:https://mp.weixin.qq.com/s/cxWw-LX1CA2_wKLLanETjA
京东创始人刘强东和其妻子章泽天最近成为了互联网舆论关注的焦点。有关他们“移民美国”和在美国购买豪宅的传言在互联网上广泛传播。然而,京东官方通过微博发言人发布的消息澄清了这些传言,称这些言论纯属虚假信息和蓄意捏造。
日前,据博主“@超能数码君老周”爆料,国内三大运营商中国移动、中国电信和中国联通预计将集体采购百万台规模的华为Mate60系列手机。
据报道,荷兰半导体设备公司ASML正看到美国对华遏制政策的负面影响。阿斯麦(ASML)CEO彼得·温宁克在一档电视节目中分享了他对中国大陆问题以及该公司面临的出口管制和保护主义的看法。彼得曾在多个场合表达了他对出口管制以及中荷经济关系的担忧。
今年早些时候,抖音悄然上线了一款名为“青桃”的 App,Slogan 为“看见你的热爱”,根据应用介绍可知,“青桃”是一个属于年轻人的兴趣知识视频平台,由抖音官方出品的中长视频关联版本,整体风格有些类似B站。
日前,威马汽车首席数据官梅松林转发了一份“世界各国地区拥车率排行榜”,同时,他发文表示:中国汽车普及率低于非洲国家尼日利亚,每百户家庭仅17户有车。意大利世界排名第一,每十户中九户有车。
近日,一项新的研究发现,维生素 C 和 E 等抗氧化剂会激活一种机制,刺激癌症肿瘤中新血管的生长,帮助它们生长和扩散。
据媒体援引消息人士报道,苹果公司正在测试使用3D打印技术来生产其智能手表的钢质底盘。消息传出后,3D系统一度大涨超10%,不过截至周三收盘,该股涨幅回落至2%以内。
9月2日,坐拥千万粉丝的网红主播“秀才”账号被封禁,在社交媒体平台上引发热议。平台相关负责人表示,“秀才”账号违反平台相关规定,已封禁。据知情人士透露,秀才近期被举报存在违法行为,这可能是他被封禁的部分原因。据悉,“秀才”年龄39岁,是安徽省亳州市蒙城县人,抖音网红,粉丝数量超1200万。他曾被称为“中老年...
9月3日消息,亚马逊的一些股东,包括持有该公司股票的一家养老基金,日前对亚马逊、其创始人贝索斯和其董事会提起诉讼,指控他们在为 Project Kuiper 卫星星座项目购买发射服务时“违反了信义义务”。
据消息,为推广自家应用,苹果现推出了一个名为“Apps by Apple”的网站,展示了苹果为旗下产品(如 iPhone、iPad、Apple Watch、Mac 和 Apple TV)开发的各种应用程序。
特斯拉本周在美国大幅下调Model S和X售价,引发了该公司一些最坚定支持者的不满。知名特斯拉多头、未来基金(Future Fund)管理合伙人加里·布莱克发帖称,降价是一种“短期麻醉剂”,会让潜在客户等待进一步降价。
据外媒9月2日报道,荷兰半导体设备制造商阿斯麦称,尽管荷兰政府颁布的半导体设备出口管制新规9月正式生效,但该公司已获得在2023年底以前向中国运送受限制芯片制造机器的许可。
近日,根据美国证券交易委员会的文件显示,苹果卫星服务提供商 Globalstar 近期向马斯克旗下的 SpaceX 支付 6400 万美元(约 4.65 亿元人民币)。用于在 2023-2025 年期间,发射卫星,进一步扩展苹果 iPhone 系列的 SOS 卫星服务。
据报道,马斯克旗下社交平台𝕏(推特)日前调整了隐私政策,允许 𝕏 使用用户发布的信息来训练其人工智能(AI)模型。新的隐私政策将于 9 月 29 日生效。新政策规定,𝕏可能会使用所收集到的平台信息和公开可用的信息,来帮助训练 𝕏 的机器学习或人工智能模型。
9月2日,荣耀CEO赵明在采访中谈及华为手机回归时表示,替老同事们高兴,觉得手机行业,由于华为的回归,让竞争充满了更多的可能性和更多的魅力,对行业来说也是件好事。
《自然》30日发表的一篇论文报道了一个名为Swift的人工智能(AI)系统,该系统驾驶无人机的能力可在真实世界中一对一冠军赛里战胜人类对手。
近日,非营利组织纽约真菌学会(NYMS)发出警告,表示亚马逊为代表的电商平台上,充斥着各种AI生成的蘑菇觅食科普书籍,其中存在诸多错误。
社交媒体平台𝕏(原推特)新隐私政策提到:“在您同意的情况下,我们可能出于安全、安保和身份识别目的收集和使用您的生物识别信息。”
2023年德国柏林消费电子展上,各大企业都带来了最新的理念和产品,而高端化、本土化的中国产品正在不断吸引欧洲等国际市场的目光。
罗永浩日前在直播中吐槽苹果即将推出的 iPhone 新品,具体内容为:“以我对我‘子公司’的了解,我认为 iPhone 15 跟 iPhone 14 不会有什么区别的,除了序(列)号变了,这个‘不要脸’的东西,这个‘臭厨子’。