亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

關于Vue組件庫開發詳析

發布時間:2020-08-23 06:03:48 來源:腳本之家 閱讀:182 作者:Frans 欄目:web開發

前言

2017年是Vue.js大爆發的一年,React迎來了一個強有力的競爭對手,王者地位受到挑戰(撰寫此文時github上Vue與React的star數量已逼近)。我們團隊這一年有十多個大型項目采用了Vue技術棧,在開發效率、頁面性能、可維護性等方面都有不錯的收效。 我們希望把這些項目中可復用的功能組件提取出來,給后續項目使用,以減少重復開發,提高效率,同時也為了致敬前端界“出一個框架,造一遍輪子”的行規, 一個基于Vue 2的移動端UI組件庫被提上日程。

組件庫的開發過程總的來說還是比較順利的,這里與大家分享一些問題與思考。

腳手架選擇

盡管我們團隊的這些Vue技術棧項目的腳手架大都使用的是webpack,在為組件庫選擇腳手架的時候我們還是在webpack與Rollup中猶豫了一下。

Rollup看起來更適合組件庫的開發,它把所有模塊構建在一個函數內,執行效率更高,它支持Tree Shaking,只打包需要的代碼,輸出文件更小(webpack后來也支持了)。但綜合考慮之后,我們還是選擇了webpack作為打包工具。首先,按照規劃,demo演示和文檔頁面也在這個腳手架中,所以對代碼分割、熱加載等功能是有需求的,而這方面能力Rollup遠不及webpack。另外,這個組件庫由多人開發維護,基于現有webpack腳手架開發成本更低、效率更高。選擇webpack,讓我們可以更專注于造輪子。

打包

即便選擇了webpack作為打包工具,我們也并不希望這個庫的使用場景局限在webpack項目中,通過AMD/CMD方式、甚至通過script標簽直接引用等場景都應該得到支持。為了達到這個目的,我們需要在webpack配置文件中設置輸出格式,需要配置的選項是output.libraryTarget,有以下可選值:

“var”(默認值)輸出為一個變量

var MyLibrary = _entry_return_ ;

“this” 輸出為this的一個屬性

this["MyLibrary"] = _entry_return_ ;

“window” 輸出為window對象的一個屬性

window["MyLibrary"] = _entry_return_ ;

“global” 輸出為global對象的一個屬性

global["MyLibrary"] = _entry_return_ ;

“commonjs” 輸出為exports 的一個屬性

exports["MyLibrary"] = _entry_return_ ;

“commonjs2” 以module.exports形式輸出

module.exports = _entry_return_ ;

“amd” 輸出為AMD模塊

“umd” 暴露給所有模塊定義,允許它和CommonJS/AMD/全局變量一起工作

很顯然,我們需要把output.libraryTarget的值設為“umd”,以使我們的庫可以工作在各種場景下。

另一個與庫打包有關的設置項是output.umdNamedDefine,在output.libraryTarget 設為umd,且output.library 也設置了的情況下,把此選項值設為true,將會為AMD模塊命名。

webpackConfig.output = {
 path: path.resolve(__dirname, 'dist'),
 publicPath:"/",
 filename: '[name].js',
 library: 'xxx', //模塊名稱
 libraryTarget: 'umd', //輸出格式
 umdNamedDefine: true //是否把模塊名作為AMD輸出的命名空間
};

Vue組件庫只提供組件,Vue文件自身需要組件庫使用者在項目中自行引入,庫中無需打包。所以我們可以把Vue加到externals中。

externals: {
 vue: 'vue'
}

這樣Vue就不會被打包。不過,有個問題,就是用script標簽的形式引用Vue的時候,掛在window上的變量名是“Vue”,而不是我們需要的”vue”,因此使用時會報vue未定義的錯誤。

關于Vue組件庫開發詳析

還好,webpack的externals配置項支持傳入一個對象,可以為不同導出形式指定不同名稱。所以下面這種寫法可以解決這個問題。

關于Vue組件庫開發詳析

組件類型

