ElementUI 原始碼簡析 原始碼結構篇

2022-04-28 21:51:23 字數 4243 閱讀 4333

首先,我們先來看看 elementui 的目錄結構,總體來說,elementui 的目錄結構與vue-cli2相差不大:

test:存放單元測試檔案,合格的單元測試也是乙個成熟的開源專案必備的。

types:存放宣告檔案,方便引入 typescript 寫的專案中,需要在package.json中指定 typing 欄位的值為 宣告的入口檔案才能生效。

說完了資料夾目錄,拋開那些常見的.babelrc.eslintc等檔案,我們來看看根目錄下的幾個看起來比較奇怪的檔案:

接下來,我們來看看專案的入口檔案。正如前面所說的,入口檔案就是src/index.js

/*

automatically generated by './build/bin/build-entry.js'

*/import pagination from '../packages/pagination/index.js';

//...

//引入元件

const components =[

pagination,

dialog,

//...//

元件名稱

];const install = function(vue, opts ={}) );

//全域性註冊指令

vue.use(infinitescroll);

vue.use(loading.directive);

//全域性設定尺寸

vue.prototype.$element =;

//在 vue 原型上掛載方法

vue.prototype.$loading =loading.service;

vue.prototype.$msgbox =messagebox;

vue.prototype.$alert =messagebox.alert;

vue.prototype.$confirm =messagebox.confirm;

vue.prototype.$prompt =messagebox.prompt;

vue.prototype.$notify =notification;

vue.prototype.$message =message;

};/*

istanbul ignore if

*/if (typeof window !== 'undefined' &&window.vue)

export

default

;

總體來說,入口檔案十分簡單易懂。由於使用vue.use方法呼叫外掛程式時,會自動呼叫install函式,所以只需要在install函式中批量全域性註冊各種指令、元件,掛載全域性方法即可。

elementui 的入口檔案有兩點十分值得我們學習:

初始化時,提供選項用於配置全域性屬性,大大方便了元件的使用。

自動化生成入口檔案

我們先來看看入口檔案的第一句話:

這句話告訴我們,該檔案是由build/bin/build-entry.js生成的,所以我們來到該檔案:

var components = require('../../components.json');

var fs = require('fs');

var render = require('json-templater/string');

var uppercamelcase = require('uppercamelcase');

var path = require('path');

var endofline = require('os').eol;

//輸出位址

var output_path = path.join(__dirname, '../../src/index.js');

//匯入模板

var import_template = 'import } from \'../packages/}/index.js\';';

//安裝元件模板

var install_component_template = ' }';

//模板

var main_template = `/*

automatically generated by './build/bin/build-entry.js' */}

import locale from 'element-ui/src/locale';

import collapsetransition from 'element-ui/src/transitions/collapse-transition';

const components =[

}, collapsetransition

];const install = function(vue, opts ={}) );

vue.use(infinitescroll);

vue.use(loading.directive);

vue.prototype.$element =;

vue.prototype.$loading =loading.service;

vue.prototype.$msgbox =messagebox;

vue.prototype.$alert =messagebox.alert;

vue.prototype.$confirm =messagebox.confirm;

vue.prototype.$prompt =messagebox.prompt;

vue.prototype.$notify =notification;

vue.prototype.$message =message;

};/*

istanbul ignore if

*/if (typeof window !== 'undefined' &&window.vue)

export

default

}', locale: locale.use,

i18n: locale.i18n,

install,

collapsetransition,

loading,}};

`;delete

components.font;

var componentnames =object.keys(components);

var includecomponenttemplate =;

var installtemplate =;

var listtemplate =;

//根據 components.json 檔案批量生成模板所需的引數

componentnames.foreach(name =>));

if (['loading', 'messagebox', 'notification', 'message', 'infinitescroll'].indexof(componentname) === -1) ));

} if (componentname !== 'loading') listtemplate.push(` $`);

});//

傳入模板引數

var template =render(main_template, );

//生成入口檔案

fs.writefilesync(output_path, template);

console.log('[build entry] done:', output_path);

build-entry.js使用了json-templater來生成了入口檔案。在這裡,我們不關注json-templater的用法,僅僅研究這個檔案的思想。

它通過引入components.json這個我們前面提到過的靜態檔案,批量生成了元件引入、註冊的**。這樣做的好處是什麼?我們不再需要每新增或刪除乙個元件,就在入口檔案中進行多處修改,使用自動化生成入口檔案之後,我們只需要修改一處即可。

ElementUI 原始碼簡析 Basic篇

row 布局元件中的父元件,用於控制子元件。很簡單的乙個布局標籤,主要通過 justify 和 align 控制子元素的對齊方式,使用 render 函式通過傳入的 tag 屬性控制生成的標籤。在這裡推薦學習下 render 函式和 jsx 的寫法,因為之後比較複雜的元件都是通過 render函式 ...

Sample BSP原始碼簡析

ifndef bsp h define bsp h include sdksample.h include filesystemlayer.h filesystemlayer.h 用來處理檔案系統的目錄 路徑等資訊 後面的mfslayer getconfigfilepath就是用了該檔案中定義的類。...

libc hashtable 原始碼簡析

本文分析的是 中截止至 2016 年 1 月 30 日最新的libc libc 中,hashtable的實現為鏈式結構。在教科書 introduction to algorithm 3rd edition 中,介紹的實現是由乙個陣列作為buckets,每個陣列中儲存乙個鍊錶。但是libc 中,使用乙...