# 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 ~~~ 然后在`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' ~~~