本文将会从 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... 欢迎访问点赞!!