基于elementUI封装自己的UI组件库
初始化 project
这里我们使用官方的 vue-cli 初始化一个 Vue 项目
npm install -g @vue/cli # or yarn global add @vue/cli vue create admin-ui
在src的同级目录创建packages文件夹,用于存放需要打包的组件
package目录结构
接下来让我们写一个简单的Vue component,基于elementUI的input组件的封装
<template> <div v-show="showInput"> <el-input v-model="currentValue" v-bind="$props" @keydown.enter.native="handleInputEnter" :placeholder="placeholder" :dataType="dataType" ref="input" :inputPattern='inputPattern'> </template> </el-input> <div :style="{ visibility: !!editorErrorMessage ? 'visible' : 'hidden' }">{{ editorErrorMessage }}</div> </div> </template> <script> import { Input, Button, Select, Option } from 'element-ui' import pattern from '../../pattern.js' const EMAIL_ERROR = '邮箱验证失败'; export default { name: "FkInput", data() { return { editorErrorMessage: null, showInput: true, inputType: '', emailPattern: pattern.email }; }, props: { ...Input.props, //继承elementUI原有的props ...Button.props, ...Select.props, ...Option.props, value: { type: [Number, String], default: '' }, placeholder: { type: String, default: '请输入内容' }, inputPattern: { type: [Object, String], default: null } }, computed: { currentValue: { get: function() { return this.value; }, set: function(newValue) { this.$emit("input", newValue); // 通过 input 事件更新 model } } }, methods: { evtChange(newValue, lr) { this.$emit('change', newValue, lr); // 事件传值 }, handleInputEnter() { if (this.inputType !== 'textarea') { this.validate() } }, validate() { const type = this.dataType && this.dataType.toLowerCase(); var pattern = this.inputPattern ? this.inputPattern.pattern : '', message = this.inputPattern ? this.inputPattern.message : ''; if (type || pattern) { switch (type) {//在实际项目中需要对多种输入数据类型进行验证,本例只验证了邮箱 case 'email': pattern = this.emailPattern; message = EMAIL_ERROR; break; default: break; } if (pattern && !pattern.test(this.currentValue || '')) { this.editorErrorMessage = message; return false; } } this.editorErrorMessage = ''; } }, mounted() { this.$nextTick(_ => { this.inputType = this.$refs.input.type; }) console.log('mounted'); }, updata() { }, watch: { currentValue: { immediate: true, handler(val) { this.$nextTick(_ => { if (this.inputType !== 'textarea' && val !== '') { this.validate(); } else if (val == '') { this.editorErrorMessage = '' } }); } } } } </script> <style stylus="css"> </style>
组件需加上name属性,在使用组件时,用的就是name的值作为标签值,上面的input组件在使用时<fk-input></fk-input>
配置 project
下面我们来配置当前项目, 以使其可以发布到 npm 上.
如果组件进行按需引入,我们需要每个组件注册到Vue上,因此单个组件中需要暴露我们的Component:
/packages/input/index.js import FkInput from './src/input.vue' FkInput.install = function (Vue) { Vue.component(FkInput.name, FkInput) } export default FkInput
然后我们编辑入口文件 packages/index.js,使其被作为UI库导入时能自动在Vue中注册我们的Component:
import FkInput from './input/index.js' const components = [ FkInput ] const install = function(Vue) { components.forEach(component => { Vue.component(component.name, component); }); } if (typeof window !== 'undefined' && window.Vue) { install(window.Vue); } export default { FkInput, install } export { FkInput, install }
elementUI的引入方式有两种:一种是按需引入,比如某个项目中只使用了某几个组件,可以使用下面的方式
import { Button,Input } from 'element-ui' Vue.use(Button) Vue.use(Input)
如果项目中使用了很多elementUI组件,为了避免漏掉引入的组件,可以使用下面的引入方式
import UI from 'element-ui' Vue.use(UI)
此处也是为了可以使用按需引入的方式进行加载组件,export了两次;
export暴露出来可以在使用时按需引入,export default暴露出来的组件只能在使用时全局引入。
接下来我们添加 build项目的脚本到package.json的scripts中:
其中 --name admin-ui 指定的是要发布的library的名称,我们执行上面新家的脚本:
npm run lib
这里我们选择默认发布我们的 *.common.js 文件, 所以我们在 package.json中添加main属性.
指定该属性后, 当我们引用该组件库时, 会默认加载 main 中指定的文件.
最后, 我们再配置 package.json中的 files属性, 来配置我们想要发布到 npm 上的文件路径.
我们这里将用户引用我们的组件库可能用到的所有文件都放进来:
最终的配置为
npm 发布
首先我们注册一个 npm 账号 (如果已有账号, 可以跳过此步骤)
npm add user// 按照提示输入用户名, 邮箱等即可
然后使用 npm login 登录注册号的状态
登录后可以使用 npm whoami
查看登录状态
在发布之前, 我们修改一下项目的名称(注意不要和已有项目名称冲突), 推荐使用 @username/projectName 的命名方式.
接下来我们就可以发布我们的 UI 组件库了, 在发布之前我们再编译一次, 让build出的文件为我们最新的修改:
npm run lib
我们使用下面的命令发布我们的项目:
npm publish --access public
需要注意的是 package.json中指定的version属性: 每次要更新我们的组件库都需要更新一下version,配置中的private属性需要设置为false
测试使用
这样我们就完成了自己的 UI 组件库的发布. 接下来我们可以在任何需要使用到该组件库的项目中使用:
Import UI '@ssthouse/admin-ui' Vue.use(UI)
接下来我们就可以在 Vue的template中使用组件库中的 Component了:
<template> <fk-input v-model="input" :inputPattern="inputPattern" clearable></fk-input> </template> <script> export default { name: '', data() { return { input: '', placeholder: '', inputPattern:{ pattern: /[\w!#$%&'*+/=?^_`{|}~-]+(?:\.[\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\w](?:[\w-]*[\w])?\.)+[\w](?:[\w-]*[\w])?/, message: '此信息是验证失败提示' } } } } } </script>
最后
经过上面这些步骤后, 我们就拥有了一个属于自己的组件库了. 我们可以随时更新, 发布自己新版的组件库.
而依赖了该组件库的项目只需要使用简单的 npm 命令即可更新 : )


- 相关文章
微信公众号在线生成二维码带参数怎么搞?
带参数二维码是微信公众号渠道二维码的一种实现
微信的带参数二维码有两种,一种是临时二维码,一种是永久二维码,但是永久二维码的生成是有个数限制的,微...谷歌ARCore技术特性简介
谷歌美国时间2017.8.29号刚发布了ARCore预览版,这是一个类似于苹果ARKit的增强现实SDK,在此之前,谷歌虽然已投资AR平台Tango,但由于需要特定的硬件和传感器,...
CentOS6 Apache2.2用域名配置多虚拟机
在CentOS下使用域名配置多虚拟机的步骤如下:
1. 使用CSS3原生变量(Native Variables)新特性简介
对Web开发者来说,一个盼望已久的特性是CSS终于支持原生变量了!
变量是程序语言中用来解决代码重复和进行表达式计算的关键概念(想想数学方程式中的x)。...使用HTML5 Canvas实现的界面元素截屏功能
HTTP/2背景和新特性简介
Babylon.js入门教程和开发实例
Babylon.js是一款WebGL开发框架。和Three.js类似。主要的技术区别是Three.js还试图回退兼容CSS 3D。Three.js是完全社区推动的,比Babylon.js要成熟些,而Babylon...
使用SVG和CSS3创建圆形进度条动画
圆形进度条是一个经典的控制面板元素,常用于显示任务进度,比如用户档案的完整程度,或者升级状态。有很多方法来实现圆形进度条,比如用JS, CSS3, Canvas, SVG...
计算WebGL中的uniforms变量使用数
在使用Three.js为人体模型加载皮肤材料时,启用了skinning:true的参数。有时候会导致GL编译错误,提示“too many uniforms”。下面的文章有助于理解错误原因和检...
深入理解Three.js(WebGL)贴图(纹理映射)和UV映射
本文将详细描述如何使用Three.js给3D对象添加贴图(Texture Map,也译作纹理映射,“贴图”的翻译要更直观,而“纹理映射”更准确。)。为了能够查看在线演示效...
WebGL入门教程4 - 使用纹理贴图(Texture Map)
3D建模和纹理贴图的关系就好比人体和皮肤(或着装)的关系,3D建模用来处理空间属性,而贴图适合用来处理细腻的表面属性。如果不使用贴图,而想在表面达到足够的...
浏览器控制台报JS脚本执行错误:Module is not defined
现在JS分成了两个分支,一部分在服务器端发展如NodeJS,一部分是传统的浏览器运行环境。
有些插件在编写JS代码时,是针对Node编写的,所以直接在浏览器中使...WebGL入门教程3 - Canvas、Context、API和绘制一个矩形
HTML网页布局:静态、自适应、流式、响应式
静态布局(Static Layout)即传统Web设计,对于PC设计一个Layout,在屏幕宽高有调整时,使用横向和竖向的滚动条来查阅被遮掩部分;对于移动设备,单独设计一个布...
更多...