規劃中的Vue組件庫包含組件(Component)、指令(Directive)和過濾器(Filter)三種類型的存在。

比較特殊的是模態彈窗類(Modal)組件,如Dialog、Toast等等。頁面中可能存在很多個Modal,而很多場景下用戶的行為只會觸發其中一部分,如果把所有可能彈出的Modal(特別是異步的、結構內容復雜的Modal)全部寫在頁面上,是否妥當?對于多頁面應用,每個頁面都寫一遍或者再封裝一層組件是否繁瑣而冗余?這個問題在知乎上引發過討論,尤大(Vue.js作者尤雨溪)本人在參與討論時給出建議,組件多層嵌套時,應該把Modal放在根組件里,然后在子組件里通過事件觸發。在具體應用里,應該這么用,這符合Vue提倡的“狀態驅動”。不過在組件庫里,我們還是希望提供一種更便捷更通用的方式來使用Modal類型的組件。

參考了Element UI等優秀組件庫的做法,我們把Modal類型的組件掛到了Vue.prototype上,使之成為Vue的實例方法,一次安裝、全局調用。

this.$dialog(options);

因此,我們的組件庫組件類型還包括“實例方法”。

組件CSS作用域

對于一個組件,我們希望它的CSS只作用于當前組件內的元素,所以我們給每個組件的Vue單頁面文件的style標簽加上了scoped屬性。編譯后,HTML標簽會被自動添加一個隨機生成的唯一屬性 (比如 data-v-f3f3eg9) ,同時對應的CSS選擇器也會增加同名的屬性選擇器(如.example[data-v-f3f3eg9]),這樣組件內的 CSS 便指定了作用域。

關于Vue組件庫開發詳析

編譯后:

關于Vue組件庫開發詳析

通過scoped屬性的確能達到給組件樣式設置作用域的目的,基本能避免組件內的樣式影響外部,但是它也帶來了另外一個問題,就是給外部覆蓋內部樣式帶來了不便。無論組件功能多么通用,接口多么靈活,只要涉及到UI,就難免無法滿足所有項目樣式需求,所以應該允許在具體的項目中根據需要覆蓋組件部分甚至全部樣式。而scoped隨機生成屬性名提高了覆蓋樣式的難度。

經過權衡,我們在組件里移除了scoped屬性,改用class策略來避免組件內樣式影響外部。當然,scoped屬性也不是沒有存在的意義,它更適合在具體應用中使用,對于復用性高的組件來說,不是最佳選擇。

按需使用與自定義構建

隨著項目推進,組件庫里的組件越來越多,目前已超過40個,構建之后的文件也越來越大。如果某個應用只用到了庫里的少數幾個組件,完全沒有必要使用完整的構建包,所以我們需要提供一種按需使用的方式。早期,我們是讓用戶通過私有npm安裝組件庫之后,根據應用自身需要直接引用src目錄下組件源碼的方式來實現按需加載。這種方式有較大局限性,因為引用的源碼沒有經過編譯,需要用戶自己去處理組件的依賴關系,ES6/SCSS/Vue模板等編譯工作也需要用戶在自己的項目里完成,繁瑣、易出錯,也難以支持webpack外的其他場景。 我們設想提供一種自定義構建的方式,來實現按需打包。首先讓用戶選擇需要哪些組件,然后基于這些信息生成一個個性化的配置文件,再基于這個文件進行構建,最終只打包編譯用戶指定的這些組件。

那么,通過哪種方式與用戶交互,收集用戶指令呢?比較友好的方式是通過web,比如在項目主頁中提供一個頁面,讓用戶在線選擇組件,然后下載構建之后的文件。而根據我們組件庫目前的定位,推薦的使用方式是通過私有npm安裝,所以我們首先推出的是通過命令行界面(CLI)方式來完成自定義構建。

用戶只需要在終端執行命令“npm run custom”,即可得到全部組件的列表,通過鍵盤選擇需要的組件,然后按下回車,腳手架便開始自動完成剩余的個性化構建工作。

關于Vue組件庫開發詳析

