用过Vue.js开发的童鞋应该都知道ElementUI、Iview、Ant Design of Vue等UI框架,这些框架给咱们平常的开发带来巨大的便利,大大提升了开发效率,有不少公司或者项目组也会有属于本身的UI框架。组件开发在面试中也会被问到,有本身的开源UI框架在面试中也有很多的加分。成就感也天然而然的提升。下面分享一下我最近学习开发的内容。css
咱们使用ElementUI时都知道,导入EelementUI后须要使用Vue.use()才能生效,由于每一个插件都应该暴露一个install方法,install 方法调用时,会将 Vue 做为参数传入。Vue.use()也能够传入参数,如Vue.use(MyPlugin, { someOption: true })
可自定义全局的设置,在Vue官方文档有关于插件开发的说明,具体可前去学习。html
Vue支持对*.vue文件进行快速原型开发,因此咱们就不用脚手架构建项目了,直接在bash窗口执行如下命令建立项目vue
$ mkdir my-ui
$ cd my-ui
$ npm init -y
复制代码
在项目中建立如下文件和文件夹,node
在Button.vue
文件中加入如下代码git
<template>
<div>Hello Vue</div>
<template>
复制代码
要支持Vue原型开发,还须要安装如下两个插件github
$ npm install -g @vue/cli
$ npm install -g @vue/cli-service-global
复制代码
安装完成后执行npm serve Button.vue
打开localhost:8080就能看到‘Hello Vue’,接下来咱们就模仿EelmentUI的Button完成一个Button插件。web
修改Button.vue中template的内容以下:面试
<template>
<button :class="`tom-button tom-button-${type} tom-button-${size} ${round ? 'tom-button-round': ''} ${disabled ? 'is-disabled' : ''}`" @click="onClick" :disabled="disabled" >
<slot></slot>
</button>
</template>
复制代码
而后js部分经过props对象传入值,在methods对象添加方法,使用this.$emit传递事件。npm
export default {
name: 'tom-button',
props: {
type: {
type: String,
default: 'default',
validator(type) {
return ['default', 'primary', 'info', 'warning', 'danger'].includes(
type
)
}
},
size: {
type: String,
default: 'medium',
validator(size) {
return ['medium', 'small', 'mini'].includes(size)
}
},
round: {
type: Boolean,
default: false
},
disabled: {
type: Boolean,
defalut: false
}
},
methods: {
onClick(event) {
this.$emit('click', event)
}
}
}
复制代码
最后给Button加上因此的样式json
.tom-button {
display: inline-block;
outline: 0;
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
user-select: none;
cursor: pointer;
line-height: 1;
white-space: nowrap;
background-color: #fff;
border: 1px solid #dcdfe6;
color: #606266;
-webkit-appearance: none;
text-align: center;
box-sizing: border-box;
outline: none;
margin: 0;
transition: 0.1s;
font-weight: 500;
padding: 12px 20px;
font-size: 14px;
border-radius: 4px;
}
.tom-button.is-disabled {
color: #c0c4cc;
cursor: not-allowed;
background-image: none;
background-color: #fff;
border-color: #ebeef5;
}
/*背景颜色*/
.tom-button-primary {
color: #fff;
background-color: #409eff;
border-color: #409eff;
}
.tom-button-primary.is-disabled {
color: #fff;
background-color: #a0cfff;
border-color: #a0cfff;
}
.tom-button-success {
color: #fff;
background-color: #67c23a;
border-color: #67c23a;
}
.tom-button-success.is-disabled {
color: #fff;
background-color: #b3e19d;
border-color: #b3e19d;
}
.tom-button-info {
color: #fff;
background-color: #c8c9cc;
border-color: #c8c9cc;
}
.tom-button-info.is-disabled {
color: #fff;
background-color: #c8c9cc;
border-color: #c8c9cc;
}
.tom-button-warning {
color: #fff;
background-color: #e6a23c;
border-color: #e6a23c;
}
.tom-button-warning.is-disabled {
color: #fff;
background-color: #f3d19e;
border-color: #f3d19e;
}
.tom-button-danger {
color: #fff;
background-color: #f56c6c;
border-color: #f56c6c;
}
.tom-button-danger.is-disabled {
color: #fff;
background-color: #fab6b6;
border-color: #fab6b6;
}
/*Button大小*/
.tom-button-medium {
padding: 10px 20px;
font-size: 14px;
border-radius: 4px;
}
.tom-button-small {
padding: 9px 15px;
font-size: 12px;
border-radius: 3px;
}
.tom-button-mini {
padding: 7px 15px;
font-size: 12px;
border-radius: 3px;
}
/*是否圆角*/
.tom-button-round {
border-radius: 20px;
}
复制代码
而后在Btton文件夹中的index.js给组件添加install方法并导出
import TomButton from './Button.vue'
TomButton.install = function(Vue) {
Vue.component(TomButton.name, TomButton);
};
export default TomButton
复制代码
最后在src目录下的index.js中导入Button中的index.js并全局导出。
// 引入组件
import TomButton from './Button/index.js'
const components = [
TomButton
]
const install = function(Vue, opts) {
if (install.installed) return
// 遍历注册全局组件
components.forEach(component => {
Vue.component(component.name, component);
});
}
// 用于script标签引入
if (typeof window !== 'undefined' && window.Vue) {
install(window.Vue)
}
export default {
install,
TomButton
}
复制代码
到此Button插件就已经完成了,我先在本地测试一下,在根目录新建app.vue文件,导入Button组件:
<template>
<div class="home">
<tom-button size="medium" type="primary" disabled @click="handleClick">按钮</tom-button>
</div>
</template>
<script>
import TomButton from './src/Button/Button.vue'
export default {
components: {
TomButton
},
methods: {
handleClick() {
console.log('test')
}
}
}
</script>
复制代码
在命令窗口执行vue serve app.js
打开浏览器不出意外就会显示以下的按钮,鼠标移上去,也有禁用的符号
本地测试没问题后,就能够打包发布了。打包工具我使用的是rollup.js,使用它首先须要全局安装
$ npm install rollup --global
复制代码
rollup.js默认是不支持打包*.vue文件的,因此要支持打包.vue文件还须要安装如下的包
$ npm install rollup-plugin-commonjs --save
$ npm install rollup-plugin-vue --save
$ npm install vue-template-compiler --save
复制代码
而后在根目录新建配置文件rollup.config.js
,并添加配置代码:
import vue from 'rollup-plugin-vue';
import commonjs from 'rollup-plugin-commonjs';
export default {
input: 'src/Button/index.js',
output: {
file: 'lib/st-vue-ui.js',
format: 'cjs'
},
// 支持.vue文件的打包
plugins: [
commonjs(),
vue(),
]
};
复制代码
接着在package.json
文件添加一条命令"build": "rollup -c rollup.config.js"
,以下图:
完成后在命令窗口执行npm run build
命令,打包完成在根目录就会生成lib文件夹,里面的js文件就是打包后的文件。
打包完成,接下来就能够发布到npm上了,是否是想一想还有点小激动。发布前须要在根目录新建一个.npmignore
文件,这个文件和Git的.gitignore
文件同样,用于过滤不用上传的文件,.npmignore
文件内容以下:
node_modules/
src/
rollup.config.js
app.vue
.gitignore
复制代码
而后在package.json
文件添加一些字段,如下是参考配置,了解更多可去npm官网查看
"name": "st-vue-ui", // 项目名字,npm install + name
"version": "1.0.3", // 项目版本号
"description": "基于Vue的UI插件", // 项目描述
"main": "lib/st-vue-ui.js", //指定了包加载的入口文件,默认值是模块根目录下面的index.js
"private": false, // 为false时表明你的包不是私有的,全部人都能查看并npm install使用
"keywords": ["vue", "UI"], // 项目关键字
复制代码
为了让别人更方便的使用本身插件,咱们能够加上说明文档。在根目录新建README.md
文件,对本身的插件进行简单的介绍,能够下载typora这个软件对*.md
文件进行编辑。
好了,终于能够发布了,发布到npm须要到npm注册一个帐号,注册完成后,回到项目的命令窗口执行npm login
,输入用户名、密码、邮箱登陆成功。
而后执行npm publish
就能够发布了,第一次发布会遇到报错,提示须要验证邮箱。根据提示去邮箱验证后从新执行npm publish
通常均可以发布成功,如图:
发布成功后去本身的主页下查看就能够看到了
如今按照跟ElementUI同样的方法,你能够在本身的项目中使用了。下次更新发布须要修改版本号打包再上传,使用的时候把package.json中包名的版本号改成最新的,而后执行npm install
后重启项目就能够了。
这里我只作了一个简单的Button插件,若是再写一个插件,就在src创建对应的目录如Input,而后新建Input.vue和index.js,把对应的插件的index.js文件导入便可。搭建一套UI组件库仍是挺复杂的,不过经过这个小demo应该能够得到不少的灵感,也对Vue的使用有了更多的学习。目前这个UI框架只能全局引入,不能像ElementUI那样按需引入。目前没有太多时间去学习,以后学习了再作更新,若有思路或者作过的童鞋也欢迎留言指导。路过的童鞋不要忘了点赞鼓励一下哦!