阅读 473

如何封装一个Vue UI组件库,并实现按需加载?

这篇文章会介绍如何基于Vue CLI 命令行工具封装一个Vue UI组件库。之前有写过 React 版本从零开始配置做一个React UI 组件的文件,有兴趣的可以看下。 从零开始封装React UI 组件库并发布到NPM

1.安装 Vue CLI

cnpm i  @vue/cli -g
复制代码

可通过 vue --version 命令查看是否安装成功。

2.快速创建一个项目

vue create zswui-v
复制代码

3.新建packages组件源码文件夹

  • zswui-v 根目录创建 packages 文件夹存储 我们的组件源码
  • packages 文件夹下新建 index.js 文件统一导出组件

4.举个例子

以封装一个 Button 按钮为例

  • 新建一个 button 文件夹
  • 在上一步的button文件夹下新建 index.js 文件,作为Button组件的导出
  • button 文件夹下新建 src/button.vue src/button.less

至此目录文件如下

packages                                —————————————组件源码包
    |——button                           —————————————Button组件
        |——src                          —————————————Button源码文件夹
        |   |——button.less              —————————————Button组件样式文件
        |   |——button.vue               —————————————Button组件源码
        index.js                        —————————————Button组件导出文件
    index.js
public
src
.gitigore
babel.config.js
package.json
READEM.md 
复制代码

源码展示

// button/src/button.less
.winyh-button{
    color: pink;
}
复制代码
// button/src/button.vue

<template>
  <button
    class="winyh-button"
    @click="handleClick"
    :disabled="disabled"
  >
    <slot></slot>
  </button>
</template>
<script>
export default {
  name: "Button",
  props: {
    disabled: {
      type: Boolean,
      default: false,
    }
  },
  methods: {
    handleClick(evt) {
      this.$emit("click", evt);
    },
  },
};
</script>

<style lang="less" scoped>
@import "./button.less";
</style>

复制代码
// button/index.js
import Button from "./src/button";

Button.install = function(Vue) {
  Vue.component(Button.name, Button);
};

export default Button;

复制代码

组件集中导出

import Button from "./button";
import Input from "./input";

// 组件集合,用于遍历
const components = [Button, Input];

console.log({ components });

// 定义 install 方法
const install = function(Vue) {
  if (install.installed) return;
  // 遍历注册全局组件
  components.map((component) => Vue.component(component.name, component));
};

// 判断是否是直接引入文件
if (typeof window !== "undefined" && window.Vue) {
  install(window.Vue);
}

export {
  install,
  Button, 
  Input,
};

export default {
  install, 
  Button, 
  Input,
};

复制代码

脚本配置

// package.json 文件源码
{
  "name": "zswui-v",
  "version": "0.0.1",
  "private": false,
  "main": "lib/zswui-v.common.js",
  "style": "lib/zswui-v.css",
  "scripts": {
    "serve": "vue-cli-service serve --open",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint",
    "lib": "vue-cli-service build --target lib --name zswui-v --dest lib packages/index.js",
    "pack": "npm run lib && npm pack",
    "docs:dev": "npx vuepress dev docs",
    "docs:build": "npx vuepress build docs"
  },
  "dependencies": {
    "core-js": "^3.6.5",
    "vue": "^2.6.11"
  },
  "devDependencies": {
    "@vue/cli-plugin-babel": "~4.4.0",
    "@vue/cli-plugin-eslint": "~4.4.0",
    "@vue/cli-plugin-router": "^4.4.6",
    "@vue/cli-service": "~4.4.0",
    "babel-eslint": "^10.1.0",
    "babel-plugin-component": "^1.1.1",
    "babel-plugin-import": "^1.12.2",
    "eslint": "^6.7.2",
    "eslint-plugin-vue": "^6.2.2",
    "less": "^3.12.2",
    "less-loader": "^6.2.0",
    "vue-template-compiler": "^2.6.11",
    "vuepress": "^1.5.2",
    "script-loader": "^0.7.2"
  },
  "eslintConfig": {
    "root": true,
    "env": {
      "node": true
    },
    "extends": [
      "plugin:vue/essential",
      "eslint:recommended"
    ],
    "parserOptions": {
      "parser": "babel-eslint"
    },
    "rules": {}
  },
  "browserslist": [
    "> 1%",
    "last 2 versions",
    "not dead"
  ]
}

复制代码

重点说明

npm run lib

这条命令会生成一个 lib 文件夹,将所有的组件打包。然后 npm publish 发布到 npm仓库。

npm run pack

这条命令会在本地生成一个.tgz的文件。执行 cnpm i /path/to/xxx.tgz 文件就可以在本地安装并测试自己封装的组件库了。

组件全局引入

cnpm i zswui-v --save
复制代码
import zswuiv from "zswui-v"

Vue.use(zswuiv)

// 组件里就可以引用了
<Button></Button>
复制代码

组件按需加载

需要先安装插件

cnpm i babel-plugin-import --save-dev
复制代码

在引入组件库的项目根目录新建.babelrc 文件, 配置如下

{
  "plugins": [
    [
      "import",
      {
        "libraryName": "plglib", // 组件名
        "libraryDirectory": "packages" // 组件源码包名
      }
    ]
  ]
}
复制代码

在组件中按需引入 Button

<tempalte>  
    <div>
        <Button>winyh</Button>
        <p>zswui-v 组件库</p>
    </div>
</tempalte>

import { Button } from "zswui-v"

export default {
    components:{
        Button
    }
}


复制代码

Vue 版本的源码仓库:zswui-v

React 版本的源码仓库:zswui