您好,登錄后才能下訂單哦!
這些是我構建大型Vue項目得出的最佳實踐,這些技巧將幫助你更高效的編碼,并且使其更容易維護和協作。
在我今年的自由職業生涯中我有幸開發了一些大型Vue程序。我所說的這些項目使用了大量Vuex stores 😰 ,很多Vue組件(有數百個)和很多視圖(pages)😄。對我而言這是非常有意義的經歷,我發現了很多使擴展的方法。同時我還需要修復一些亂七八糟的錯誤用法。🍝
所以我將分享我的10個最佳實踐,如果你有大型項目需要開發推薦你使用他們。
1. 使用Slots可以使你的組件更強大和便于理解。
最近我寫了一篇文章some important things you need to know regarding slots in Vue.js。 主要講了為什么使用Slots可以提高組件復用且易于維護。
但是這和大型Vue項目有啥關系呢。我將描繪一個使用他們解決你痛點的藍圖。
假如我要開發一個popup。起初看起來沒有什么難點,僅僅是包括標題,描述和一些按鈕。 所以把所有東西都當作props不就完了嗎。 我用了三個自定義props,并且click按鈕的時候觸發一個事件。 就是這么簡單! 😅
隨著項目的不斷發展,業務需要顯示許多其他新內容:表單字段,不同的按鈕(取決于顯示在哪個頁面上)、卡片、頁腳和列表。通過添加更多的props可以解決這個問題。😩但是隨著業務發展,組件變的太復雜了。因為他包含了很多子組件,需要觸發很多個事件。🌋我遇到了坑爹的問題,修改了一個功能后影響了其他page上的功能。我創造了一個怪物而不是一個可維護的組件!
但是,一開始使用slots可能會更好。最終我使小組件來重構這個組件。使他更容易維護、好理解、好擴展。
<template> <div class="c-base-popup"> <div v-if="$slot.header" class="c-base-popup__header"> <slot name="header"> </div> <div v-if="$slot.subheader" class="c-base-popup__subheader"> <slot name="subheader"> </div> <div class="c-base-popup__body"> <h2>{{ title }}</h2> <p v-if="description">{{ description }}</p> </div> <div v-if="$slot.actions" class="c-base-popup__actions"> <slot name="actions"> </div> <div v-if="$slot.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>
根據經驗在我看來,由熟練使用slots的開發人員構建項目對將來項目的可維護性有更重要的意義。
⚠️ 經驗規則,當子組件中使用了父組件的props時,應該使用slots。
2.好好組織的你Vuex store
通常,一個新的Vue開發人員學習Vuex是因為兩個問題:
這樣他創建第一個Vuex store,學習moudles的用法并且組織程序時。💡
問題是創建modules時沒有單一模式可循。我強烈建議一定要想清楚如何組織他們。據我所知,很多人更喜歡按照功能來組織他們(我也是:譯者注)。例如:
就我來說,用從API獲得的數據模型組織更容易理解。例子:
用那個取決于自己,但是從長遠來看組織良好的Vuex store更具生產力。這樣也容易是新人融入并且繼承你的初衷。
3.用Actions調用api和提交數據。
我的大部分(不是全部)API調用都在Vuex的actions中,你一定想知道為什么這樣做。🤨
簡單的說是因為拉取數據時需要在store中commit。還有就是他提供了我喜歡的封裝和復用。其他原因就是:
4.使用mapState、mapGetters、mapMutations和mapAction精簡代碼。
當你在組件中訪問state/getters或者調用actions/mutations時通常需要創建多個計算屬性。使用mapState,mapGetters,mapMutations和mapActions可以將來自store modules中的數據集中在一個地方,這樣可以精簡代碼并且更好理解。
// 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 Factories
我通常會創建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); };
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); } });
這樣我可以方便的在組件或Vuex操作中調用他們,如下:
export default { methods: { onSubmit() { try { this.$api.auth.login(this.email, this.password); } catch (error) { console.error(error); } } } };
6. 使用$config訪問環境變量(模板中特別有用)。
項目中定義了一些全局配置變量:
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); }
7.遵守一個commit命名規則。
在項目發展的過程中,經常需要關注組件的變更歷史。如果團隊中有人沒有遵守commit慣例,那么將很難理解他們所做的事情。
我總是使用并推薦Angular commit message guidelines。我所有的項目中都會使用他,通常團隊中的其他人也會發現他的好處。
遵守這些規則使commit更加可讀,在查看項目歷史時使得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 file更新更多。
8.始終在生產環境中凍結Package的版本。
我知道...所有軟件包都應遵循 the semantic versioning rules.。但實際情況并非如此。😅
為了避免一個依賴影響了整個項目在半夜被拖起來,凍結所有程序包的版本可以使你一覺睡到天明并且工作愉快。 😇
這很簡單:避免以^開頭的版本:
{ "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. 顯示一個大的數據時應該使用Vue虛擬滾動條。
在頁面中顯示多行或需要循環大量數據時,你已經注意到該頁面渲染速度很快變慢。 要解決此問題,您可以使用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>
10.追蹤第三方程序包的大小
多人合作一個項目時,如果沒人關注安裝的依賴包數量很快變的難以置信。為了避免程序變慢(尤其是在移動網絡環境),我這VSC中使用import cost package這樣就可以編輯器中看到導入的包有多大,并且找出大的原因。
例如在最近的項目中,導入了整個lodash庫(壓縮后24kB)。 有啥子問題? 僅僅使用cloneDeep方法。 通過import cost package找到了問題,我們通過以下方式解決了該問題:
npm remove lodash npm install lodash.clonedeep
在使用的地方導入:
import cloneDeep from "lodash.clonedeep";
為了進一步優化,我們還可以使用Webpack Bundle Analyzer包通過樹狀圖來可視化Webpack輸出文件的大小。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持億速云。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。