Vue組件開發小結

組件化是長期開發過程當中一個提煉精華的過程,目的主要是如下幾點:前端

  1. 提升複用性
  2. 解耦
  3. 提高將來的開發效率

那麼如何達到這樣的效果呢,咱們能夠分幾步來按部就班地完成。vue

下文主要是思路,想直接獲取代碼可轉戰ElementUI的Github去看源碼webpack

一 組件的定義

組件從大類上能夠分爲兩種:git

  • 基礎組件:例如ElementUI
  • 業務組件:經過基礎組件或者業務組件組合而成,與業務強相關甚至強綁定

二 組件的顆粒度

基礎組件的顆粒度爭議並不大,就是Button,Table等等 業務組件的顆粒度最大能夠爲一個feature,一個feature就是一個能夠獨立上線特性,例如文章的評論點贊功能。咱們能夠想象有一個開關,打開就有這個feature,關閉就沒有,且不會形成聯動的影響。github

三 組件的接口

  1. Vue的組件基本都是經過屬性來進行配置,進而控制組件的功能變化。所以開發組件以前咱們就得明肯定義變量是什麼,明確組件須要開放的接口
  2. 咱們須要理解每個組件的核心功能是什麼,可經過單一職責這樣的設計模式來考慮。組件的核心功能是不能發生變化的,這也是爲了接口的向後兼容
  3. 對於業務組件,咱們能否直接把一些常年不發生變化的數據和UI綁定在一塊兒,從而刪減部分接口。你們沒必要擔憂耦合性,解耦的前提是有被解耦的需求。

四 開發組件

1 UI規範

UI規範是組件開發的物理依據,你得知道要作成什麼樣子,你才能作。UI規範要對整套組件的各個視覺元素(長,寬,padding,margin,圓角,顏色,字體,字號,邊框,圖標,陰影)有語意明確的定義和友好的標註,這樣前端工程師們才能作到有法可依。web

2 開發

舉例:
1.sass或less來寫樣式
2.重置樣式文件和樣式的公共變量文件(將視覺元素翻譯成代碼中的常量造成的文件),這是根據本身的UI規範來決定的
3.ES6的哪些特性不使用,用哪個stage的babel來翻譯
4.須要引入的第三方包有哪些,這個也決定了最後打包出來組件js的大小
5.工程的目錄結構
複製代碼

3 打包

對於Vue,咱們一般使用的是webpack。具體配置這裏不詳細講解,能夠參考入門Webpack,看這篇就夠了,還有一個快速方法就是經過Vue-cli生成的模板工程來進行更改。 接着咱們要定義清楚咱們的打包策略:設計模式

舉例:
1.全部的樣式打到一個文件
2.有fonts則單獨打出來
3.組件JS和VueJS不打在一塊兒
4.非通用的第三方包需和組件打在一塊兒
複製代碼

五 最佳實踐

以上四點是正式編寫組件代碼的前置工做。如今咱們經過elementUI的源碼來看一個最佳實踐,咱們的例子是比較簡單的麪包屑,先看一下怎麼去使用的這個組件: api

用法.png
而後咱們來看一下代碼如何實現的

<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暴露出來的兩個接口,也就是上文第三點提到的內容,接口的值是從父組件傳過來的。咱們再看一下ElBreadcrumb,也就是父組件的代碼實現。sass

這裏簡單解釋一下inject:inject和provide是成對出現的,是vue@2.2.0的新特性。經過此種方法變能夠直接調用提供provide的組件中的屬性了,總結就是依賴注入(DI)。bash

<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暴露出來了兩個接口,這個兩個的值是使用者傳入的。咱們能夠看到,默認的分隔符是'/',若是你在ElBreadcrumbItem中經過屬性傳入的分隔符是'+',那麪包屑每一級中的分隔符也會是'+',注意一下代碼中的provide和上面的inject相對應。最後就是讓組件可註冊

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

總結

本文簡單梳理了一下組件開發的思路,重點在於組件開發的這些前置條件:

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

完成這幾點,從代碼層面只是一小部分工做,但若把整個組件做爲一個產品來看,就已經完成了一半了。

相關文章
相關標籤/搜索