本文將會從 NutUI 初學者的使用入手,對 NutUI 作了一個快速的概述,但願能幫助新人在項目中快速上手。
文章包括如下主要內容css
Vue 給你們帶來了組件化,這個功能給開發人員帶來了強大而且簡潔的複用組件能力。設計精美,擴展良好的組件無疑會讓產品效果更加統一,帶來更好的觀看感受,減小大量重複性工做,提升代碼的可維護性。
當咱們最初開始使用一個組件庫的時候,不只須要從組件庫中簡單地尋找一個能用的組件,而是從產品的角度出發,除了組件庫所提供的基本組件外,尋求她所具有的其餘特殊功能。
固然了,最後這個組件庫還應該有持續的更新和維護。咱們找了不少組件進行分析測評。先來看一下這一期關於 NutUI 的上手結果。html
NutUI 是一款很是優秀的移動端組件庫。50+組件覆蓋,包含基礎類、數據錄入類、操做反饋類、數據展現類、導航類、佈局類和業務類組件。並且組件風格統一,開發人員的持續維護,保證了組件的健壯性和可維護性,知足多數場景M端需求。同時優秀的文檔和活躍的社區支持,給使用者帶來最優的體驗。
NutUI 從2017年開始發版,全部組件均是從京東的業務中抽離出來,而後不斷整合修復,最終發展成型。專業的標準設計稿保證一致性,優秀的組件自動化測試和不斷的更新保證組件的穩定性。可以解決目前市面上多數基於 Vue 開發的 M 端需求,加快使用者開發進度。那麼下面咱們就帶你們走進 NutUI。vue
咱們依據 NutUI 2.2.2 版本的源碼來分析該組件庫的使用和注意事項。固然,NutUI 早期必定不是這樣子的,咱們分析的這個版本已是通過它屢次迭代優化後的,若是你想去了解它的發展歷程,能夠去 https://github.com/jdf2e/nutu... 搜索它的歷史版本。同時,NutUI 也在進行 3.0 版本的開發。 3.0 版本中將會獨立出 Nut-CLI,同時支持 Vue3.0 的語法,全新的組件和規範。期待你的加入。(想要成爲 NutUI 的維護者嗎?歡迎去 https://github.com/jdf2e/nutu... 中 issue 留言和加入)webpack
目前主流的庫都支持 CDN 引入和 NPM 安裝。NutUI 不例外,還更有亮點。
先說一下 CDN 引入。咱們只要在咱們的 HTML 頁面上加入以下代碼,就能夠完整的使用 NutUI 了。git
<!-- 生產環境版本,優化了尺寸和速度 --> <!-- 引入樣式 --> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@nutui/nutui/dist/nutui.min.css"> <!-- 引入Vue --> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.min.js"></script> <!-- 引入組件庫 --> <script src="https://cdn.jsdelivr.net/npm/@nutui/nutui/dist/nutui.min.js"></script>
固然,NutUI 在這方面比較優秀的就是能夠 CDN 按需加載引入。 (下面實例爲只引入 Button 組件)github
<body> <div id="app"><nut-button>CDN按需加載</nut-button></div> <!-- 開發環境版本,包含了有幫助的命令行警告 --> <!-- 引入樣式 --> <link rel="stylesheet"href="https://cdn.jsdelivr.net/npm/@nutui/nutui/dist/packages/button/button.css"/> <!-- 引入Vue --> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <!-- 引入組件庫 --> <script src="https://cdn.jsdelivr.net/npm/@nutui/nutui/dist/packages/button/button.js"></script> <script> Vue.component(button.default.name, button.default); new Vue({ el: "#app" }); </script> </body>
注意,CDN 引入使用組件的時候。因爲 HTML 中的 attribute 名是大小寫不敏感的,因此瀏覽器會把全部大寫字符解釋爲小寫字符。這意味着當你使用 DOM 中的模板時,組件中的 prop 屬性 camelCase (駝峯命名法) 須要使用其等價的 kebab-case (短橫線分隔命名) 命名。詳情參考 Prop用法
NPM 引入的方式也很是簡潔。咱們使用 Vue-CLI 或者 Gaea CLI 搭建項目以後。在入口文件添加以下代碼。web
Gaea CLI 也是一款 Vue 技術棧單頁面構建工具。且支持一鍵上傳,TypeScript ,Skeleton等特點功能
import Vue from 'vue'; import Nutui from '@nutui/nutui'; import '@nutui/nutui/dist/nutui.css'; Nutui.install(Vue);
固然,如上引入的好處是方便,只須要三行代碼就能夠完整地使用 NutUI 全部的組件,但缺點也很明顯,引入的組件包體積很大,一般一個項目也用不到全部的組件,會有資源浪費。npm
因此最佳方案推薦按需引入。在須要使用某組件的頁面添加以下代碼:(如下爲 dialog , picker 組件按需加載)json
import Vue from 'vue'; import { Dialog,Picker } from '@nutui/nutui'; Dialog.install(Vue); Picker.install(Vue);
在這裏說明一下,NutUI 會主動打包對應組件的 css 代碼,而不像其餘組件庫直接打包全部css。segmentfault
當咱們這樣使用的時候,以爲理所應當,那麼爲何 import { Dialog } from '@nutui/nutui'; 能夠實現按需引入呢?
實際上咱們查看源碼能夠獲得,NutUI 藉助 webpack 的 @nutui/babel-plugin-seperate-import 組件實現將
import { Dialog } from '@nutui/nutui';
轉換成以下代碼
import Dialog from '@nutui/nutui/dist/packages/button/button.js'; // 加載構建後的JS import '@nutui/nutui/dist/packages/button/dialog.css'; //加載構建後的CSS
同時,NutUI 在構建的時候,已經構建出一個完整版的組件庫包和每一個組件獨立的包。而後咱們手動使用 Dialog.install(Vue) 進行註冊。這樣咱們就精準地引入了對應 lib 下的 Dialog 組件的 JS 和 CSS 代碼了。實現了咱們的目標:按需加載。
webpack
的中如何構建多個bundle
呢?主要是entry
選項的配置,entry
的值一般是一個字符串,其實它還能夠是一個對象。咱們新增一個webpack
配置文件,基於組件庫的組件配置文件生成一個對象,key是組件名,value是組件的入口js文件,將此對象做爲該配置文件的entry
選項值便可,其餘配置與完整版的組件庫webpack
配置文件一致(輸出目錄可根據須要自行配置)。構建時執行這兩個配置文件,便可構建出一個完整版的組件庫包和每一個組件獨立的包
const cptConf = require('../src/config.json'); const entry = {}; //遍歷全部組件 cptConf.packages.map((item)=>{ entry[cptName] = `./src/packages/${item.name.toLowerCase()}/index.js`; }); module.exports = { entry };
上面咱們已經完整的引入了 NutUI,接下來,咱們將使用案例來看一下如何使用組件。
咱們在使用一個組件庫的時候,最好在 NutUI 官網上提早把該庫全部的組件所有通讀一遍。這樣,不只使咱們對組件庫有一個完整的印象,並且更有利於咱們在使用組件的時候具備更多選擇性。好比如下一個案例:
一個 app 開發中,進入項目後,經常會出現一個協議的提示,如圖:
你們是否是一會兒就想到了使用 Dialog 組件,可是在使用過程當中,發現內容過長,並且基礎的 Dialog 不支持內容自定義,更不支持內容的滾動。這個時候是否是一籌莫展?其實,換種方式,使用 Popup 組件,而後居中展現,內容所有支持自定義,不就完美的解決了咱們的需求。因此建議你們在使用前通讀一下全部組件,磨刀不誤砍柴工,反而更加有效的提升開發效率。
組件瞭解結束以後,正式進入開發,激動人心的時候終於到了。咱們先來看幾個常規的組件。
日曆組件:日曆組件開發過程當中常見的剛需組件,一個優秀的日曆組件須要包含可以選擇日期,區間選擇等功能。
NutUI 的日曆組件的日曆區間選擇功能,支持同一天的選擇。好比選擇2020/05/20-2020/05/20,這但是其餘組件不支持的功能哦!
咱們使用按需引入的方法來使用日曆組件,在 main.js 中加載日曆組件
import { Calendar } from '@nutui/nutui'; Calendar.install(Vue);
接下來咱們在須要的頁面中添加指定組件
<nut-calendar :is-visible.sync="isVisible2" :default-value="data2" :is-auto-back-fill="true" @close="switchPickerClose('isVisible2')" @choose="setChooseValue2" > </nut-calendar> <nut-cell :showIcon="true" :isLink="true" @click.native="switchPicker('isVisible2')"> <span slot="title"><label>日期選擇</label></span> <span slot="sub-title">有默認日期,選擇後自動回填的~~~</span> <div slot="desc" class="selected-option" > <span class="show-value">{{date2 ? date2 : '請選擇日期'}}</span> </div> </nut-cell> // js部分 export default { data() { return { isVisible2: false, date2: '2020-12-22', }; }, methods: { setChooseValue2(param) { this.date2 = param[3]; }, switchPickerClose(isVisible2){ this.isVisible2=!this.isVisible2; } } };
上面代碼中,is-visible.sync 是來控制日曆是否展現,default-value 是展現日曆的默認日期,close 是關閉事件,choose是咱們選擇日期的事件觸發。默認日曆組件時不顯示的,咱們須要經過點擊 Cell 來控制日曆組件,這樣一個完整的日曆效果就實現了,剩下的就是咱們處理本身的業務了!
思考 : 爲何要使用 .sync ?
除了日曆組件這種須要在頁面上放置組件來展現的,部分組件支持直接函數式調用,好比 Dialog組件,咱們來體驗一下。
先全局註冊 Dialog 組件。
import { Button , Dialog } from '@nutui/nutui'; Button.install(Vue); Dialog.install(Vue);
而後咱們在按鈕上添加一個事件,在事件中使用dialog
<nut-button @click="clickHandler" > 提交 </nut-button> //js部分 export default { data() {}, methods: { clickHandler() { this.$dialog({ title: "提交", content: "你肯定提交當前數據嗎", closeBtn:true, //顯式右上角關閉按鈕 onOkBtn(event) { //肯定按鈕點擊事件 alert("okBtn"); this.close(); //關閉對話框 }, onCancelBtn(event) { //取消按鈕點擊事件,默認行爲關閉對話框 alert("cancelBtn"); //return false; //阻止默認「關閉對話框」的行爲 }, onCloseBtn(event) { //右上角關閉按鈕點擊事件 alert("closeBtn"); //return false; //阻止默認「關閉對話框」的行爲 }, closeCallback(target) { alert("had close"); //對話框關閉回調函數,不管經過何種方式關閉都會觸發 } }); } } };
dialog 的內容不只支持文字,同時支持圖片類型。
this.$dialog({ type:"image", //設置彈窗類型爲」圖片彈窗「 link:"http://m.jd.com", //點擊圖片跳轉的Url imgSrc:"m.360buyimg.com//5b9549eeE4997a18c/070eaf5bddf26be8.jpg", //圖片Url onClickImageLink:function(){ //圖片點擊事件,默認行爲是跳轉Url console.log(this); //返回false可阻止默認的連接跳轉行爲 } });
爲何咱們使用 Dialog 能夠直接經過 this 來直接調用呢?緣由就是 Dialog 組件在構建的時候,其實構建了兩種:一種支持咱們使用組件式使用,另外一種支持咱們使用函數式調用。
import DialogVue from './dialog.vue'; import Dialog from './_dialog'; import './dialog.scss'; const DialogArr = [Dialog, DialogVue]; DialogArr.install = function(Vue){ Vue.prototype['$dialog'] = Dialog; Vue.component(DialogVue.name, DialogVue); }
上面代碼咱們能夠看到,Dialog 構建時,不只使用了 Vue.prototype 來擴展一個新的方法,同時也使用了 Vue.component 來實現組件式調用。
NutUI 中目前不只有傳統的通用組件,如今也在逐漸增長好多特點組件。好比目前已經有的抽獎組件和簽名組件。先去官網一睹爲快吧!
(更多組件和使用方法參考官網文檔 https://nutui.jd.com/)
使用任何一個組件功能能夠相似,但樣式倒是各式各樣。如何在使用 NutUI 的基礎上實現本身的樣式定製呢?
首先咱們來看,NutUI 中全部公共的樣式都在 diststylesvariable.scss 中。當咱們想要修改的時候,能夠在項目中建立一個 scss 文件,而後複製公共樣式中全部變量。
咱們須要修改一下配置。在vue.config.js 的 css 配置或者 webpack 中的 sass-loader 的配置。引入咱們自定義的 scss 文件,注意屬性哦。
module.exports = { css: { loaderOptions: { // 給 sass-loader 傳遞選項 scss: { // @/ 是 src/ 的別名 // 注意:在 sass-loader v7 中,這個選項名是 "data" prependData: ` @import "@/assets/custom_theme.scss"; //這個是咱們自定義的scss文件@import "@nutui/nutui/dist/styles/index.scss"; `, } }, } }
而後咱們使用組件的時候,須要引入 SCSS 文件,而不是 CSS 文件。這樣變完成了對 NutUI 的全局樣式定製。
import Nutui from '@nutui/nutui'; import '@nutui/nutui/dist/nutui.scss';
固然,若是咱們項目中某個特殊組件須要修改樣式,並且不想影響該組件在其餘地方的使用,咱們能夠在頁面上直接使用 /deep/ 進行樣式修改,可是注意添加對樣式style 添加 scoped 哦!
/deep/ 是Vue提供的深度選擇器。詳情參考 VUE官網 Scope CSS
隨着愈來愈多的多語言項目進入咱們的開發需求中。國際化方案成爲一種必需品。談到 Vue 的國際化方案,你們很容易會聯想到 vue-i18n 方案,NutUI 並未引入 vue-i18n,不過它是能夠很好地兼容 vue-i18n 。
全部的國際化方案都會用到語言包,語言包一般會返回一個 JSON 格式的數據,NutUI 組件庫的語言包在 locale/lang 目錄下。咱們使用的時候,須要在引入 NutUI 的時候同時引入對應的語言包。以下是引用了英語語言包。
import Vue from 'vue'; import NutUI from '@nutui/nutui'; import enUS from '@nutui/nutui/dist/locales/lang/en-US'; Vue.use(NutUI , { locale: 'en-US', lang: enUS });
這樣咱們的頁面中全部關於 NutUI 組件的都會使用英語語言展現,如圖:
固然,這只是修改了組件內部的語言,如何將 NutUI 和本身的語言包完美融合呢?咱們構建一個本身的語言包。
// zh_cn.js文件 export default { app: { hello: '你好,世界!' } } // en_us.js文件 export default { app: { hello: 'Hello,World!' } }
而後再入口文件中進行引入。
import Vue from 'vue'; import VueI18n from 'vue-i18n'; import {locale} from '@nutui/nutui'; import enUS from '@nutui/nutui/dist/locales/lang/en-US'; import zhCN from '@nutui/nutui/dist/locales/lang/zn-CH'; import enLocale from './en_us'; import zhLocale from './zh_cn'; Vue.use(VueI18n); Vue.locale = () => {}; // 將語言包進行合併 const messages = { en: { ...enUS, ...enLocale }, zh: { ...zhCN, ...zhLocale } } const i18n = new VueI18n({ locale: 'zh', // 設置默認語言 messages: messages // 設置資源文件對象 }) // const app = new Vue({ el: '#app', i18n })
這樣便將 i18n 和咱們 NutUI 的語言包進行了合併。如何在頁面中使用呢?
<template> <nut-navbar :title="$t('app.hello')" @click-left="show=true"> </nut-navbar> </template>
咱們在 JS 中使用的時候須要加上 this。例如:
created () { console.log('start to enter created ', this.$t('app.hello')) }
接下來,咱們在語言切換的按鈕上綁定以下事件,便可完美的實現語言切換功能了。
tabEn: function () { this.$i18n.locale = 'en' }, tabCn: function () { this.$i18n.locale = 'zh' }
這樣,咱們就完美的實現了多語言的展現和切換功能。是否是很優秀?
當咱們使用一個組件庫的時候,友好的文檔和 Demo 是必不可少的。她可讓咱們更方便快捷的使用。NutUI 的 Demo 和文檔是分開的。從 NutUI 的Github中能夠看出,NutUI 把全部的組件都放在 src/packages 下面。每個組件大概由下面幾部分組成。
其中_test 文件夾內是組件的單元測試。NutUI 如何進行單元測試可參考文章 NutUI單元測試實踐 。其中詳細介紹瞭如何編寫單元測試和在 NutUI 中單元測試實踐。
剩下的文件中以組件命名的 js ,vue , css 文件,是該組件的核心。上面也介紹了一個組件是如何從0開始構建的,一個通用的組件從參數傳入,參數處理,校驗,參數存儲,function 回調等各類特性保證才產出。
demo.vue 文件包含了該組件各類常規用法。咱們官網上全部的實例寫法,均可以在對應組件的 demo 文件種找到。同窗們能夠若是有需求,能夠只看 demo ,來 copy 你想要的功能哦!
最後咱們說到的是.md 文件。md 文件就是咱們官網上對該組件的說明和使用方法,咱們是如何將 md 直接變成咱們的官網呢,點擊這裏能夠獲得答案哦!
至此,關於NutUI 的基本使用,咱們今天就先介紹到這裏。是否是很心動,趕快在你的項目中使用起來吧!歡迎提出寶貴意見 https://github.com/jdf2e/nutui/issues。本文中全部的示例都收錄在https://github.com/jdf2e/nutu... 歡迎訪問點贊!!