概述
公司技術棧開始用vue主導開發,但因為公司前端會vue的不多所以在項目中用到vue的技術不是很深,之前出去面試被接連打擊,而且本來打算開始為公司vue的項目構建自己的組件庫所以去下載了iview
的源碼
打算研究一番,學習大神的組件封裝模式和vue的深層技術的運用,隨便寫博客系列來記錄下自己的心得,因為是個人總結所以可能在認識會有點局限也歡迎各路大神一起討論學習。
iview目錄結構
1.assets—圖片存放目錄
2.build—Webpack配置存放目錄
3.dist—打包之后頁面存放目錄
4.examples—組件的demo頁面存放目錄
5.src—組件根目錄
6.components—組件存放目錄
7.directives—組件封裝的指令存放目錄
8.locale—組件封裝的語言配置存放目錄
9.mixins—組件封裝的混入存放目錄
10.styles—組件的樣式根目錄
11.animation—動畫樣式
12.common—公共樣式
13.components—組件樣式
14.mixins—混入樣式
15.custom.less—樣式公共變量
16.index.less—樣式入口
17.utils—組件內部公共方法
18.index.js—組件入口
源碼解析
index.js 入口
/**
* 配置語言、加載組件
* @param {Object} Vue
* @param {Object} opts
*/
const install = function(Vue, opts = {}) {
if (install.installed) return;
locale.use(opts.locale);
locale.i18n(opts.i18n);
Object.keys(iview).forEach(key => {
Vue.component(key, iview[key]);
});
Vue.prototype.$Loading = LoadingBar;
Vue.prototype.$Message = Message;
Vue.prototype.$Modal = Modal;
Vue.prototype.$Notice = Notice;
Vue.prototype.$Spin = Spin;
};
/**
* 在瀏覽器環境下默認加載組件
*/
// auto install
if (typeof window !== 'undefined' && window.Vue) {
install(window.Vue);
}
/**
* 組件vue.user的對象
*/
const API = {
version: process.env.VERSION, // eslint-disable-line no-undef
locale: locale.use,
i18n: locale.i18n,
install,
Circle,
Switch,
...components
};
API.lang = (code) => {
const langObject = window['iview/locale'].default;
if (code === langObject.i.locale) locale.use(langObject);
else console.log(`The ${code} language pack is not loaded.`); // eslint-disable-line no-console
};
/**
* 輸出對象
*/
module.exports.default = module.exports = API; // eslint-disable-line no-undef
在 examples 文件中的 main.js 中加載 iview 組件
知識點:use
vue 的 use 源碼:
import { toArray } from '../util/index'
export function initUse (Vue: GlobalAPI) {
/**
* 判斷參數fn是fn的話直接運行fn,是對象的話運行對象里的install方法
* @param {Function|Object} plugin 下面參數類型限制是typescript的寫法
* @returns Vue
*/
Vue.use = function (plugin: Function | Object) {
// 判斷該方法或對象是否已經注冊過
const installedPlugins = (this._installedPlugins || (this._installedPlugins = []))
if (installedPlugins.indexOf(plugin) > -1) {
return this
}
// 將參數轉化為數組
const args = toArray(arguments, 1)
// 把vue對象插到數組第一個
args.unshift(this)
// 判斷plugin對象的install是否是方法
if (typeof plugin.install === 'object') {
// 將plugin對象的install執行並且this指向plugin
plugin.install.apply(plugin, args)
// 如果plugin是方法
} else if (typeof plugin === 'function') {
// 執行plugin方法this指向null
plugin.apply(null, args)
}
installedPlugins.push(plugin)
return this
}
}
看源碼我們可以知道在我們以后編寫插件的時候可以有兩種方式。
一種是將這個插件的邏輯封裝成一個對象最后將最后在 install 編寫業務代碼暴露給 Vue 對象。這樣做的好處是可以添加任意參數在這個對象上方便將 install 函數封裝得更加精簡,可拓展性也比較高。
還有一種則是將所有邏輯都編寫成一個函數暴露給 Vue。
其實兩種方法原理都一樣,無非第二種就是將這個插件直接當成 install 函數來處理。
button組件
button的功能不是很多,主要是樣式,所以學習 button 組件大部分時間是看樣式。vue 組件在目錄:
組件樣式目錄:
組件樣式混入目錄:
在分析樣式之前我們先去官網上看 iview 按鈕組件的大概分了哪種模式和按鈕交互上的一些細節。大類上按鈕分為單個按鈕和按鈕組兩類。
單個按鈕
1).字體居中不換行。
2).默認按鈕、幽靈按鍵 hover 邊框顏色和字體顏色改變,過渡效果,主按鍵 hover 背景顏色變淺20%。
3).所有按鍵 active 加陰影,陰影顏色和背景色相同,過渡效果。
1.默認按鈕、主按鍵、幽靈按鈕、虛線按鈕、文字按鈕(因為這些種類的按鈕在實際用到比較多的是主按鍵和幽靈按鍵,所以在自己模擬組件的主要實現了這兩張按鍵)按鈕的交互效果:
2.圖標按鈕
3.按鈕組合
更細的分類可以看 iview官網api。