建立和維護(hù)大型 Vue.js 項(xiàng)目的 10 個(gè)最佳實(shí)踐
這是我在使用大型代碼庫(kù)進(jìn)行 Vue 項(xiàng)目時(shí)開發(fā)的最佳實(shí)踐。這些技巧將幫助您開發(fā)更有效的代碼,更易于維護(hù)和共享。
今年的自由職業(yè)生涯中,我有機(jī)會(huì)從事一些大型Vue應(yīng)用程序的工作。我所談?wù)摰捻?xiàng)目有超過12個(gè)Vuex 存儲(chǔ),大量組件(有時(shí)數(shù)百個(gè))和許多視圖(頁(yè)面)。實(shí)際上,這對(duì)我來說是非常有意義的經(jīng)歷,因?yàn)槲野l(fā)現(xiàn)了許多有趣的模式來使代碼可擴(kuò)展。我還必須修復(fù)一些導(dǎo)致著名的意大利面條代碼難題的錯(cuò)誤做法
因此,今天,我將與您分享10個(gè)最佳實(shí)踐,如果您要處理大量的代碼庫(kù),我建議您遵循這些最佳實(shí)踐。
1.使用插槽(slot)使組件更易于理解并且功能更強(qiáng)大
有一天,我只需要?jiǎng)?chuàng)建一個(gè)彈出窗口。乍一看,沒有什么真正復(fù)雜的,只是包括標(biāo)題,描述和一些按鈕。所以我要做的就是把所有東西都當(dāng)作屬性。最后,我用了三個(gè)屬性來定制組件,當(dāng)人們單擊按鈕時(shí)會(huì)發(fā)出一個(gè)事件。十分簡(jiǎn)單!:sweat_smile:
但是,隨著項(xiàng)目的不斷發(fā)展,團(tuán)隊(duì)要求我們?cè)谄渲酗@示許多其他新內(nèi)容:表單字段,不同的按鈕(取決于顯示在哪個(gè)頁(yè)面上),卡片,頁(yè)腳和列表。我發(fā)現(xiàn),如果我繼續(xù)使用屬性來使這個(gè)組件不斷擴(kuò)展,似乎也可以。但是上帝,:weary:我錯(cuò)了!該組件很快變得太復(fù)雜了,以至于無法理解,因?yàn)樗藷o數(shù)的子組件,使用了太多的屬性并發(fā)出了大量事件。:volcano:我經(jīng)歷了一種可怕的情況,當(dāng)您在某處進(jìn)行更改時(shí),它最終以某種方式破壞了另一頁(yè)上的其他內(nèi)容。我搞了個(gè)科學(xué)怪人的怪物,而不是一個(gè)可維護(hù)的組件!
但是,如果我從一開始就依賴插槽,情況可能會(huì)更好。最后,我重構(gòu)了所有東西以提供這個(gè)小組件。易于維護(hù),更快地理解并且可擴(kuò)展性更高!
<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>
我的觀點(diǎn)是,根據(jù)經(jīng)驗(yàn),由知道何時(shí)使用插槽的開發(fā)人員構(gòu)建的項(xiàng)目確實(shí)對(duì)其未來的可維護(hù)性有很大的影響。這樣就可以減少發(fā)出事件的次數(shù),使代碼更易于理解,并且可以在內(nèi)部顯示所需的任何組件時(shí)提供更大的靈活性。
作為一個(gè)經(jīng)驗(yàn)法則,請(qǐng)記住,當(dāng)最終在子組件的父組件中復(fù)制子組件的屬性時(shí),應(yīng)該從這一點(diǎn)開始使用插槽。
2.正確組織您的 Vuex 存儲(chǔ)
通常,新的 Vue.js
開發(fā)人員開始學(xué)習(xí) Vuex
,因?yàn)樗麄兣既话l(fā)現(xiàn)了以下兩個(gè)問題:
- 他們要么需要從樹結(jié)構(gòu)中實(shí)際上相距太遠(yuǎn)的另一個(gè)組件訪問給定組件的數(shù)據(jù),要么
- 他們需要數(shù)據(jù)在組件銷毀后繼續(xù)存在。
那是他們創(chuàng)建第一個(gè) Vuex
存儲(chǔ),了解模塊并開始在應(yīng)用程序中進(jìn)行組織的時(shí)候。
問題是創(chuàng)建模塊時(shí)沒有單一模式可以遵循。但是我強(qiáng)烈建議您考慮如何組織它們。據(jù)我了解,大多數(shù)開發(fā)人員都喜歡按功能組織它們。例如:
- 驗(yàn)證碼
- 博客
- 收件箱
- 設(shè)定
就我而言,我發(fā)現(xiàn)根據(jù)它們從API提取的數(shù)據(jù)模型來組織它們時(shí)更容易理解。例如:
- 用戶數(shù)
- 隊(duì)伍
- 留言內(nèi)容
- 小部件
- 文章
您選擇哪一個(gè)取決于您。唯一要記住的是,從長(zhǎng)遠(yuǎn)來看,組織良好的 Vuex
存儲(chǔ)將使團(tuán)隊(duì)更具生產(chǎn)力。這也將使新來者更容易在加入您的團(tuán)隊(duì)時(shí)就將您的想法圍繞您的代碼庫(kù)。
3.使用操作(Vuex Actions)進(jìn)行 API 調(diào)用和提交數(shù)據(jù)
我的大多數(shù)API調(diào)用(如果不是全部)都在我的 Vuex
操作(vuex actions
)中進(jìn)行。您可能想知道:為什么這里調(diào)用更好?
僅僅因?yàn)樗鼈冎械拇蠖鄶?shù)都提取了我需要在存儲(chǔ)(vuex store
)中提交的數(shù)據(jù)。此外,它們提供了我真正喜歡的封裝性和可重用性。我這樣做還有其他一些原因:
- 如果我需要在兩個(gè)不同的地方(例如博客和首頁(yè))獲取文章的首頁(yè),則可以使用正確的參數(shù)調(diào)用適當(dāng)?shù)恼{(diào)度程序。數(shù)據(jù)將被提取,提交和返回,除了調(diào)度程序調(diào)用外,沒有重復(fù)的代碼。
- 如果我需要?jiǎng)?chuàng)建一些邏輯來避免在提取第一頁(yè)時(shí)提取它,則可以在一個(gè)地方進(jìn)行。除了減少服務(wù)器上的負(fù)載之外,我還有信心它可以在任何地方使用。
- 我可以在這些操作(vuex actions)中跟蹤我的大多數(shù) Mixpanel 事件,從而使分析代碼庫(kù)真正易于維護(hù)。我確實(shí)有一些應(yīng)用程序,其中所有 Mixpanel 調(diào)用都是在操作中單獨(dú)進(jìn)行的。當(dāng)我不必了解跟蹤什么不跟蹤什么以及何時(shí)發(fā)送時(shí),:joy:這種方式工作會(huì)給我?guī)碛卸啻蟮目鞓贰?/li>
譯注:Mixpanel
是一家數(shù)據(jù)跟蹤和分析公司,允許開發(fā)者跟蹤各種用戶行為,比如用戶瀏覽的頁(yè)面數(shù),iPhone
應(yīng)用分析,Facebook
應(yīng)用互動(dòng)情況,以及 Email 分析。類似Firebase
一樣的埋點(diǎn)分析工具。
4.使用 mapState,mapGetters,mapMutations 和 mapAction 簡(jiǎn)化代碼庫(kù)
當(dāng)您只需要訪問state/getter
或在組件內(nèi)部調(diào)用action/mutation
時(shí),通常無需創(chuàng)建多個(gè)計(jì)算屬性或方法。使用 mapState
, mapGetters
, mapMutations
和 mapActions
可以幫助你縮短你的代碼,通過分組來化繁為簡(jiǎn),從你存儲(chǔ)里模塊一個(gè)地方就能掌握全局。
// 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
官方文檔中提供了您在這些便捷幫助器上所需的所有信息。
5.使用 API 工廠
我通常喜歡創(chuàng)建一個(gè) this.$api
可以在任何地方調(diào)用以獲取API端點(diǎn)的助手。在項(xiàng)目的根目錄下,我有一個(gè) api 包含所有類的文件夾(請(qǐng)參閱下面的其中一個(gè))。
api ├── auth.js ├── notifications.js └── teams.js
每個(gè)節(jié)點(diǎn)都將其類別的所有端點(diǎn)分組。這是我在 Nuxt
應(yīng)用程序中使用插件初始化此模式的方式(這與標(biāo)準(zhǔn) Vue 應(yīng)用程序中的過程非常相似)。
// 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); };
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); } });
現(xiàn)在,我可以簡(jiǎn)單地在我的組件或 Vuex 操作中調(diào)用它們,如下所示:
export default { methods: { onSubmit() { try { this.$api.auth.login(this.email, this.password); } catch (error) { console.error(error); } } } };
6.使用 $config 訪問您的環(huán)境變量(在模板中特別有用)
您的項(xiàng)目可能在某些文件中定義了一些全局配置變量:
config ├── development.json └── production.json
我喜歡通過 this.$config
助手快速訪問它們,尤其是當(dāng)我在模板中時(shí)。與往常一樣,擴(kuò)展Vue對(duì)象非常容易:
// 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); }
7.遵循一個(gè)約定來寫提交注釋
隨著項(xiàng)目的發(fā)展,您將需要定期瀏覽組件的提交歷史記錄。如果您的團(tuán)隊(duì)沒有遵循相同的約定來書寫他們的提交說明,那么將很難理解每個(gè)團(tuán)隊(duì)成員的行為。
我總是使用并推薦Angular commit
消息準(zhǔn)則。在我從事的每個(gè)項(xiàng)目中,我都會(huì)遵循它,在許多情況下,其他團(tuán)隊(duì)成員也會(huì)很快發(fā)現(xiàn)遵循它也更好。
遵循這些準(zhǔn)則會(huì)導(dǎo)致更具可讀性的消息,從而在查看項(xiàng)目歷史記錄時(shí)更易于跟蹤提交。簡(jiǎn)而言之,這是它的工作方式:
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
文件以了解更多約定。
8.始終在生產(chǎn)項(xiàng)目時(shí)凍結(jié)軟件包的版本
我知道...所有軟件包都應(yīng)遵循語(yǔ)義版本控制規(guī)則。但實(shí)際情況是,其中一些并非如此。:sweat_smile:
為避免因您的一個(gè)依賴項(xiàng)在半夜醒來破壞了整個(gè)項(xiàng)目,鎖定所有軟件包的版本會(huì)使您的早晨工作壓力減輕。:innocent:
它的意思很簡(jiǎn)單:避免使用以 ^ 開頭的版本:
{ "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" } }
9.顯示大量數(shù)據(jù)時(shí)使用 Vue 虛擬滾動(dòng)條
當(dāng)您需要在給定頁(yè)面中顯示很多行或需要循環(huán)訪問大量數(shù)據(jù)時(shí),您可能已經(jīng)注意到該頁(yè)面的呈現(xiàn)速度很快。要解決此問題,可以使用vue-virtual-scoller
。
npm install vue-virtual-scroller
它將僅渲染列表中的可見項(xiàng),并重用組件和dom元素,以使其盡可能高效。它真的很容易使用,順滑得很
<template> <RecycleScroller class="scroller" :items="list" :item-size="32" key-field="id" v-slot="{ item }" > <div class="user"> {{ item.name }} </div> </RecycleScroller> </template>
10.跟蹤第三方程序包的大小
當(dāng)很多人在同一個(gè)項(xiàng)目中工作時(shí),如果沒有人關(guān)注它們,那么已安裝軟件包的數(shù)量會(huì)迅速增加,令人難以置信。為了避免您的應(yīng)用程序變慢(尤其是在移動(dòng)網(wǎng)絡(luò)變慢的情況下),我在Visual Studio Code
中使用了導(dǎo)入費(fèi)用包。這樣,我可以從編輯器中直接看到導(dǎo)入的模塊庫(kù)有多大,并且可以查看導(dǎo)入的模塊庫(kù)過大時(shí)出了什么問題。
例如,在最近的項(xiàng)目中,導(dǎo)入了整個(gè) lodash 庫(kù)(壓縮后大約24kB)。問題在于,項(xiàng)目里僅僅使用cloneDeep
一個(gè)方法。通過在 導(dǎo)入費(fèi)用包 中識(shí)別此問題后,我們通過以下方式解決了該問題:
npm remove lodash npm install lodash.clonedeep
然后可以在需要的地方導(dǎo)入clonedeep函數(shù):
import cloneDeep from "lodash.clonedeep"; 的JavaScript
為了進(jìn)一步優(yōu)化,您還可以使用
Webpack Bundle Analyzer
軟件包通過交互式可縮放樹狀圖來可視化Webpack
輸出文件的大小。
到此這篇關(guān)于建立和維護(hù)大型 Vue.js 項(xiàng)目的 10 個(gè)最佳實(shí)踐的文章就介紹到這了,更多相關(guān)建立和維護(hù) Vue.js 項(xiàng)目實(shí)踐內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue elementUI el-form 數(shù)據(jù)無法賦值且不報(bào)錯(cuò)的問題及解決方法
vue項(xiàng)目中使用elementUI的el-form組件,里面有部分后端數(shù)據(jù)遍歷的字段和部分確定的字段,遇到個(gè)問題遍歷的字段可以修改值但是確定的幾個(gè)字段無法修改值,下面小編給大家分享vue elementUI el-form 數(shù)據(jù)無法賦值且不報(bào)錯(cuò)的問題及解決方法,感興趣的朋友一起看看吧2023-12-12vue3項(xiàng)目使用pinia狀態(tài)管理器的使用
Pinia是一個(gè)專為Vue3設(shè)計(jì)的現(xiàn)代化狀態(tài)管理庫(kù),本文主要介紹了vue3項(xiàng)目使用pinia狀態(tài)管理器的使用,具有一定的參考價(jià)值,感興趣的可以了解一下2024-05-05vue實(shí)現(xiàn)todolist基本功能以及數(shù)據(jù)存儲(chǔ)功能實(shí)例詳解
本文通過實(shí)例代碼給大家介紹了vue實(shí)現(xiàn)todolist基本功能以及數(shù)據(jù)存儲(chǔ)功能,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-04-04Vue+NodeJS實(shí)現(xiàn)大文件上傳的示例代碼
常見的文件上傳方式可能就是new一個(gè)FormData,把文件append進(jìn)去以后post給后端就可以了。但如果采用這種方式來上傳大文件就很容易產(chǎn)生上傳超時(shí)的問題。所以本文將利用Vue+NodeJS實(shí)現(xiàn)大文件上傳,需要的可以參考一下2022-05-05前端Vue3引入高德地圖并展示行駛軌跡動(dòng)畫的步驟
最近在Vue項(xiàng)目中引入高德地圖,實(shí)現(xiàn)地圖展示與交互的方法和技術(shù),這里跟大家分享下,這篇文章主要給大家介紹了關(guān)于前端Vue3引入高德地圖并展示行駛軌跡動(dòng)畫的相關(guān)資料,需要的朋友可以參考下2024-09-09詳解如何實(shí)現(xiàn)一個(gè)簡(jiǎn)單的 vuex
本篇文章主要介紹了如何實(shí)現(xiàn)一個(gè)簡(jiǎn)單的 vuex,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-02-02select的change方法傳遞多個(gè)參數(shù)的方法詳解
element-ui中的select,checkbox等組件的change方法的回調(diào)函數(shù)只有當(dāng)前選擇的val,如果想再傳入自定義參數(shù)怎么辦,本文給大家分享select的change方法如何傳遞多個(gè)參數(shù),感興趣的朋友一起看看吧2024-02-02Vue監(jiān)聽數(shù)據(jù)渲染DOM完以后執(zhí)行某個(gè)函數(shù)詳解
今天小編就為大家分享一篇Vue監(jiān)聽數(shù)據(jù)渲染DOM完以后執(zhí)行某個(gè)函數(shù)詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-09-09談?wù)剬?duì)vue響應(yīng)式數(shù)據(jù)更新的誤解
本篇文章主要介紹了談?wù)剬?duì)vue響應(yīng)式數(shù)據(jù)更新的誤解,深入了解了vue響應(yīng)式數(shù)據(jù),有興趣的可以了解一下2017-08-08