搭建自己的 vue 元件庫(二) —— Element-ui 專案分析

閒不住的李先森發表於2018-09-07

Element UI 專案分析

講過 vue 的外掛開發原理,迫不及待的想要搭建一套自己的 外掛庫,那就從熟悉市面上最常用到的 vue UI 元件 ———— Element UI 開始吧。

使用 vue init webpack-simple productName 初始化專案

前提環境: node npm vue-cli

# init
vue init webpack-simple my-project

# run 
cd my-project
npm install 
npm run dev
複製程式碼

在專案中 安裝 Element

npm install element-ui --save-dev
複製程式碼

目錄結構

安裝 element-ui 之後,開啟 node_modules/element-ui 目錄

Element 的原始碼分為 原始碼版本 和 釋出版本(npm install element-ui 時安裝到 node_modules 中的 element-ui 檔案),釋出版本少了很多原始碼檔案的webpack 等配置檔案,專案結構也更加清晰,方便理解。 這裡分析的就是釋出版本。

Element ui 目錄結構

element-ui
    |--- lib                        // 存放 打包後問檔案目錄
    |--- packages                   // 元件的原始碼目錄
        |--- alert                  // 元件的原始碼包
            |--- src                // 元件bao
            |--- index.js           // 元件的入口檔案
    |--- src                        // 原始碼目錄
        |--- directive              // 實現滾動優化,滑鼠點選優化
        |--- locale                 // i18n 國際化
        |--- mixins                 // Vue 混合器
        |--- transition             // 樣式過渡效果
        |--- utils                  //工具類包
        |--- index.js               //原始碼入口檔案
    |--- types                      //typescript 檔案包
    |--- package.json               //npm 包依賴、檔案配置
複製程式碼

上面也提到了 Element-ui 的原始碼是分為 原始碼版本 和 釋出版本, 從原始碼版本的 build/webpack.common.js 檔案中的 webpack 配置的 entry 可以看到 Element 的檔案入口是 src/index.js 那麼我們的分析也從 src/index 入手。

src/index.js

// src/index.js

import Pagination from '../packages/pagination/index.js'
import Dialog from '../packages/dialog/index'
...   //packages 下的匯入元件包

const components = [   // 講所有的元件統一放到 components 中
    Pagination,
    Dialog,
    ...
]

const install = function(Vue,opts = {}) {

    components.map(component => {
        // 遍歷將元件加入到Vue中
        Vue.component(component.name, component);
    });

    // 載入中
    Vue.use(Loading.directive);

    // 定義Vue的原型 prototype
    Vue.prototype.$ELEMENT = {
        size: opts.size || '',
        zIndex: opts.zIndex || 2000
    };

    Vue.prototype.$alert = MessageBox.alert;
}

複製程式碼

Element-ui 的入口檔案,遵循於 vue外掛開發 的開發方式。

檔案的頭部引入了 packages/xx/index.js, 這個是 Element 內建元件的入口檔案。

installvue 外掛的公開方法。當使用 Vue.use(element) 的時候將會呼叫這個方法。 這個方法的第一個引數是 Vue 構造器, 第二個引數是一個可選的物件。

vue外掛開發中提到外掛的第二種形式 -- 新增全域性資源: 指令/過濾器/過渡/元件 在 install 中,將 內建的檔案通過 元件註冊的形式將 元件新增到了 Elemnet 的全域性資源中。在使用 Element 的專案中, 我們會直接使用 <el-input />, 這便是 Vue.component(component.name,component) 這句話的功勞。 如果對於元件註冊不熟悉 可以看 官網 元件註冊

    Vue.use(Loading.directive);
複製程式碼

這行程式碼同樣是外掛開發的第二種形式,它將 Loading 元件的 directive 掛載到全域性資源。

同樣也使用到了vue外掛開發中提到外掛的第四種形式 -- 新增 vue 例項方法

    Vue.prototype.$alert = MessageBox.alert;
複製程式碼

在使用 Element 的時候,我們就可以使用 this.$alert('xxxx') 這種寫法了。

    if (typeof window !== 'undefined' && window.Vue) {
    install(window.Vue);
    }
複製程式碼

當檢測到 Vue 是全域性變數的時候,自動將 執行 install 方法

module.exports = {
    version: 'xxx',
    install,
    CollapseTransition,
    Loading,
    Pagination,
    Dialog,
    ...
}
module.exports.default = module.exports;
複製程式碼

匯出 Element,這裡匯出的就是 使用 import Element from 'Element' 接收到的物件。 可以看出 src/index.js 檔案不僅匯出了 version install, 同時還匯出了 Dialog Loading 元件,這是因為 Element 的元件是可以單獨引入專案,內建的每一個元件也同樣有一個 install 方法。

packages/button/src/index.js

在分析完 src/index.js 檔案之後,可以看到, Element 的核心就是它的元件,不同功能的元件使得 Element 可以適用於很多場景。

我們從最常見的 button 的入口分析,Element 中一個元件的構成。

import ElButton from './src/button';

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

export default ElButton;


複製程式碼

可以看出這個檔案是 src/index 的簡單版本,返回 ElButton 物件,該物件包含一個 install 方法。 並且在 install 方法中給 Vue 掛在了一個 ElButton 元件資源。

而在 src/index.js 檔案中 Element 又匯入了這個 ElButton 元件。 我們知道在使用 Element 單個元件的時候我們這樣寫

   import {Button} from 'element-ui'
   Vue.use(Button)
複製程式碼

這裡 Vue.use(Button) 就會找到 Button 元件的 install 方法,並給 Vue 掛載了一個 ElButton 元件資源。

說過了 vue外掛開發, 也看過了 Element-ui 的專案結構和專案入口檔案。下一節 我們將會講述如何 在 npm 上面釋出一個我們仿照 Element-ui 的專案。

相關文章