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
|--- 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
內建元件的入口檔案。
install
是 vue
外掛的公開方法。當使用 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
的專案。