# test-ui-vue
**Repository Path**: xydoc/test-ui-vue
## Basic Information
- **Project Name**: test-ui-vue
- **Description**: 从零开始做一个基于Vue-cli的组件库.md
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2021-09-15
- **Last Updated**: 2024-11-30
## Categories & Tags
**Categories**: Uncategorized
**Tags**: Vue, vue-cli
## README
# 从零开始做一个基于Vue Cli的组件库
### 一、使用Vue Cli创建项目
1、安装Vue Cli
~~~sh
npm install -g @vue/cli
# OR
yarn global add @vue/cli
~~~
2、创建项目
~~~sh
vue create test-ui-vue
~~~
### 二、修改目录,以及配置文件
1、将src目录改为`examples`用来展示组件。
2、创建同级别的目录`packages`,用来存放自定义组件。
3、由于修改了目录,所以需要重新新配置`webpack`,先在最外层创建`vue.config.js`。现在的目录结构如下:
~~~sh
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文件并运行项目。
~~~javascript
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`文件,用来导出所有组件。目录结构如下:
~~~sh
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`中编写组件
~~~vue
~~~
3、在`/packages/button/src/index.js`中暴露组件
~~~javascript
import TsButton from './src/button';
/* istanbul ignore next */
TsButton.install = function(Vue) {
Vue.component(TsButton.name, TsButton);
};
export default TsButton;
~~~
4、最后在`/src/index.js`中导出所有组件
~~~javascript
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`中引入组件
~~~javascript
// 引入组件
import TestUi from '../src/index'
Vue.use(TestUi)
~~~
### 四、发布组件进行测试
1、在 `package.json`的 `scripts` 字段中新增一下命令:
~~~sh
"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其他配置,配置如下
~~~json
{
"name": "test-ui-vue",
"version": "0.1.2",
"description": "从零开始做一个基于Vue Cli的组件库",
"main": "lib/test-ui-vue.umd.min.js",
"author": "xuyong",
"license": "MIT",
"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`文件忽略不需要提交的目录和文件。
~~~sh
# 这是复制 .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`中引用
~~~javascript
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`中调用组件:
~~~vue
~~~
### 五、添加`markdown`插件,使项目支持使用`markdown`直接编写文档并显示到页面
1、安装`markdown`插件
~~~sh
npm i vue-markdown-loader -D
~~~
2、修改`vue.config.js`, 添加`vue-markdown-loader`,使用`webpack`能识别`md`文件
~~~javascript
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;
});
config.module
.rule("md")
.test(/\.md/)
.use("vue-loader")
.loader("vue-loader")
.end()
.use("vue-markdown-loader")
.loader("vue-markdown-loader/lib/markdown-compiler")
.options({
raw: true,
});
},
};
~~~
3、创建存放文档的目录及`md`文件
在 `examples` 目录下创建 `docs` 文件夹,在`docs`文件夹下创建 test.md,文件内容如下
~~~markdown
## tip
:::tip
这是一个 tip。这是一个 tip。这是一个 tip。这是一个 tip。这是一个 tip。这是一个 tip。
:::
## warning
:::warning
这是一个 warning,**这是一个 warning,**。
这是一个 warning。
这是一个 warning,这是一个 warning,这是一个 warning,这是一个 warning。
:::
## demo
:::demo 这是一个 demo。这是一个 demo。这是一个 demo。这是一个 demo。这是一个 demo。这是一个 demo。这是一个 demo。这是一个 demo。
```html
```
:::
~~~
将 `test.md` 添加进路由进行测试
在`router/index.js`中添加
~~~javascript
{
path: '/test',
name: 'test',
component: () => import(/* webpackChunkName: "about" */ '../docs/test.md')
}
~~~
4、安装其他的`markdown`插件
~~~sh
cnpm i markdown-it markdown-it-container -S
~~~
再次修改vue.config.js文件
~~~javascript
const path = require("path");
// 引入markdown-it
const md = require("markdown-it")();
/**
* 增加 hljs 的 classname
*/
function wrapCustomClass(render) {
return function (...args) {
return render(...args)
.replace('', '')
}
}
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;
});
config.module
.rule("md")
.test(/\.md/)
.use("vue-loader")
.loader("vue-loader")
.end()
.use("vue-markdown-loader")
.loader("vue-markdown-loader/lib/markdown-compiler")
.options({
raw: true,
preventExtract: true, // 这个加载器将自动从html令牌内容中提取脚本和样式标签
// 定义处理规则
preprocess: (MarkdownIt, source) => {
MarkdownIt.renderer.rules.table_open = function () {
return '';
};
MarkdownIt.renderer.rules.fence = wrapCustomClass(MarkdownIt.renderer.rules.fence)
// ```code`` 给这种样式加个class code_inline
const code_inline = MarkdownIt.renderer.rules.code_inline;
MarkdownIt.renderer.rules.code_inline = function (...args) {
args[0][args[1]].attrJoin("class", "code_inline");
return code_inline(...args);
};
return source;
},
use: [
// :::demo ****
[
require("markdown-it-container"),
"demo",
{
validate: function (params) {
return params.trim().match(/^demo\s*(.*)$/);
},
render: function(tokens, idx) {
if (tokens[idx].nesting === 1) {
return `
`;
}
return '
\n';
}
},
],
[require("markdown-it-container"), "tip"],
[require("markdown-it-container"), "warning"],
],
});
},
};
~~~
在 examples/components 下添加 DemoBlock.vue,内容如下:
~~~vue
{{isExpand ? '隐藏代码' : '显示代码'}}
~~~
然后在`main.js`中引用`DemoBlock`组件
~~~javascript
import Vue from "vue";
import App from "./App.vue";
import router from "./router";
// 引入组件
import DemoBlock from './components/DemoBlock.vue'
import TestUi from "../src/index";
Vue.use(TestUi);
Vue.component('DemoBlock', DemoBlock)
Vue.config.productionTip = false;
new Vue({
router,
render: (h) => h(App),
}).$mount("#app");
~~~
重新运行项目就可以看到效果了。
5、现在效果应该都出来了,可以给代码添加高亮,使其更漂亮。
~~~sh
npm i highlight.js -S
~~~
再在main.js中添加如下配置,然后代码就能语法高亮了!
~~~javascript
import 'highlight.js/styles/vs.css'
~~~