片刻之后,只包含用戶所選組件的構建包會出現在dist目錄下,文件體積比完整版本小很多。

關于Vue組件庫開發詳析

這種方式下,所選組件會經歷組件庫腳手架完整的構建流程,自動處理組件依賴關系,對ES6/SCSS/Vue等語法也進行了編譯,構建出的文件也支持AMD/CMD/script標簽直接引用等場景,能比較好的滿足按需使用的需求。

圖標

組件庫UI組件難免會包含一些小圖標,需要尋找一種合適的方式處理這些圖標。

在應用開發中有時會把一些圖片轉成Base64編碼放在代碼里,這會使數據量增大30%左右,所以這種方式不適合較大圖片。而對于小圖標來說,增加的絕對數據量并不大,卻能減少一個http請求,也不失為一種優化方案。不過,組件庫較普通應用對數據量更為敏感,這種方式不是上策。

另一種處理小圖標的經典方案是雪碧圖(CSS Sprite),但這種基于精準位置信息的圖標引用方式在移動端基于rem的布局中并不是那么受歡迎,因為rem布局自身就難以精確,如果用于組件庫也會給按需引用帶來一些不便。

對于小圖標,在移動端更需要的是矢量方案,天然適配各種像素密度的屏幕。

在組件庫中,比較流行的是采用基于CSS3字體(@font-face)的ICON FONT方案,也就是把圖標放在一個自定義字體文件中。有很多優點,比如:

  • ICON在字體中是矢量存在,受移動端歡迎
  • 良好的瀏覽器兼容性,web字體并非CSS3發明,更早之前的瀏覽器(包括IE6)也都事實上支持,雖有些許差異,終歸是有辦法兼容的
  • 可通過CSS控制ICON顏色和透明度等樣式,甚至可以實現顏色漸變效果

關于Vue組件庫開發詳析

我們并沒有選擇ICON FONT方案,我們認為SVG方案更適合移動端組件庫:

  • SVG雖在PC端個別古董瀏覽器中兼容較差,但在移動端兼容良好
  • ICON FONT被認為是文本,所以一些瀏覽器會對其進行抗鋸齒處理,這可能導致圖標不那么銳利,清晰度打折扣
  • SVG樣式控制比ICON FONT更靈活,甚至可以控制圖標各個部分的顏色,實現彩色圖標。而這對ICON FONT來說是不可能實現的
  • ICON FONT通常是用偽對象或偽類插入頁面,其展示受到“line-height”、“vertical-align”、“letter-spacing”、“word-spacing”及字體相關CSS屬性影響,也受到字體字符設計本身影響。而SVG在頁面中就是一個標簽,更方便控制,語義化也更好
  • 結合symbol元素可以實現所謂“SVG Sprite”,也就是把很多SVG圖標整合在一起,通過ID引用指定圖標,可以復用。這種方式比CSS Sprite還要方便,因為不需要關心圖標具體位置信息

關于Vue組件庫開發詳析

SVG Sprite也不是必須手動去組合,借助webpack的 svg-sprite-loader 可以輕松實現SVG Sprite的動態生成,圖標的按需加載不是夢。

擴展閱讀

  • NutUI組件庫 - https://nutui.jd.com
  • webpack output.libraryTarget - https://webpack.js.org/configuration/output/#output-librarytarget
  • umd - https://github.com/umdjs/umd

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對億速云的支持。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

宁津县| 宝兴县| 大洼县| 太白县| 兰溪市| 托里县| 平山县| 景洪市| 台山市| 德化县| 日喀则市| 永嘉县| 隆子县| 土默特左旗| 邢台县| 新郑市| 庆阳市| 新河县| 平远县| 新竹市| 保德县| 青阳县| 金门县| 连云港市| 鄂尔多斯市| 永城市| 上饶市| 石城县| 宁安市| 长海县| 日喀则市| 耒阳市| 依兰县| 平邑县| 和田县| 宝丰县| 荣成市| 宣威市| 枣强县| 东莞市| 盈江县|