用vue搭建组件库的流程
用vue简单搭建组件库
目录
一、项目介绍
所需要的技术:
二、用脚手架生成vue项目
1、安装脚手架
npm install -g @vue/cli
2、检查版本
vue --version
我的版本是5.0.8
如果需要升级版本
npm update -g @vue/cli
或者
yarn global update --latest @vue/cli
3、创建项目
vue create 项目名称
三、修正项目结构
修正前:
node_modules:模块
public:静态文件
src:存放入口文件(main.js)、组件等
babel.config.js:配置初始化项目的babel插件
package.json:展示项目的开发依赖和业务依赖
修正后:
搭建组件库,components是重点,将其放在外面
由于src都是存放重要的业务代码,但是本项目重点是components,为了第三方开发者看到开源组件库而产生的歧义,将src改名为examples
由于vue是根据默认的配置进行渲染的,但是我们更改了src的文件名和components的位置等,所以要在vue.config.js进行配置修改(如果没有vue.config.js则需要自己创建):
const { defineConfig } = require("@vue/cli-service");
module.exports = defineConfig({
pages: {
index: {
entry: "examples/main.js", //入口文件
template: "public/index.html", //使用的模板
filename: "index.html", //文件名称
},
},
});
四、跑通一个demo
给components创建css文件夹存放样式代码,创建lib文件夹存放逻辑代码
自定义全局组件,一般引入、注册组件时,方法是:
//引入组件
import Demo from "../components/lib/demo/index.js";
//注册组件
Vue.use(Demo);
注册组件调用的是Vue.component('name', 组件名字)方法,Vue.use()方法实际执行是组件的install方法里的Vue.component()函数,所以这里需要给组件绑定一个install方法去实现真正的绑定组件的逻辑Vue.component()
在components/lib/demo创建index.js文件,给组件绑定一个install方法去实现真正的绑定组件的逻辑Vue.component():
//引入组件
import Demo from "./src/main";
//给组件绑定install方法
export default Demo.install = function (Vue) {
Vue.component(Demo.name, Demo);
};
那么在入口文件main.js注册组件就可以写成:
//引入组件
import Demo from "../components/lib/demo/index.js";
//注册组件
Vue.use(Demo);
这样组件就可以正常使用了
五、卡片组件的设计与代码编写
1、首先分析卡片组件的结构,从整体到局部、从上到下分析组件由什么构成、有什么属性、每个属性有什么类型
2、编写html和样式
##### components/lib/card/src/main.vue ######
<template>
<div class="m*-card">
<div class="m-card-img">
<img src="" alt="" />
</div>
<div class="m-card-summary">summary</div>
<div class="footer">footer</div>
</div>
</template>
<script>
export default {
name: "m-card",
//设置固定属性,属性放在props
props: {
width: {
//卡片宽度
type: Number,
default: 0,
},
imgSrc: {
//卡片图片资源地址
type: String,
default: "",
},
ingHeight: {
//卡片图片高度
type: Number,
default: 0,
},
summary: {
//卡片概要
type: String,
default: "",
},
},
};
</script>
##### components/css/card.css ######
.m-card {
width: 270px;
border-radius: 8px;
background: #fff;
overflow: hidden;
box-shadow: 0 6px 10px 0 rgba(95, 101, 105, 0.15);
padding-bottom: 8px;
}
.m-card-img {
height: 152px;
}
img {
width: 100%;
height: 100%;
}
.m-card-summary {
padding: 8px;
text-align: left;
font-size: 14px;
}
3、编写逻辑代码
##### components/lib/card/src/main.vue ######
<template>
<!-- 给卡片动态设置props里的属性,如果用户输入了该属性的具体值,则按用户的来,否则就按默认的 -->
<div class="m-card" :style="width ? { width: width + 'px' } : {}">
<div
class="m-card-img"
:style="imgHeight ? { height: imgHeight + 'px' } : {}"
>
<img :src="imgSrc" alt="" />
</div>
<!-- 如果卡片概要是string类型,那么就按用户设置的来或者没设置的就按默认的来 -->
<div v-if="summary" class="m-card-summary">{{ summary }}</div>
<!-- 如果卡片概要不是string类型而是插槽 -->
<div v-else class="m-card-summary"><slot></slot></div>
<!-- footer不一定有,用插槽即可,如果用户不设置footer插槽则没有 -->
<!-- <div class="footer">footer</div> -->
<slot class="footer"></slot>
</div>
</template>
六、测试组件的功能
###### examples/App.vue ######
结构部分:
<template>
<div id="app">
<m-card
imgSrc="java.png"
summary="剑指Java面试-offer直通车 百度资深面试官授课"
></m-card>
<br>
<m-card
imgSrc="c.png"
summary="C语言系统化精讲 重塑你的编程思想 打造坚实的开发基础"
>
<!-- 构造footer, v-slot告诉插槽结构在footer -->
<template v-slot:footer>
<div class="footer">
<div class="lever">中级·528人报名</div>
<div class="price">¥299.00</div>
</div>
</template>
</m-card>
<br>
<m-card imgSrc="spring.png" :width="370" :imgHeight="90">
<!-- 测试当概要为插槽结构时是否能实现,没有指明插槽的名字,会自己填到card组件的 <div v-else class="m-card-summary"><slot></slot></div>里的slot里 -->
本路线旨在帮助想快速掌握springboot应用的工程师,全方位多角度带你升级
<template v-slot:footer>
<div class="footer-spring">
<div class="lever">4步骤 · 6门课</div>
<div class="price">10965收藏</div>
</div>
</template></m-card
>
</div>
</template>
样式部分:
<style>
#app {
font-family: Avenir, Arial, Helvetica, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
.footer {
padding: 0 8px;
font-size: 12px;
text-align: left;
}
.level {
color: #9199a1;
margin-bottom: 8px;
}
.price {
color: #f01414;
}
.footer-spring{
display: flex;
justify-content: space-between;
padding: 0 8px;
font-size: 12px;
}
</style>
七、前端模块化
js代码随着业务复杂而日益膨胀,将js代码进行切分,就是模块化
模块化的演进过程:
简要介绍上述的几种模块化方式:
八、webpack打包js文件
1、编写webpack配置文件
在项目文件夹下新建webpack.component.js,完成配置:
//引入vue-loader
const { VueLoaderPlugin } = require("vue-loader");
//引入path,构造绝对路径
const path = require("path"); //node自带
//动态填写组件的入口文件的名字,需要遍历src文件夹,因此需要通过内置库glob去遍历文件夹
const glob = require("glob"); //node自带的库
//设置入口文件,因为每个组件都有自己的入口,所以需要用对象来声明
const list = {
// card: "./components/lib/card/index.js",
};
//输入参数:1.配置组件文件夹的目录,2.配置多入口文件的配置对象
async function makeList(dirPash, list) {
const files = glob.sync(`${dirPash}/**/index.js`); //接受遍历到的文件,主要拿到的是每个组件下的index.js文件
// console.log('files',files) //终端输出完整的文件名,现在想拆分文件名,拿到组件的名字
//遍历files
for (let file of files) {
const component = file.split(/[/.]/)[2]; //拿到组件名
// console.log("component:", component);
list[component] = `./${file}`;
}
// console.log(list);
}
//执行函数
makeList("component/lib", list);
//导出对象给webpack
module.exports = {
//自定义的字段
entry: list, //打包的入口文件,每个组件都有自己的入口
mode:'development', //设置为开发模式
output: {
//输出配置
filename: "[name].umd.js", //name即组件名,最后会得到card.umd.js
path: path.resolve(__dirname, "dist"), //必须用绝对路径,否则打包时报错
library: "mui",
libraryTarget: "umd",
},
plugins: [
//配置loader,对文件进行预处理
//安装vue-loader:npm i vue-loader -D
//引入vue-loader
new VueLoaderPlugin(),
],
module: {
//配置vue-loader
rules:[ {
//告诉webpack对什么文件使用什么rule
test: /\.vue$/,
use: [
{
loader: "vue-loader",
},
],
},
],
},
};
我们希望动态的填充文件名字,就不需要在list里输入完整的文件名了
完整文件名:
const list = {
card:'./components/lib/card/index.js'
};
动态写法:
//动态填写组件的入口文件的名字,需要遍历src文件夹,因此需要通过内置库glob去遍历文件夹
const glob = require("glob"); //node自带的库
//设置入口文件,因为每个组件都有自己的入口,所以需要用对象来声明
const list = {
// card: "./components/lib/card/index.js",
};
//输入参数:1.配置组件文件夹的目录,2.配置多入口文件的配置对象
async function makeList(dirPash, list) {
const files = glob.sync(`${dirPash}/**/index.js`); //接受遍历到的文件,主要拿到的是每个组件下的index.js文件
// console.log('files',files) //终端输出完整的文件名,现在想拆分文件名,拿到组件的名字
//遍历files
for (let file of files) {
const component = file.split(/[/.]/)[2]; //拿到组件名
// console.log("component:", component);
list[component] = `./${file}`;
}
// console.log(list);
}
//执行函数
makeList("component/lib", list);
在终端运行webpack配置文件:node webpack.component.js
在package.json配置打包命令:
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint",
"build:js":"webpack --config ./webpack.components.js"
},
在终端里运行webpack:npm run build:js,在项目里多了一个dist文件夹,存放的就是打包好的文件内容,但是文件里只有组件对应的.umd.js文件,并没有整个组件库的入口文件,这样一来用户只能按需引入,为了用户能够完全引入整个组件库,在lib文件夹下新建index.js,作为整个组件库的入口文件
九、Gulp打包css
webpack没有办法处理css文件,所以需要用到gulp。在项目文件新建gulpfile.js文件,写好配置:
//引入gulp
const gulp = require("gulp");
//如果用到less、sass、scss等css预处理器,则需要引入相关的库将css预处理器转换成css
// const sass = require("gulp-sass"); //将sass转换为css
//对css代码进行压缩
const minifyCss = require("gulp-minify-css");
//整个构建流的配置
gulp.task("css", async function () {
//输出构建流的配置
return gulp
.src("component/css/**/*.css")
.pipe(css()) //将需要处理的文件塞给gulp,src内的路径意思是将css下的所有的以css结尾的文件,拿到这些文件后转换成css(这里针对的是用less、sass、scss等css预处理器写样式才需要这么做,将上面写的css的地方换成自己用的预处理器就可以了)
.pipe(minifyCss()) //压缩css
.pipe(gulp.dest("dist/css")); //拿到压缩文件后将其输出到最后的打包目录
});
在package.json文件里配置gulp的运行命令:
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint",
"build:js": "webpack --config ./webpack.component.js",
"build:css": "npx gulp css"(用的是预处理器,再将css换成less、sass、scss等)
},
终端运行npm run build:css打包css文件,在dist文件夹下会新增css文件夹,里面存放着每个组件的css打包文件,如同webpack打包的时候一样,现在在components/css下建立一个入口文件index.css打包所有组件的css文件:
/* 引入组件 */
@import "./card.css";
在package.json文件新增一个命令,将js和css打包用同一个命令执行,这里直接修改的是build的命令:
"scripts": {
"serve": "vue-cli-service serve",
"build": "npm run build:js && npm run build:css",(先打包js再打包css)
"lint": "vue-cli-service lint",
"build:js": "webpack --config ./webpack.component.js",
"build:css": "npx gulp css"
},
十、将组件库发布到npm
1、到npm官网注册一个自己的账号后登录,点击用户头像下的packages就可以看到自己发布的库。npm发布依赖的配置是package.json,所以要对自定义配置进行修改:
{
"name": "mooc-ui",
"version": "0.1.0",
"private": true,(1.将private去掉,因为这里是第三方的组件库,不需要private属性)
"scripts": {
"serve": "vue-cli-service serve",
"build": "npm run build:js && npm run build:css",
"lint": "vue-cli-service lint",
"build:js": "webpack --config ./webpack.component.js",
"build:css": "npx gulp css"
},
2.添加配置,写在上面删除的private所在的行
{
"name": "mooc-ui",
"version": "0.1.0",
"description": "组件库演示", (定义组件库的描述信息)
"main": "dist/index.umd.js", (定义组件库的入口文件)
"keywords": [ (库的关键词,方便用户找到库)
"mooc-ui",
"vue",
"ui"
],
"author": "kw_chng", (打印作者信息)
"files": [ (制定希望发表的文件目录,因为不是所有文件都需要发表)
"dist",
"components"
],
2、修改README.md文件:(在vscode右上角有浏览建可以浏览README.md)
# mooc-ui组件库
### 快速开始
#### 1.安装组件库
```bash
npm i mooc-ui
```
#### 2.引用组件库
```javascript
//全部引入
import "mooc-ui/dist/css/index.css";
import MUI from "mooc-ui";
Vue.use(MUI);
//按需引入
import "mooc-ui/dist/css/card.css";
import {Card} from "mooc-ui";
Vue.use(Card);
```
3、发布
(1)登录:在终端输入:npm login,按照提示输入自己的账号、密码(不会显示自己写了啥)、邮箱,登录成功
(2)发布:npm publish。如果有报错(npm publish 发包报错 !npm ERR! 403 403 Forbidden - PUT http://registry.npmjs.org/vue-auto-router-cli - You do not have permission to publish “vue-auto-router-cli”. Are you logged in as the correct user?),说明这个库的名字已经被别人用啦,就需要修改package.json的name
十一、测试发布后的组件库
在npm上找到自己发布的库,然后根据快速开始的下载命令和运用指令去用自己的库,看看能不能用,符不符合预期。
十二、搭建组件库文档站点
1、VuePress
(1)安装:npm install -D vuepress
(2)在当前目录下创建文件夹docs,并创建一个写有Hello VuePress的README.md:mkdir docs && echo '# Hello VuePress' > docs/README.md
(3)给 package.json
添加一些 scripts 脚本
{
"scripts": {
"docs:dev": "vuepress dev docs",
"docs:build": "vuepress build docs"
}
}
(4)运行:npm run docs:dev
2、初始化组件库文档结构
(1)在docs下新建.vuepress文件夹,再建配置文件config.js
(2)根据vuepress官网的配置去设置文档的主题
(3).vuepress文件夹下新建components文件夹,将components/lib/src/main.vue复制到下面并改名为m-card,对应的css也复制进来,在m-card.vue里加上style部分:
<style scoped>
@import './card.css';
</style>
(4)在.vuepress文件夹下新建componentD文件夹,再建card.md
这时文档就已经可以看到组件的效果了,但是静态资源(卡片上的图片)怎么显示,去找vuepress官网关于静态资源的配置
3、编写卡片组件文档(在card.md里)
4、编写首页文档(在docs/README.md)
十三、将项目部署到GitHub
更多推荐
所有评论(0)