什么是vue组件库
Vue:一套用于构建用户界面的渐进式框架
Vue组件:组件是可复用的Vue实例 -*.Vue
Vue组件库:基于Vue实现的,独立于业务的第三方UI库,如Element、Ant Design
开始
一、项目初始化
1.用脚手架生成一个项目
安装地址:cli.vuejs.org/zh/guide/in…
npm install -g @vue/cli
vue create m-ui
这里选用vue2
进行开发
2.修正项目结构
vue脚手架生成的目录如下:
我们需要进行一些修改:
将src
重命名为examples
,并添加UI
目录,用来存放组件相关逻辑代码,脚手架默认会启动src
下的服务,因为目录名变了,所以我们需要在vue.config.js
下重新配置项目入口。
修改后的目录结构:
3.跑通一个Button组件
先用Button
组件做个示范,首先需要在UI
目录下新建一个packages
目录用来存放我们的自定义组件,同时新建一个css
目录用来存放组件的样式代码,然后在packages
目录下新建一个button
目录,在其目录下新建src
目录,用来存放组件的源代码main.vue
。
准备工作做好后就可以来封装我们的Button
组件了。
1.在main.vue
中编写button组件逻辑代码
这里我使用scss来处理css代码:安装依赖npm i sass sass-loade@5 node-sass -D
(这里组件的样式已省略,可以自行设计)
<template>
<button class="m-button" v-bind:class="[`m-button--${type}`,`m-button--${size}`,
{'is-plain':plain},
{'is-round':round},
{'is-circle':circle},
{'is-disabled':disabled},
{'is-loading':loading}]"
@click="handleClick"
:disabled="disabled || loading"
:loading="loading"
>
<i class="m-icon-loading" v-if="loading"></i>
<i v-if="icon&&!loading" :class="`iconfont icon-${icon} `"></i>
<!--如果没有传入文本插槽,则不显示span内容-->
<span v-if="$slots.default">
<slot></slot>
</span>
</button>
</template>
<script>
export default {
name: "MButton",
props:{
size:{
type:String,
default:'14px',
},
type:{
type:String,
default:'default',
},
plain:{
type:Boolean,
default:false
},
round:{
type:Boolean,
default:false,
},
circle:{
type:Boolean,
default:false,
},
loading:{
type:Boolean,
default:false,
},
disabled:{
type:Boolean,
default:false,
},
icon:{
type:String,
default:"",
},
autofocus:{
type:Boolean,
default:false,
}
},
methods: {
handleClick(evt) {
this.$emit('click', evt);
}
}
}
</script>
2.在button
目录下创建index.js
文件,用来作为组件对外的接口(实现按需引入)
import Button from './src/main.vue'
Button.install = function(Vue) {
Vue.component(Button.name, Button)
}
export default Button
3.在examples
下的main.js
中添加Button
组件
为什么使用组件库的时候在main.js下直接用
Vue.use(Button)
就可以使用组件了呢?因为
Vue.use(Button)
会默认调用Button的Button.install()
方法再去执行里面的Vue.component()
去注册组件。
4.在App.vue
中引入Button
组件
<div id="app">
<img alt="Vue logo" src="./assets/logo.png">
<M-Button type="main" size="small" icon="correct">封装成功</M-Button>
</div>
这样在页面上就能呈现一个Button
组件了
二、设计一个badge组件
1.怎么设计一个组件?
由外到内分析,从外看整体需要什么属性,然后划分为每块区域需要什么属性和样式,把需要的api整理成一个表格
组件的主要用途:复用=>通用
了解大概的功能后,可以开始动手操作了,前面的步骤和Button
组件是一样的,所以不再赘述。这里放上目录
2.编写组件逻辑代码
main.vue
<template>
<div class="m-badge">
<slot></slot>
<sup
v-show="!hidden && (content || content === 0 || isDot)"
v-text="content"
class="m-badge__content"
:class="[
'm-badge__content--' + type,
{
'is-fixed': $slots.default,
'is-dot': isDot
}
]">
</sup>
</div>
</template>
<script>
export default {
name:'MBadge',
props: {
value: [String, Number],
max: Number,
isDot: Boolean,
hidden: Boolean,
type: {
type: String,
validator(val) {
// 这个值必须匹配下列字符串中的一个
return ['primary', 'success', 'warning', 'info', 'danger'].indexOf(val) > -1;
}
}
},
computed: {
content() {
if (this.isDot) return;
const value = this.value;
const max = this.max;
if (typeof value === 'number' && typeof max === 'number') {
return max < value ? `${max}+` : value;
}
return value;
}
}
}
</script>
badge.scss
.m-badge {
position: relative;
vertical-align: middle;
display: inline-block;
&__content {
background-color: #f06897;
border-radius: 10px;
color: #FFF;
display: inline-block;
font-size: 12px;
height: 18px;
line-height: 18px;
padding: 0 6px;
text-align: center;
white-space: nowrap;
border: 1px solid #FFF
}
&__content.is-fixed {
position: absolute;
top: 0;
right: 10px;
-webkit-transform: translateY(-50%) translateX(100%);
transform: translateY(-50%) translateX(100%)
}
&__content.is-fixed.is-dot {
right: 5px
}
&__content.is-dot {
height: 8px;
width: 8px;
padding: 0;
right: 0;
border-radius: 50%
}
&__content--primary {
background-color: #0ba5f8;
}
&__content--success {
background-color: #00ce3f;
}
&__content--warning {
background-color: #e79f18;
}
&__content--info {
background-color: #a8ddfa;
}
&__content--danger {
background-color: #ed437d;
}
}
index.js
import Badge from './src/main.vue'
Badge.install = function(Vue) {
Vue.component(Badge.name, Badge);
};
export default Badge;
3.测试组件
1.在examples
下的mian.js
中添加Badge
组件
2.在App.vue
页面中使用组件:
<template>
<div id="app">
<img alt="Vue logo" src="./assets/logo.png">
<M-Button type="main" size="small" icon="correct">封装成功</M-Button>
<div style="width:500px; display:flex;justify-content: space-between;">
<M-Badge :value="1" type="success">
<M-Button size="small">Number类型</M-Button>
</M-Badge>
<M-Badge :value="100" :max="99" type="warning">
<M-Button size="small">限制最大值</M-Button>
</M-Badge>
<M-Badge is-dot>
<M-Button size="small" icon="look">小圆点</M-Button>
</M-Badge>
<M-Badge value="hot" type="primary">
<M-Button size="small" >String类型</M-Button>
</M-Badge>
</div>
</div>
</template>
3.效果展示:
三、组件库打包
使用webpack打包js为umd模块
现在组件只能实现按需引入,因为并没有配置整个组件库的入口,所以需要在packages
下面新建一个index.js
文件来配置一个组件库的入口
准备工作完成后,我们开始配置webpack:
1.根目录下创建一个webpack配置文件(名字任意):webpack.component.js
2.安装环境依赖:
- 安装webpack-cli:
npm i webpack-cli
- 为了处理.vue结尾的文件,安装vue-loader:
npm i vue-loader@15 -D
3.编写webpack打包逻辑
const path = require('path')
const { VueLoaderPlugin } = require('vue-loader')
const glob = require('glob'); //node自带的模块用于遍历
const list = {};
async function makeList(dirPath, list) {
const files = glob.sync(`${dirPath}/**/index.js`); //console.log(files):'UI/packages/button/index.js'.'...'
for (let file of files) {
const component = file.split(/[/.]/)[2]; //取到组件name
list[component] = `./${file}`; //添加到list对象
}
}
makeList('UI/packages', list);
module.exports = {
entry: list,
mode: 'development',
output: {
filename: '[name].umd.js',
path: path.resolve(__dirname, 'dist'),
library: 'mui',
libraryTarget: 'umd'
},
plugins: [
new VueLoaderPlugin(),
],
module: {
rules: [{
test: /.vue$/,
use: [{
loader: 'vue-loader',
}]
}]
}
}
4.配置打包命令:找到package.json
文件,配置build:js
打包命令
5.执行npm run build:js
命令进行打包
打包后生成dist目录 其中的**.umd.js
就是我们打包好的文件
到此为止,已经完成了组件库js部分的打包了!
gulp打包css
gulp官网:www.gulpjs.com.cn/
在css目录下新建一个index.scss
来收归所有css代码:
@import './button.scss';
@import './badge.scss';
1.安装打包需要的依赖:npm i sass gulp gulp-sass gulp-minify-css -D
2.在项目根目录下新建一个文件gulpfile.js
来配置打包代码
const gulp = require('gulp');
const sass = require('gulp-sass')(require('sass'))
const minifyCSS = require('gulp-minify-css');
gulp.task('sass', async function() {
return gulp.src('UI/css/**/*.scss')
.pipe(sass())
.pipe(minifyCSS())
.pipe(gulp.dest('dist/css'))
});
3.在package.json
的scripts
下 配置css打包命令:"build:css":"npx gulp sass"
4.执行打包命令:build:css
可以得到打包后的css
5.合并打包命令:
这样只要执行一次build
命令就能同时打包js
和css
文件了。
为什么用webpack和gulp两个打包工具?
1.Gulp侧重于前端开发的整个过程的控制管理(像是流水线),我们可以通过给gulp配置不同的task(通过Gulp中的gulp.task()方法配置,比如启动server、sass/less预编译、文件的合并压缩等等)来让gulp实现不同的功能,从而构建整个前端开发流程。
2.Webpack有人也称之为 模块打包机 ,由此也可以看出Webpack更侧重于模块打包,当然我们可以把开发中的所有资源(图片、js文件、css文件等)都可以看成模块,最初Webpack本身就是为前端JS代码打包而设计的,后来被扩展到其他资源的打包处理。Webpack是通过loader(加载器)和plugins(插件)对资源进行处理的。
3.另外我们知道Gulp是对整个过程进行控制,所以在其配置文件(gulpfile.js)中配置的每一个task对项目中该task配置路径下所有的资源都可以管理。比如,对sass文件进行预编译的task可以对其配置路径下的所有sass文件进行预编译处理
四、组件库发布
1.发布到npm
1.先来修改一下package.json
配置,首先删除private
项
在删除的地方添加组件库的配置信息
"name": "m-ui0",
"version": "0.1.0",
//项目文件中不能添加注释,此举是方便解释
"description": "组件库教程",//表述信息
"main": "dist/index.umd.js",//组件库的入口文件
"keywords": [//关键词 便于查找到我们的组件库
"m-ui0",
"vue",
"ui"
],
"author": "moon",//作者信息
//不需要把所有目录都发布到包里,可以指定希望发布的文件目录
"files": [
"dist",
"UI"//为了方便用户查看源码
],
3.更新README.md
文件,这里主要是用来介绍我们组件库的一些使用和说明。
以上全部做完,就可以开始发布我们的组件库了
登录npm官网:www.npmjs.com/
1.先来注册一个npm账号:
注意:在运行npm login命令之前。必须先把下包的服务器地址切换为npm的官方服务器。否则会导致发布包失败!
2.可以执行 nrm ls
命令 检测登录的服务器是否为官方服务器
关于nrm工具的用法这里不再赘述,可以参考这篇文章:blog.csdn.net/jcodery/art…
3.检查完后在终端执行npm login
命令,依次输入用户名、密码、邮箱后,即可登录成功。
4.登录成功后执行npm publish
命令 发布我们的组件库
4.大功告成!现在就可以在npm官方上看到我们的组件库了:
点击头像=>Packages
点进去可以看到详细信息:
2.测试发布后的组件库
1.新建一个项目
按照README提示
2.先安装我们的组件库npm i m-ui0
3.在main.js
中引入我们的组件库
//全部引入
import 'm-ui0/dist/css/index.css';
import MUI from 'm-ui0';
Vue.use(MUI)
4.在App.vue
中使用组件
5.重新启动项目看效果
五、组件库文档搭建
1.vuepress
中文文档:www.vuepress.cn/guide/getti…
1.将 VuePress 安装为本地依赖:执行npm install -D vuepress
2.创建第一篇文档:执行mkdir docs ; echo '# Hello VuePress' > docs/README.md
运行成功后会生成一个
docs
目录,其中的README.md
文件就是我们的文档
3.在 package.json 中添加一些 scripts
{
"scripts": {
"docs:dev": "vuepress dev docs",
"docs:build": "vuepress build docs"
}
}
4.在本地启动服务器:执行npm run docs:dev
运行成功后就可以看到我们的文档了
乱码问题解决方法:
方法一:①找到README.md文件,用记事本打开 ②选择 文件->另存为,编码改为UTF-8->保存 ③然后就得到正常的页面了。
方法二:删除原README.md文件,重新创建。
2.初始化组件库文档结构
1.添加一个侧边栏
侧边栏需要两个内容:主页和文档
这里用Button组件来进行演示
⑴创建卡片组件对应的入口,在docs目录下新建componentDocs
文件夹在其中新建button.md
文件:用来编写Button
组件的文档
⑵在docs
目录下新建一个.vuepress
文件夹并在其中新建一个config.js
配置文件
想要使 侧边栏(Sidebar)生效,需要配置 themeConfig.sidebar,基本的配置,需要一个包含了多个链接的数组,配置如下:
.vuepress/config.js
module.exports = {
themeConfig: {
sidebar: [
'/',
'/componentsDocs/button'
]
}
}
配置完成后重新启动文档,会出现如下页面:
2.在md文件中使用vue组件
引用官方文档的示例:
所有在 .vuepress/components 中找到的 *.vue 文件将会自动地被注册为全局的异步组件,如:
你可以直接使用这些组件在任意的 Markdown 文件中(组件名是通过文件名取到的):
<demo-1/>
<OtherComponent/>
<Foo-Bar/>
下面我们来正式操作:
⑴在.vuepress
目录下新建一个components
文件夹
⑵把UI
下的Button
组件main.vue
以及其样式scss
文件复制一份到components
目录下,并进行如下修改:
①将
main.vue
文件改名为M-Button.vue
,因为后续还会有其他组件被引用,便于区分;②在
main.vue
中引用scss
文件
⑶之后就可以在md文件中直接使用我们的组件了
注意:md中使用的组件名和我们起的文件名要保持一致
页面效果:
3.编写组件文档
1.先来编写button组件文档:
来到button.md
文件,编写说明文档:
页面效果:
2.编写主页文档
来到README.md
文件,编写说明文档:
页面效果:
4.在github上创建个人站点
我们需要创建一个GitHub Pages
站点
详情可参考GitHub文档:docs.github.com/cn/pages/ge…
首先登录githup
网站:github.com/ 新建一个仓库
我们仓库名称必须是<user>.github.io
格式:
创建成功后,可以在Settings
下的Pages
中查看我们的站点
目前站点没有任何配置,它默认先去找index
文件,如果找不到会显示README.md
文件的内容
5.将文档站点部署到github.io
1.首先我们再新建一个仓库,名字随意
2.仓库建好后,让其和我们本地的项目绑定,并推送到线上仓库
git init
git remote add origin [url]
git add .
git commit -m "1"
git push -u origin master
3.部署vuepress文档
⑴在.vuepress
目录下的config.js
中配置base
我们还可以给站点增加一些配置:
⑵在项目根目录下,创建一个如下的 deploy.sh 文件(参考文档)
⑶在package.json
下的scripts
中配置发布命令:deploy:bash deploy.sh
在部署前我们先把本地代码提交到远程仓库:
git add .
git commit -m "1"
git push
然后执行命令:npm run deploy
进行部署,项目会生成如下文件:
然后就可以在我们项目的pages
中访问我们的站点了
最后附上地址: