<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          建立和維護(hù)大型 Vue.js 項目的 10 個最佳實(shí)踐

          共 11053字,需瀏覽 23分鐘

           ·

          2021-09-30 15:53

          點(diǎn)擊上方 前端瓶子君,關(guān)注公眾號

          回復(fù)算法,加入前端編程面試算法每日一題群

          這是我在使用大型代碼庫進(jìn)行 Vue 項目時開發(fā)的最佳實(shí)踐。這些技巧將幫助您開發(fā)更有效的代碼,更易于維護(hù)和共享。

          今年的自由職業(yè)生涯中,我有機(jī)會從事一些大型Vue應(yīng)用程序的工作。我所談?wù)摰捻椖坑谐^12個Vuex 存儲,大量組件(有時數(shù)百個)和許多視圖(頁面)。實(shí)際上,這對我來說是非常有意義的經(jīng)歷,因為我發(fā)現(xiàn)了許多有趣的模式來使代碼可擴(kuò)展。我還必須修復(fù)一些導(dǎo)致著名的意大利面條代碼難題的錯誤做法。??

          因此,今天,我將與您分享10個最佳實(shí)踐,如果您要處理大量的代碼庫,我建議您遵循這些最佳實(shí)踐。

          1.使用插槽(slot)使組件更易于理解并且功能更強(qiáng)大

          我最近寫了一篇文章,介紹有關(guān)Vue.js中的插槽您需要了解的一些重要事項。它著重說明插槽如何使您的組件更可重用且更易于維護(hù),以及為什么要使用它們。

          ??但是,這與大型Vue.js項目有什么關(guān)系?一圖勝千言,所以我將為您畫一張圖片,這是我第一次后悔不使用它們。

          有一天,我只需要創(chuàng)建一個彈出窗口。乍一看,沒有什么真正復(fù)雜的,只是包括標(biāo)題,描述和一些按鈕。所以我要做的就是把所有東西都當(dāng)作屬性。最后,我用了三個屬性來定制組件,當(dāng)人們單擊按鈕時會發(fā)出一個事件。十分簡單!??

          但是,隨著項目的不斷發(fā)展,團(tuán)隊要求我們在其中顯示許多其他新內(nèi)容:表單字段,不同的按鈕(取決于顯示在哪個頁面上),卡片,頁腳和列表。我發(fā)現(xiàn),如果我繼續(xù)使用屬性來使這個組件不斷擴(kuò)展,似乎也可以。但是上帝,??我錯了!該組件很快變得太復(fù)雜了,以至于無法理解,因為它包含了無數(shù)的子組件,使用了太多的屬性并發(fā)出了大量事件。??我經(jīng)歷了一種可怕的情況,當(dāng)您在某處進(jìn)行更改時,它最終以某種方式破壞了另一頁上的其他內(nèi)容。我搞了個科學(xué)怪人的怪物,而不是一個可維護(hù)的組件!??

          但是,如果我從一開始就依賴插槽,情況可能會更好。最后,我重構(gòu)了所有東西以提供這個小組件。易于維護(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>
          <scriptexport default {
            props: {
              description: {
                typeString,
                defaultnull
              },
              title: {
                typeString,
                requiredtrue
              }
            }
          } </script>
           

          我的觀點(diǎn)是,根據(jù)經(jīng)驗,由知道何時使用插槽的開發(fā)人員構(gòu)建的項目確實(shí)對其未來的可維護(hù)性有很大的影響。這樣就可以減少發(fā)出事件的次數(shù),使代碼更易于理解,并且可以在內(nèi)部顯示所需的任何組件時提供更大的靈活性。

          ??作為一個經(jīng)驗法則,請記住,當(dāng)最終在子組件的父組件中復(fù)制子組件的屬性時,應(yīng)該從這一點(diǎn)開始使用插槽。

          2.正確組織您的 Vuex 存儲

          通常,新的 Vue.js 開發(fā)人員開始學(xué)習(xí) Vuex,因為他們偶然發(fā)現(xiàn)了以下兩個問題:

          • 他們要么需要從樹結(jié)構(gòu)中實(shí)際上相距太遠(yuǎn)的另一個組件訪問給定組件的數(shù)據(jù),要么
          • 他們需要數(shù)據(jù)在組件銷毀后繼續(xù)存在。

          那是他們創(chuàng)建第一個 Vuex 存儲,了解模塊并開始在應(yīng)用程序中進(jìn)行組織的時候。??

          問題是創(chuàng)建模塊時沒有單一模式可以遵循。但是,????我強(qiáng)烈建議您考慮如何組織它們。據(jù)我了解,大多數(shù)開發(fā)人員都喜歡按功能組織它們。例如:

          • 驗證碼
          • 博客
          • 收件箱
          • 設(shè)定

          就我而言,我發(fā)現(xiàn)根據(jù)它們從API提取的數(shù)據(jù)模型來組織它們時更容易理解。例如:

          • 用戶數(shù)
          • 隊伍
          • 留言內(nèi)容
          • 小部件
          • 文章

          您選擇哪一個取決于您。唯一要記住的是,從長遠(yuǎn)來看,組織良好的 Vuex 存儲將使團(tuán)隊更具生產(chǎn)力。這也將使新來者更容易在加入您的團(tuán)隊時就將您的想法圍繞您的代碼庫。

          3.使用操作(Vuex Actions)進(jìn)行 API 調(diào)用和提交數(shù)據(jù)

          我的大多數(shù)API調(diào)用(如果不是全部)都在我的 Vuex 操作(vuex actions)中進(jìn)行。您可能想知道:為什么這里調(diào)用更好???

          僅僅因為它們中的大多數(shù)都提取了我需要在存儲(vuex store)中提交的數(shù)據(jù)。此外,它們提供了我真正喜歡的封裝性和可重用性。我這樣做還有其他一些原因:

          • 如果我需要在兩個不同的地方(例如博客和首頁)獲取文章的首頁,則可以使用正確的參數(shù)調(diào)用適當(dāng)?shù)恼{(diào)度程序。數(shù)據(jù)將被提取,提交和返回,除了調(diào)度程序調(diào)用外,沒有重復(fù)的代碼。
          • 如果我需要創(chuàng)建一些邏輯來避免在提取第一頁時提取它,則可以在一個地方進(jìn)行。除了減少服務(wù)器上的負(fù)載之外,我還有信心它可以在任何地方使用。
          • 我可以在這些操作(vuex actions)中跟蹤我的大多數(shù) Mixpanel 事件,從而使分析代碼庫真正易于維護(hù)。我確實(shí)有一些應(yīng)用程序,其中所有 Mixpanel 調(diào)用都是在操作中單獨(dú)進(jìn)行的。當(dāng)我不必了解跟蹤什么不跟蹤什么以及何時發(fā)送時,??這種方式工作會給我?guī)碛卸啻蟮目鞓贰?/section>

          譯注:Mixpanel 是一家數(shù)據(jù)跟蹤和分析公司,允許開發(fā)者跟蹤各種用戶行為,比如用戶瀏覽的頁面數(shù),iPhone 應(yīng)用分析,F(xiàn)acebook 應(yīng)用互動情況,以及 Email 分析。類似Firebase一樣的埋點(diǎn)分析工具。

          4.使用 mapState,mapGetters,mapMutations 和 mapAction 簡化代碼庫

          當(dāng)您只需要訪問state/getter或在組件內(nèi)部調(diào)用action/mutation時,通常無需創(chuàng)建多個計算屬性或方法。使用mapStatemapGetters,mapMutationsmapActions可以幫助你縮短你的代碼,通過分組來化繁為簡,從你存儲里模塊一個地方就能掌握全局。

          // 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", {
                propertystate => state.object.nested.property
              })
            },
            methods: {
              // Accessing actions
              ...mapActions("my_module", ["myAction"]),
              // Accessing mutations
              ...mapMutations("my_module", ["myMutation"])
            }
          }; 

          Vuex官方文檔中提供了您在這些便捷幫助器上所需的所有信息。??

          5.使用 API 工廠

          我通常喜歡創(chuàng)建一個this.$api可以在任何地方調(diào)用以獲取API端點(diǎn)的助手。在項目的根目錄下,我有一個api包含所有類的文件夾(請參閱下面的其中一個)。

          api
          ├── auth.js
          ├── notifications.js
          └── teams.js 

          每個節(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);
          }; 

          的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

          現(xiàn)在,我可以簡單地在我的組件或 Vuex 操作中調(diào)用它們,如下所示:

          export default {
            methods: {
              onSubmit() {
                try {
                  this.$api.auth.login(this.email, this.password);
                } catch (error) {
                  console.error(error);
                }
              }
            }
          }; 

          的JavaScript

          6.使用 $config 訪問您的環(huán)境變量(在模板中特別有用)

          您的項目可能在某些文件中定義了一些全局配置變量:

          config
          ├── development.json
          └── production.json 

          我喜歡通過this.$config助手快速訪問它們,尤其是當(dāng)我在模板中時。與往常一樣,擴(kuò)展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.遵循一個約定來寫提交注釋

          隨著項目的發(fā)展,您將需要定期瀏覽組件的提交歷史記錄。如果您的團(tuán)隊沒有遵循相同的約定來書寫他們的提交說明,那么將很難理解每個團(tuán)隊成員的行為。

          我總是使用并推薦Angular commit消息準(zhǔn)則。在我從事的每個項目中,我都會遵循它,在許多情況下,其他團(tuán)隊成員也會很快發(fā)現(xiàn)遵循它也更好。

          遵循這些準(zhǔn)則會導(dǎo)致更具可讀性的消息,從而在查看項目歷史記錄時更易于跟蹤提交。簡而言之,這是它的工作方式:

          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)項目時凍結(jié)軟件包的版本

          我知道...所有軟件包都應(yīng)遵循語義版本控制規(guī)則。但實(shí)際情況是,其中一些并非如此。??

          為避免因您的一個依賴項在半夜醒來破壞了整個項目,鎖定所有軟件包的版本會使您的早晨工作壓力減輕。??

          它的意思很簡單:避免使用以^開頭的版本:

          {
            "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ù)時使用 Vue 虛擬滾動條

          當(dāng)您需要在給定頁面中顯示很多行或需要循環(huán)訪問大量數(shù)據(jù)時,您可能已經(jīng)注意到該頁面的呈現(xiàn)速度很快。要解決此問題,可以使用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

          10.跟蹤第三方程序包的大小

          當(dāng)很多人在同一個項目中工作時,如果沒有人關(guān)注它們,那么已安裝軟件包的數(shù)量會迅速增加,令人難以置信。為了避免您的應(yīng)用程序變慢(尤其是在移動網(wǎng)絡(luò)變慢的情況下),我在Visual Studio Code中使用了導(dǎo)入費(fèi)用包。這樣,我可以從編輯器中直接看到導(dǎo)入的模塊庫有多大,并且可以查看導(dǎo)入的模塊庫過大時出了什么問題。

          例如,在最近的項目中,導(dǎo)入了整個 lodash 庫(壓縮后大約24kB)。問題在于,項目里僅僅使用cloneDeep 一個方法。通過在導(dǎo)入費(fèi)用包中識別此問題后,我們通過以下方式解決了該問題:

          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輸出文件的大小。


          處理大型Vue代碼庫時,您還有其他最佳實(shí)踐嗎?請在下面的評論中告訴我,或者在Twitter @RifkiNada上與我聯(lián)系。??

          關(guān)于作者

          娜達(dá)·里基(Nada Rifki)

          Nada 是一位 JavaScript 開發(fā)人員,他喜歡使用 UI 組件來創(chuàng)建具有出色 UX 的界面。她專門研究 Vue.js,喜歡分享任何可以幫助她的前端 Web 開發(fā)人員的東西。Nada還涉足數(shù)字營銷,舞蹈和中文領(lǐng)域。

          本文:Yujiaao

          來自:https://segmentfault.com/a/1190000040712187

          譯自:https://www.telerik.com/blogs/all-you-need-to-know-about-slots-in-vuejs

          最后

          歡迎關(guān)注【前端瓶子君】??ヽ(°▽°)ノ?
          回復(fù)「算法」,加入前端編程源碼算法群,每日一道面試題(工作日),第二天瓶子君都會很認(rèn)真的解答喲!
          回復(fù)「交流」,吹吹水、聊聊技術(shù)、吐吐槽!
          回復(fù)「閱讀」,每日刷刷高質(zhì)量好文!
          如果這篇文章對你有幫助,在看」是最大的支持
           》》面試官也在看的算法資料《《
          “在看和轉(zhuǎn)發(fā)”就是最大的支持
          瀏覽 57
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  久青草福利视频 | 成人性别视频影音先锋电影 | 123区麻豆成人片 | 日本一三高清 | 日本成人网址 |