用vue搭建组件库的流程

目录

一、项目介绍

二、用脚手架生成vue项目

三、修正项目结构

四、跑通一个demo

五、卡片组件的设计与代码编写

六、测试组件的功能

七、前端模块化

八、webpack打包js文件

九、Gulp打包css

十、将组件库发布到npm

十一、测试发布后的组件库

十二、搭建组件库文档站点

十三、将项目部署到GitHub


一、项目介绍

所需要的技术:

二、用脚手架生成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

  • 4
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值