Vue組件開發(fā)小結(jié)

組件化是長期開發(fā)過程中一個提煉精華的過程雌团,目的主要是以下幾點:

  1. 提高復(fù)用性
  2. 解耦
  3. 提升未來的開發(fā)效率

那么如何達(dá)到這樣的效果呢臼闻,我們可以分幾步來循序漸進(jìn)地完成脂信。

下文主要是思路嫁蛇,想直接獲取代碼可轉(zhuǎn)戰(zhàn)ElementUI的Github去看源碼

一 組件的定義

組件從大類上可以分為兩種:

  • 基礎(chǔ)組件:例如ElementUI
  • 業(yè)務(wù)組件:通過基礎(chǔ)組件或者業(yè)務(wù)組件組合而成酒朵,與業(yè)務(wù)強(qiáng)相關(guān)甚至強(qiáng)綁定

二 組件的顆粒度

基礎(chǔ)組件的顆粒度爭議并不大,就是Button译暂,Table等等
業(yè)務(wù)組件的顆粒度最大可以為一個feature抠忘,一個feature就是一個可以獨立上線特性,例如文章的評論點贊功能外永。我們可以想象有一個開關(guān)崎脉,打開就有這個feature,關(guān)閉就沒有伯顶,且不會造成聯(lián)動的影響囚灼。

三 組件的接口

  1. Vue的組件基本都是通過屬性來進(jìn)行配置,進(jìn)而控制組件的功能變化祭衩。因此開發(fā)組件之前我們就得明確定義變量是什么灶体,明確組件需要開放的接口
  2. 我們需要理解每一個組件的核心功能是什么,可通過單一職責(zé)這樣的設(shè)計模式來考慮掐暮。組件的核心功能是不能發(fā)生變化的蝎抽,這也是為了接口的向后兼容
  3. 對于業(yè)務(wù)組件,我們可否直接把一些常年不發(fā)生變化的數(shù)據(jù)和UI綁定在一起路克,從而刪減部分接口樟结。大家不必?fù)?dān)心耦合性,解耦的前提是有被解耦的需求精算。

四 開發(fā)組件

1 UI規(guī)范

UI規(guī)范是組件開發(fā)的物理依據(jù)瓢宦,你得知道要做成什么樣子,你才能做灰羽。UI規(guī)范要對整套組件的各個視覺元素(長驮履,寬,padding谦趣,margin疲吸,圓角,顏色前鹅,字體摘悴,字號,邊框舰绘,圖標(biāo)蹂喻,陰影)有語意明確的定義和友好的標(biāo)注葱椭,這樣前端工程師們才能做到有法可依。

2 開發(fā)

舉例:
1.sass或less來寫樣式
2.重置樣式文件和樣式的公共變量文件(將視覺元素翻譯成代碼中的常量形成的文件)口四,這是根據(jù)自己的UI規(guī)范來決定的
3.ES6的哪些特性不使用孵运,用哪一個stage的babel來翻譯
4.需要引入的第三方包有哪些,這個也決定了最后打包出來組件js的大小
5.工程的目錄結(jié)構(gòu)

3 打包

對于Vue蔓彩,我們通常使用的是webpack治笨。具體配置這里不詳細(xì)講解,可以參考入門Webpack赤嚼,看這篇就夠了,還有一個快速方法就是通過Vue-cli生成的模板工程來進(jìn)行更改旷赖。
接著我們要定義清楚我們的打包策略:

舉例:
1.所有的樣式打到一個文件
2.有fonts則單獨打出來
3.組件JS和VueJS不打在一起
4.非通用的第三方包需和組件打在一起

五 最佳實踐

以上四點是正式編寫組件代碼的前置工作。現(xiàn)在我們通過elementUI的源碼來看一個最佳實踐更卒,我們的例子是比較簡單的面包屑等孵,先看一下怎么去使用的這個組件:

用法.png

然后我們來看一下代碼如何實現(xiàn)的

<template>
  <span class="el-breadcrumb__item">
    <span class="el-breadcrumb__inner" ref="link" role="link">
      <slot></slot>
    </span>
    <i v-if="separatorClass" class="el-breadcrumb__separator" :class="separatorClass"></i>
    <span v-else class="el-breadcrumb__separator" role="presentation">{{separator}}</span>
  </span>
</template>
<script>
  export default {
    name: 'ElBreadcrumbItem',
    props: {
      to: {},
      replace: Boolean
    },
    data() {
      return {
        separator: '',
        separatorClass: ''
      };
    },

    inject: ['elBreadcrumb'],

    mounted() {
      this.separator = this.elBreadcrumb.separator;
      this.separatorClass = this.elBreadcrumb.separatorClass;
      let self = this;
      if (this.to) {
        let link = this.$refs.link;
        link.setAttribute('role', 'link');
        link.addEventListener('click', _ => {
          let to = this.to;
          self.replace ? self.$router.replace(to)
            : self.$router.push(to);
        });
      }
    }
  };
</script>

props中就是ElBreadcrumbItem暴露出來的兩個接口,也就是上文第三點提到的內(nèi)容蹂空,接口的值是從父組件傳過來的俯萌。我們再看一下ElBreadcrumb,也就是父組件的代碼實現(xiàn)上枕。

