基于Vue封装一个自己的UI组件库之项目篇

2,403 阅读2分钟

闲来无事,准备动手封装一个UI库,功能后面一点点完善。

Snipaste_2022-01-18_16-04-11.jpg

初始化项目

npm install -g @vue/cli  //全局安装vue
vue create destiny-ui    //创建项目

目录结构

Snipaste_2022-01-18_16-08-07.jpg

文件夹说明
dist文档打包目录
examples组件案例目录
node-modules安装依赖目录
packages组件目录
public文件资源目录
.npmignore上传npm忽略目录
package.json项目配置信息目录
vue.config项目配置目录
README说明目录

首先来封装一个Button组件

<template>
  <button
    class="de-button"
    :class="[
      `de-button-${type}`,
      { 'is-plain': plain },
      { 'is-round': round },
      { 'is-circle': circle },
      { 'is-disabled': disabled },
    ]"
    @click="handleClick"
    :disabled="disabled"
  >
    <span> <slot></slot></span>
  </button>
</template>

<script>
export default {
  name: "DeButton",
  props: {
    type: {
      type: String,
      default: "default",
    },
    plain: {
      type: Boolean,
      default: false,
    },
    round: {
      type: Boolean,
      default: false,
    },
    circle: {
      type: Boolean,
      default: false,
    },
    disabled: {
      type: Boolean,
      default: false,
    },
  },
  mounted() {},
  methods: {
    handleClick(e) {
      this.$emit("click", e);
    },
  },
};
</script>

<style scoped lang="scss">
.de-button {
  display: inline-block;
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
  background: #ffffff;
  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;
  //禁止元素的文字被选中
  -moz-user-select: none;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  padding: 12px 20px;
  font-size: 14px;
  border-radius: 4px;
  &:hover,
  &:focus {
    color: #409eff;
    border-color: #c6e2ff;
    background-color: #ecf5ff;
  }
}
.de-button-primary {
  color: #fff;
  background-color: #409eff;
  border-color: #409eff;
  &:hover,
  &:focus {
    background: #66b1ff;
    background-color: #66b1ff;
    color: #fff;
  }
}
.de-button-success {
  color: #fff;
  background-color: #67c23a;
  border-color: #67c23a;
  &:hover,
  &:focus {
    background: #85ce61;
    background-color: #85ce61;
    color: #fff;
  }
}
.de-button-info {
  color: #fff;
  background-color: #909399;
  border-color: #909399;
  &:hover,
  &:focus {
    background: #a6a9ad;
    background-color: #a6a9ad;
    color: #fff;
  }
}
.de-button-warning {
  color: #fff;
  background-color: #e6a23c;
  border-color: #e6a23c;
  &:hover,
  &:focus {
    background: #ebb563;
    background-color: #ebb563;
    color: #fff;
  }
}
.de-button-danger {
  color: #fff;
  background-color: #f56c6c;
  border-color: #f56c6c;
  &:hover,
  &:focus {
    background: #f78989;
    background-color: #f78989;
    color: #fff;
  }
}
// 朴素按钮样式
.de-button.is-plain {
  &:hover,
  &:focus {
    background: #fff;
    border-color: #489eff;
    color: #409eff;
  }
}
.de-button-primary.is-plain {
  color: #409eff;
  background: #ecf5ff;
  &:hover,
  &:focus {
    background: #409eff;
    border-color: #409eff;
    color: #fff;
  }
}
.de-button-success.is-plain {
  color: #67c23a;
  background: #c2e7b0;
  &:hover,
  &:focus {
    background: #67c23a;
    border-color: #67c23a;
    color: #fff;
  }
}
.de-button-info.is-plain {
  color: #909399;
  background: #d3d4d6;
  &:hover,
  &:focus {
    background: #909399;
    border-color: #909399;
    color: #fff;
  }
}
.de-button-warning.is-plain {
  color: #e6a23c;
  background: #f5dab1;
  &:hover,
  &:focus {
    background: #e6a23c;
    border-color: #e6a23c;
    color: #fff;
  }
}
.de-button-danger.is-plain {
  color: #f56c6c;
  background: #fbc4c4;
  &:hover,
  &:focus {
    background: #f56c6c;
    border-color: #f56c6c;
    color: #fff;
  }
}
// round属性
.de-button.is-round {
  border-radius: 20px;
  padding: 12px 23px;
}
// circle属性
.de-button.is-circle {
  border-radius: 50%;
  padding: 12px;
}
// disabled属性
.de-button.is-disabled {
  cursor: not-allowed;
}
</style>

同目录上新建index.js,用于按需导入导出组件

import Button from './Button'
Button.install = function (Vue) {
     Vue.component(Button.name, Button)
}
export default Button

在文件中使用

<de-button>按钮</de-button>

配置项目

在packages文件下新建index.js,当组件库被使用时自动注册到Component上

// 整个包的入口
// 统一导出
import Button from './Button/index'
import './fonts/iconfont.css'
const components = [
  Button,
]
// 定义install方法
const install = function (Vue) {
  // 注册所有的组件
  components.forEach(component => {
    Vue.component(component.name, component)
  })
}
​
// 判断是否直接引入文件,如果是,就不用调用Vue.use()
if (typeof window !== 'undefined' && window.Vue) {
  install(window.Vue)
}
// 导出install方法
export default {
  install,
  Button
}
​
// 支持按需导入
export {
  install,
  Button
}

使用

全局注册

import DestinydUi from 'destinys-ui';
Vue.use(DestinydUi)

按需引入

import {Button} from 'destinys-ui';
Vue.use(Button)

配置打包文件

在package.json文件中配置打包命令

注意:每次打包的时候都需要更改version,要不然登录不上去;private必须是false;name必须在npm官方是唯一的


{
    "name": "destinys-ui",
    "version": "0.3.7",
    "private": false,
    "main": "dist/destinys-ui.umd.js",
    "author": {
        "name": "xxxx",
        "email": "xxxx@qq.com"
    },
    "scripts": {
        "lib": "vue-cli-service build --target lib packages/index.js"
      },
}

在.npmignore配置忽略目录

# 忽略目录
examples/
packages/
public/
 
# 忽略指定文件
vue.config.js
babel.config.js
*.map

最后执行打包命令

npm run lib

发布npm

1.查看自己使用的是否为npm官方源(必须是官方源)

npm get registry   //查看使用的是什么源
npm config set registry https://registry.npmjs.org/     //切换官方源
npm config set registry http://registry.npm.taobao.org   //切换淘宝源

2.登录npm

若没有npm账号,自己去官网注册,这里不做说明

npm login

这里会让你输入用户名、密码、邮箱

3.发布

npm publish

注意:若发布失败,有一下几种情况

package.json

1.version  //和之前发布的版本号一样,换一个即可
2.private  //没有设置为false
3.name     //在npm官网上名字已经存在。换一个即可

使用发布的UI库

1.安装

npm i destinys-ui

2.使用 main.js

//全局引入
import DeDestinysUI 'destinys-ui'
Vue.use(DeDestinysUI)
​
------------------------
//按需引入
import {Button} 'destinys-ui'
Vue.use(Button)

3.组件中使用 xxx.vue

<template>
  <de-button>按钮</de-button>
</template>

\