test-ui-vue v0.1.2
从零开始做一个基于Vue Cli的组件库.md
组件开发篇
一、使用Vue Cli创建项目
1、安装Vue Cli
npm install -g @vue/cli
# OR
yarn global add @vue/cli
2、创建项目
vue create test-ui-vue
二、修改目录,以及配置文件
1、将src目录改为examples
用来展示组件。
2、创建同级别的目录packages
,用来存放自定义组件。
3、由于修改了目录,所以需要重新新配置webpack
,先在最外层创建vue.config.js
。现在的目录结构如下:
TEST-UI-VUE
├── examples # demo源码
│ ├── assets # 主题 字体等静态资源
│ ├── components # 全局公用组件
│ ├── router # 路由
│ ├── views # views 所有页面
│ ├── App.vue # 入口页面
│ └── main.js # 入口文件 加载组件 初始化等
├── packages # 自定义组件模板
├── public # 静态资源
│ │── favicon.ico # favicon图标
│ └── index.html # html模板
├── src # 自定义组导出
│ └── index.js # 自定义组件入口,在此处导出所有组件
├── tests # 测试
├── .browserslistrc # 浏览器和 node 版本的配置
├── .eslintrc.js # eslint 配置项.
├── .gitignore # gitignore
├── babel.config.js # babel-loader 配置
├── jest.config.js # jest 配置
├── package.json # package.json
├── README.md # README.md
└── vue.config.js # vue-cli 配置
4、配置vue.config.js文件并运行项目。
const path = require('path')
module.exports = {
// 修改 pages 入口
pages: {
index: {
entry: 'examples/main.js', // 入口
template: 'public/index.html', // 模板
filename: 'index.html' // 输出文件
}
},
// 扩展 webpack 配置
chainWebpack: config => {
// @ 默认指向 src 目录,这里要改成 examples
// 另外也可以新增一个 ~ 指向 packages
config.resolve.alias
.set('@', path.resolve('examples'))
.set('~', path.resolve('packages'))
// 把 packages 和 examples 加入编译,因为新增的文件默认是不被 webpack 处理的
config.module
.rule('js')
.include.add(/packages/)
.end()
.include.add(/examples/)
.end()
.use('babel')
.loader('babel-loader')
.tap(options => {
// 修改它的选项...
return options
})
}
}
三、新建组件
1、在packages
下面新建一个button
组件的文件夹,同时新建一个index.js
文件,用来导出所有组件。目录结构如下:
TEST-UI-VUE
├── examples # demo源码
│ ├── assets # 主题 字体等静态资源
│ ├── components # 全局公用组件
│ ├── router # 路由
│ ├── views # views 所有页面
│ ├── App.vue # 入口页面
│ └── main.js # 入口文件 加载组件 初始化等
├── packages # 自定义组件模板
│ └── button # button组件
│ │ │── src # button组件源码
│ │ │ └── button.vue # button组件模板
│ │ └── index.js # button组件入口,导出button组件
├── public # 静态资源
│ │── favicon.ico # favicon图标
│ └── index.html # html模板
├── src # 自定义组导出
│ └── index.js # 自定义组件入口,在此处导出所有组件
├── tests # 测试
├── .browserslistrc # 浏览器和 node 版本的配置
├── .eslintrc.js # eslint 配置项.
├── .gitignore # gitignore
├── babel.config.js # babel-loader 配置
├── jest.config.js # jest 配置
├── package.json # package.json
├── README.md # README.md
└── vue.config.js # vue-cli 配置
2、在button.vue
中编写组件
<template>
<button
class="ts-button"
:class="{ 'is-disabled': disabled }"
:disabled="disabled"
>
<span><slot>测试按钮</slot></span>
</button>
</template>
<script>
export default {
name: "TsButton", // 注意这个name是必须的
props: {
disabled: {
type: Boolean,
default: false,
},
},
};
</script>
<style lang="scss">
.ts-button {
display: inline-block;
line-height: 1;
white-space: nowrap;
cursor: pointer;
background: #fff;
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;
user-select: none;
padding: 12px 20px;
font-size: 14px;
border-radius: 4px;
&:focus,
&:hover {
color: #409eff;
border-color: #c6e2ff;
background-color: #ecf5ff;
}
&.is-disabled,
&.is-disabled:focus,
&.is-disabled:hover {
color: #c0c4cc;
cursor: not-allowed;
background-image: none;
background-color: #fff;
border-color: #ebeef5;
}
}
</style>
3、在/packages/button/src/index.js
中暴露组件
import TsButton from './src/button';
/* istanbul ignore next */
TsButton.install = function(Vue) {
Vue.component(TsButton.name, TsButton);
};
export default TsButton;
4、最后在/src/index.js
中导出所有组件
import TsButton from "../packages/button/index.js";
// 所有组件列表
const components = [TsButton];
// 定义install方法,接收Vue作为参数
const install = function (Vue) {
// 判断是否安装,安装过就不继续往下执行
if (install.installed) return;
install.installed = true;
// 遍历注册所有组件
components.map((component) => Vue.use(component));
};
// 检测到Vue才执行,毕竟我们是基于Vue的
if (typeof window !== "undefined" && window.Vue) {
install(window.Vue);
}
export default {
install,
// 所有组件,必须具有install,才能使用Vue.use()
...components,
};
5、在项目中测试组件
在main.js
中引入组件
// 引入组件
import TestUi from '../src/index'
Vue.use(TestUi)
四、发布组件进行测试
1、在 package.json
的 scripts
字段中新增一下命令:
"lib": "vue-cli-service build --target lib --name test-ui-vue --dest lib src/index.js"
--target:
构建目标,默认为应用模式。这里修改为 lib
启用库模式。
--dest :
输出目录,默认 dist
。这里我们改成 lib
[entry]:
最后一个参数为入口文件,这里我们指定编译 /src/index.js/
组件库入口文件。
2、编译组件库
执行命令 npm run lib
,会发现目录下多了lib文件夹
package.json其他配置,配置如下
{
"name": "test-ui-vue",
"version": "0.1.0",
"description": "基于 vue-cli4 的组件库",
"main": "lib/test-ui.umd.min.js",
"author": "test",
"keywords": [
"test-ui"
],
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lib": "vue-cli-service build --target lib --name test-ui-vue --dest lib src/index.js",
"test:unit": "vue-cli-service test:unit",
"lint": "vue-cli-service lint"
},
"dependencies": {
"core-js": "^3.6.5",
"vue": "^2.6.11",
"vue-router": "^3.2.0"
},
"devDependencies": {
"@vue/cli-plugin-babel": "~4.5.0",
"@vue/cli-plugin-eslint": "~4.5.0",
"@vue/cli-plugin-router": "~4.5.0",
"@vue/cli-plugin-unit-jest": "~4.5.0",
"@vue/cli-service": "~4.5.0",
"@vue/eslint-config-prettier": "^6.0.0",
"@vue/test-utils": "^1.0.3",
"babel-eslint": "^10.1.0",
"eslint": "^6.7.2",
"eslint-plugin-prettier": "^3.3.1",
"eslint-plugin-vue": "^6.2.2",
"lint-staged": "^9.5.0",
"prettier": "^2.2.1",
"sass": "^1.26.5",
"sass-loader": "^8.0.2",
"vue-template-compiler": "^2.6.11"
},
"gitHooks": {
"pre-commit": "lint-staged"
},
"lint-staged": {
"*.{js,jsx,vue}": [
"vue-cli-service lint",
"git add"
]
}
}
3、添加.npmignore
文件,发布时,只有编译后的 lib
目录、package.json
、README.md
才需要被发布。所以通过配置.npmignore
文件忽略不需要提交的目录和文件。
# 这是复制 .gitignore 里面的
.DS_Store
node_modules
/dist
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw*
# 以下是新增的
# 要忽略目录和指定文件
examples/
packages/
public/
vue.config.js
babel.config.js
*.map
*.html
4、发布到npm
现需要去npm
官网注册账号
然后本地登录:npm login
最后发布到npm: npm publish
5、最后就可以测试了:
另起一个项目
npm i test-ui-vue
在main.js
中引用
import Vue from "vue";
import App from "./App.vue";
import router from "./router";
// 引入组件
import TestUiVue from 'test-ui-vue'
import 'test-ui-vue/lib/test-ui-vue.css'
Vue.use(TestUiVue)
Vue.config.productionTip = false;
new Vue({
router,
render: (h) => h(App),
}).$mount("#app");
在app.vue
中调用组件:
<template>
<div id="app">
<div id="nav">
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link>
</div>
<router-view />
<ts-button>测试按钮</ts-button>
</div>
</template>