這里簡單解釋一下inject:inject和provide是成對出現(xiàn)的咐熙,是vue@2.2.0的新特性。通過此種方法變可以直接調(diào)用提供provide的組件中的屬性了姿骏,總結(jié)就是依賴注入(DI)糖声。

<template>
  <div class="el-breadcrumb" aria-label="Breadcrumb" role="navigation">
    <slot></slot>
  </div>
</template>
<script>
  export default {
    name: 'ElBreadcrumb',

    props: {
      separator: {
        type: String,
        default: '/'
      },
      separatorClass: {
        type: String,
        default: ''
      }
    },

    provide() {
      return {
        elBreadcrumb: this
      };
    },

    mounted() {
      const items = this.$el.querySelectorAll('.el-breadcrumb__item');
      if (items.length) {
        items[items.length - 1].setAttribute('aria-current', 'page');
      }
    }
  };
</script>

slot其實是專門留給ElBreadcrumbItem的插槽,實際上ElBreadcrumb不涉及什么UI分瘦,它也通過props暴露出來了兩個接口,這個兩個的值是使用者傳入的琉苇。我們可以看到嘲玫,默認(rèn)的分隔符是'/',如果你在ElBreadcrumbItem中通過屬性傳入的分隔符是'+',那面包屑每一級中的分隔符也會是'+',注意一下代碼中的provide和上面的inject相對應(yīng)。最后就是讓組件可注冊

import ElBreadcrumb from './src/breadcrumb';

/* istanbul ignore next */
ElBreadcrumb.install = function(Vue) {
  Vue.component(ElBreadcrumb.name, ElBreadcrumb);
};

export default ElBreadcrumb;

通過給組件添加install方法并扇,讓組件可被Vue.use方法在全局注冊去团。可參考Vue官方文檔API

總結(jié)

本文簡單梳理了一下組件開發(fā)的思路穷蛹,重點在于組件開發(fā)的這些前置條件:

  • 定義組件
  • 劃分顆粒度
  • 理清組件的核心接口
  • 如何定義打包策略和UI規(guī)范

完成這幾點土陪,從代碼層面只是一小部分工作,但若把整個組件作為一個產(chǎn)品來看肴熏,就已經(jīng)完成了一半了鬼雀。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市蛙吏,隨后出現(xiàn)的幾起案子源哩,更是在濱河造成了極大的恐慌鞋吉,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,080評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件励烦,死亡現(xiàn)場離奇詭異谓着,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)坛掠,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,422評論 3 385
  • 文/潘曉璐 我一進(jìn)店門赊锚,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人屉栓,你說我怎么就攤上這事舷蒲。” “怎么了系瓢?”我有些...
    開封第一講書人閱讀 157,630評論 0 348
  • 文/不壞的土叔 我叫張陵阿纤,是天一觀的道長。 經(jīng)常有香客問我夷陋,道長欠拾,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,554評論 1 284
  • 正文 為了忘掉前任骗绕,我火速辦了婚禮藐窄,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘酬土。我一直安慰自己荆忍,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,662評論 6 386
  • 文/花漫 我一把揭開白布撤缴。 她就那樣靜靜地躺著刹枉,像睡著了一般。 火紅的嫁衣襯著肌膚如雪屈呕。 梳的紋絲不亂的頭發(fā)上微宝,一...
    開封第一講書人閱讀 49,856評論 1 290
  • 那天,我揣著相機(jī)與錄音虎眨,去河邊找鬼蟋软。 笑死,一個胖子當(dāng)著我的面吹牛嗽桩,可吹牛的內(nèi)容都是我干的岳守。 我是一名探鬼主播,決...
    沈念sama閱讀 39,014評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼碌冶,長吁一口氣:“原來是場噩夢啊……” “哼湿痢!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起种樱,我...
    開封第一講書人閱讀 37,752評論 0 268
  • 序言:老撾萬榮一對情侶失蹤蒙袍,失蹤者是張志新(化名)和其女友劉穎俊卤,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體害幅,經(jīng)...
    沈念sama閱讀 44,212評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡消恍,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,541評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了以现。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片狠怨。...
    茶點故事閱讀 38,687評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖邑遏,靈堂內(nèi)的尸體忽然破棺而出佣赖,到底是詐尸還是另有隱情,我是刑警寧澤记盒,帶...
    沈念sama閱讀 34,347評論 4 331
  • 正文 年R本政府宣布憎蛤,位于F島的核電站,受9級特大地震影響纪吮,放射性物質(zhì)發(fā)生泄漏俩檬。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,973評論 3 315
  • 文/蒙蒙 一碾盟、第九天 我趴在偏房一處隱蔽的房頂上張望棚辽。 院中可真熱鬧,春花似錦冰肴、人聲如沸屈藐。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,777評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽联逻。三九已至,卻和暖如春检痰,著一層夾襖步出監(jiān)牢的瞬間遣妥,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,006評論 1 266
  • 我被黑心中介騙來泰國打工攀细, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人爱态。 一個月前我還...
    沈念sama閱讀 46,406評論 2 360
  • 正文 我出身青樓谭贪,卻偏偏與公主長得像,于是被迫代替她去往敵國和親锦担。 傳聞我的和親對象是個殘疾皇子俭识,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,576評論 2 349

推薦閱讀更多精彩內(nèi)容