赞
踩
参考文档:
推荐使用 pnpm,安装pnpm:
npm install -g pnpm
安装vitepress:
pnpm add vitepress -D
or yarn add vitepress -D
在 script 中添加文档网站启动和打包指令,启动时指定端口 8000,并自动打开
"scripts": {
"docs:dev": "vitepress dev docs --port 8000 --open",
"docs:build": "vitepress build docs"
}
完整 package.json 文件如下:
{ "name": "vue-amazing-ui", "version": "0.0.30", "private": false, "type": "module", "files": [ "dist" ], "main": "./dist/vue-amazing-ui.umd.cjs", "module": "./dist/vue-amazing-ui.js", "exports": { "./dist/style.css": "./dist/style.css", "./css": "./dist/style.css", ".": { "import": "./dist/vue-amazing-ui.js", "require": "./dist/vue-amazing-ui.umd.cjs" } }, "scripts": { "dev": "vite --port 9000 --open --force", "build": "run-p type-check build-only", "docs:dev": "vitepress dev docs --port 8000 --open", "docs:build": "vitepress build docs", "docs:deploy": "sh script/deploy.sh", "pub": "sh script/publish.sh", "preview": "vite preview", "build-only": "vite build", "type-check": "vue-tsc --noEmit", "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore" }, "dependencies": { "@vuepic/vue-datepicker": "^4.5.1", "@vueuse/core": "^10.1.2", "@vueuse/integrations": "^10.1.2", "ant-design-vue": "^3.2.20", "core-js": "^3.30.2", "date-fns": "^2.30.0", "qrcode": "^1.5.3", "swiper": "^9.3.2", "vue": "^3.3.4", "vue-amazing-ui": "^0.0.30", "vue-router": "^4.2.1" }, "devDependencies": { "@rushstack/eslint-patch": "^1.3.0", "@types/node": "^18.16.14", "@vitejs/plugin-vue": "^4.2.3", "@vue/eslint-config-typescript": "^11.0.3", "@vue/tsconfig": "^0.1.3", "eslint": "^8.41.0", "eslint-plugin-vue": "^9.14.0", "less": "^4.1.3", "npm-run-all": "^4.1.5", "prettier": "^2.8.8", "rollup-plugin-visualizer": "^5.9.0", "terser": "^5.17.6", "typescript": "~4.7.4", "unplugin-vue-components": "^0.25.0", "vite": "^4.3.8", "vitepress": "1.0.0-beta.1", "vue-tsc": "^1.6.5" }, "description": "This template should help get you started developing with Vue Amazing UI in Vue 3.", "repository": { "type": "git", "url": "git+https://github.com/themusecatcher/vue-amazing-ui.git" }, "keywords": [ "Vue3", "TS", "Vite", "Amazing", "UI", "Components" ], "author": "theMuseCatcher", "license": "ISC", "bugs": { "url": "https://github.com/themusecatcher/vue-amazing-ui/issues" }, "homepage": "https://github.com/themusecatcher/vue-amazing-ui#readme" }
docs/
目录docs/
下新建 index.md
首页文件docs/
下新建 public/
文件夹(用于存放各种静态资源,例如:网站logo、首页图片等)启动后项目会在自动 /docs 下生成 .vitepress/ 目录
pnpm docs:dev
在 docs/.vitepress 中
config.ts
配置文件theme/
文件夹theme/
中创建 index.ts
文件theme/
中创建 global.less
存放全局样式(使用 less 文件需要安装相应依赖 )utils/
文件夹(用于存放自定义 ts 方法,一会首页自定义显示版本标签会用到)pnpm add less -D
在 docs/index.md 中编写首页相关内容,其中
fetchVersion()
自定义方法用于在首页 tagline 后添加自定义版本标签
--- layout: home title: Vue Amazing UI titleTemplate: Amazing UI Components Library hero: name: Vue Amazing UI text: Amazing UI 组件库 tagline: 基于 Vue3 + TS + Vite 开发 image: src: /logo-with-shadow.png alt: Vue Amazing UI actions: - theme: brand text: Get Started link: /guide/features - theme: alt text: View on GitHub link: https://github.com/themusecatcher/vue-amazing-ui - theme: alt text: View on NPM link: https://www.npmjs.com/package/vue-amazing-ui --- import { onMounted } from 'vue' import { fetchVersion } from './.vitepress/utils/fetchVersion' onMounted(() => { fetchVersion() })
在
docs/.vitepress/utils/
中创建fetchVersion.ts
文件
// 远程读取 github 仓库中 package.json 文件中的 version 版本号 // 方式一: // 读取规则:https://api.github.com/repos///contents/?ref= // return fetch('https://api.github.com/repos/themusecatcher/vue-amazing-ui/contents/package.json?ref=master', { // headers: { // // See https://docs.github.com/en/rest/overview/media-types // Accept: 'application/vnd.github.v3.raw', // // See https://docs.github.com/en/rest/guides/getting-started-with-the-rest-api#authentication // // Authorization: 'token ${GITHUB_TOKEN}', // } // }) // 方式二: // 读取规则:https://raw.githubusercontent.com export function fetchVersion() { return fetch('https://raw.githubusercontent.com/themusecatcher/vue-amazing-ui/master/package.json') .then(res => res.json()) .then(json => json.version ?? '') .then(version => { if (!version) return const tagLineParagragh = document.querySelector('div.VPHero.has-image.VPHomeHero > div > div.main > p.tagline') const docsVersionSpan = document.createElement('samp') docsVersionSpan.classList.add('version-tag') docsVersionSpan.innerText = version tagLineParagragh?.appendChild(docsVersionSpan) }) }
在
docs/.vitepress/theme/global.less
中写入标签样式
.version-tag {
font-size: 14px;
line-height: 1.571;
font-weight: bold;
padding: 4px 6px;
margin-left: 6px;
background: #bd34fe;
color: #FFF;
border-radius: 10px;
display: inline-block;
vertical-align: top;
margin-top: 4px;
}
效果如下图,版本标签:
0.0.30
在
theme/global.less
中写入样式,以下样式皆源自 vite 官网项目中使用的全局样式,并稍加修改:
/** * Colors * -------------------------------------------------------------------------- */ :root { --vp-c-brand: #646cff; --vp-c-brand-light: #747bff; --vp-c-brand-lighter: #9499ff; --vp-c-brand-lightest: #bcc0ff; --vp-c-brand-dark: #535bf2; --vp-c-brand-darker: #454ce1; --vp-c-brand-dimm: rgba(100, 108, 255, 0.08); --c-brand: #646cff; --c-brand-light: #747bff; } /** * Component: Button * -------------------------------------------------------------------------- */ :root { --vp-button-brand-border: var(--vp-c-brand-light); --vp-button-brand-text: var(--vp-c-white); --vp-button-brand-bg: var(--vp-c-brand); --vp-button-brand-hover-border: var(--vp-c-brand-light); --vp-button-brand-hover-text: var(--vp-c-white); --vp-button-brand-hover-bg: var(--vp-c-brand-light); --vp-button-brand-active-border: var(--vp-c-brand-light); --vp-button-brand-active-text: var(--vp-c-white); --vp-button-brand-active-bg: var(--vp-button-brand-bg); } /** * Component: Home * -------------------------------------------------------------------------- */ :root { --vp-home-hero-name-color: transparent; --vp-home-hero-name-background: -webkit-linear-gradient( 120deg, #bd34fe 30%, #41d1ff ); --vp-home-hero-image-background-image: linear-gradient( -45deg, #bd34fe 50%, #47caff 50% ); --vp-home-hero-image-filter: blur(40px); } @media (min-width: 640px) { :root { --vp-home-hero-image-filter: blur(56px); } } @media (min-width: 960px) { :root { --vp-home-hero-image-filter: blur(72px); } } /** * Component: Custom Block * -------------------------------------------------------------------------- */ :root { --vp-custom-block-tip-border: var(--vp-c-brand); --vp-custom-block-tip-text: var(--vp-c-brand-darker); --vp-custom-block-tip-bg: var(--vp-c-brand-dimm); } .dark { --vp-custom-block-tip-border: var(--vp-c-brand); --vp-custom-block-tip-text: var(--vp-c-brand-lightest); --vp-custom-block-tip-bg: var(--vp-c-brand-dimm); } /** * Component: Algolia * -------------------------------------------------------------------------- */ .DocSearch { --docsearch-primary-color: var(--vp-c-brand) !important; } /** * VitePress: Custom fix * -------------------------------------------------------------------------- */ /* Use lighter colors for links in dark mode for a11y. Also specify some classes twice to have higher specificity over scoped class data attribute. */ .dark .vp-doc a, .dark .vp-doc a > code, .dark .VPNavBarMenuLink.VPNavBarMenuLink:hover, .dark .VPNavBarMenuLink.VPNavBarMenuLink.active, .dark .link.link:hover, .dark .link.link.active, .dark .edit-link-button.edit-link-button, .dark .pager-link .title { color: var(--vp-c-brand-lighter); } .dark .vp-doc a:hover, .dark .vp-doc a > code:hover { color: var(--vp-c-brand-lightest); opacity: 1; } .vp-doc a { font-weight: normal; } .vp-doc p { margin: 0; } /* Transition by color instead of opacity */ .dark .vp-doc .custom-block a { transition: color 0.25s; } a:hover { text-decoration: none !important; } summary { font-weight: 600; &:hover { cursor: pointer; color: var(--vp-c-brand-lighter); } } svg { fill: var(--vp-c-text-1); } .VPNavBarTitle .title { transition: all 0.25s; &:hover { color: var(--vp-c-brand); } } .version-tag { font-size: 14px; line-height: 1.571; font-weight: bold; padding: 4px 6px; margin-left: 6px; background: #bd34fe; color: #FFF; border-radius: 10px; display: inline-block; vertical-align: top; margin-top: 4px; }
安装组件库
pnpm add vue-amazing-ui
在
theme/index.ts
中引入默认主题、全局样式并全局注册组件库
import DefaultTheme from 'vitepress/theme'
import './global.less' // global less
import VueAmazingUI from 'vue-amazing-ui'
import 'vue-amazing-ui/css'
// import VueAmazingUI from '../../../dist/vue-amazing-ui'
// import '../../../dist/style.css'
export default {
extends: DefaultTheme, // or ...DefaultTheme
enhanceApp ({ app }) {
app.use(VueAmazingUI)
}
}
在
docs/.vitepress/config.ts
中进行网站配置
import { defineConfig } from 'vitepress' export default defineConfig({ title: `Vue Amazing UI`, description: 'Amazing UI 组件库', base: '/vue-amazing-ui/', head: [ // 网站图标 ['link', { rel: 'icon', type: 'image/svg+xml', href: 'logo.svg' }], // ['link', { rel: 'icon', type: 'image/x-icon', href: 'favicon.ico' }], ], appearance: true, // 默认 true,设为 false 则无法切换dark/light主题,可选 'dark' true false markdown: { lineNumbers: false // 是否显示行数,默认false }, themeConfig: { logo: '/logo.svg', editLink: { pattern: 'https://github.com/themusecatcher/vue-amazing-ui/tree/master/docs/:path', text: 'Suggest changes to this page', }, // 默认支持icon包括:'discord'|'facebook'|'github'|'instagram'|'linkedin'|'mastodon'|'slack'|'twitter'|'youtube' socialLinks: [ { icon: 'github', link: 'https://github.com/themusecatcher/vue-amazing-ui' }, // 自定义icon // { // icon: { // svg: 'Dribbble' // }, // link: 'https://www.npmjs.com/package/vue-amazing-ui' // } ], // search: { // vitepress 内置 search // provider: 'local' // }, algolia: { // algolia 搜索服务 与 内置 search 可二选一 appId: 'SHDNEYGA8Z', apiKey: '91419401b0b0efd31b610e54e5b97249', indexName: 'vue-amazing-ui' }, footer: { message: 'Released under the MIT License.', copyright: 'Copyright © 2023-present The Muse Catcher', }, nav: [ { text: '组件', link: '/guide/features', activeMatch: '/guide/' }, { text: '工具', link: '/utils/started', activeMatch: '/utils/' }, { text: '链接', items: [ { text: 'My Github', link: 'https://github.com/themusecatcher' }, { text: 'My CSDN', link: 'https://blog.csdn.net/Dandrose?type=blog' }, { items: [ { text: 'vue', link: 'https://cn.vuejs.org/', }, { text: 'vitepress', link: 'https://vitepress.dev/', } ] } ] } ], sidebar: { '/guide/': [ { text: '指引', items: [ { text: '特性', link: '/guide/features' }, { text: '快速上手', link: '/guide/started' } ] }, { text: '组件', items: [ { text: '面包屑 Breadcrumb', link: '/guide/components/breadcrumb' }, { text: '按钮 Button', link: '/guide/components/button' }, { text: '走马灯 Carousel', link: '/guide/components/carousel' }, { text: '级联选择 Cascader', link: '/guide/components/cascader' }, { text: '多选框 Checkbox', link: '/guide/components/checkbox' }, { text: '折叠面板 Collapse', link: '/guide/components/collapse' }, { text: '倒计时 Countdown', link: '/guide/components/countdown' }, { text: '日期选择 DatePicker', link: '/guide/components/datepicker' }, { text: '对话框 Dialog', link: '/guide/components/dialog' }, { text: '分割线 Divider', link: '/guide/components/divider' }, { text: '空状态 Empty', link: '/guide/components/empty' }, { text: '图片 Image', link: '/guide/components/image' }, { text: '数字输入框 InputNumber', link: '/guide/components/inputnumber' }, { text: '全局提示 Message', link: '/guide/components/message' }, { text: '信息提示 Modal', link: '/guide/components/modal' }, { text: '通知提醒框 Notification', link: '/guide/components/notification' }, { text: '分页器 Pagination', link: '/guide/components/pagination' }, { text: '进度条 Progress', link: '/guide/components/progress' }, { text: '二维码 QRCode', link: '/guide/components/qrcode' }, { text: '单选框 Radio', link: '/guide/components/radio' }, { text: '评分 Rate', link: '/guide/components/rate' }, { text: '选择器 Select', link: '/guide/components/select' }, { text: '滑动输入条 Slider', link: '/guide/components/slider' }, { text: '加载中 Spin', link: '/guide/components/spin' }, { text: '步骤条 Steps', link: '/guide/components/steps' }, { text: '触摸滑动插件 Swiper', link: '/guide/components/swiper' }, { text: '开关 Switch', link: '/guide/components/switch' }, { text: '表格 Table', link: '/guide/components/table' }, { text: '标签页 Tabs', link: '/guide/components/tabs' }, { text: '文字滚动 TextScroll', link: '/guide/components/textscroll' }, { text: '时间轴 Timeline', link: '/guide/components/timeline' }, { text: '文字提示 Tooltip', link: '/guide/components/tooltip' }, { text: '上传 Upload', link: '/guide/components/upload' }, { text: '播放器 Video', link: '/guide/components/video' }, { text: '瀑布流 Waterfall', link: '/guide/components/waterfall' } ] } ], '/utils/': [ { text: '指引', items: [ { text: '快速上手', link: '/utils/started' } ] }, { text: '工具', items: [ { text: 'date 日期格式化', link: '/utils/date-format' }, { text: 'raf 动画帧', link: '/utils/animation-frame' }, { text: 'raf 定时器', link: '/utils/raf-timeout' }, { text: 'throttle 节流', link: '/utils/throttle' }, { text: 'debounce 防抖', link: '/utils/debounce' }, { text: 'add 加法', link: '/utils/add' }, { text: 'downloadFile 下载文件', link: '/utils/download-file' } ] } ] } } })
填写部署到公网的网站地址、邮箱和代码仓库地址,全部勾选,然后提交!
I am the maintainer of the website, I can modify the code ~
获取
appId
、apiKey
、indexName
在
docs/.vitepress/config.ts
中写入以下配置
import { defineConfig } from 'vitepress'
export default defineConfig({
themeConfig: {
algolia: {
appId: 'SHDNEYGA8Z',
apiKey: '91419401b0b0efd31b610e54e5b97249',
indexName: 'vue-amazing-ui'
}
}
})
algolia 搜索效果如下图:
网站整体目录结构如下图:
网站首页效果如下图:
在
docs/
下新建/guide
文件夹
注意:目录结构需要与
docs/.vitepress/config.ts
配置文件中的sidebar
属性相对应
创建
components/
目录用于存放每个组件对应的文档页
创建
features.md
和started.md
用与编写网站指引中的 特性 和 快速上手页面
features.md
文件:
# 特性
## 简要介绍
该组件库采用 Vue3 + TS + Vite3 + Less 实现!
开箱即用!
## 三种使用方式
- 全局引入所有组件
- 按需引入部分组件
- git clone [vue-amazing-ui](https://github.com/themusecatcher/vue-amazing-ui) 到本地后,从 packages 下单独拷贝单文件组件 (SFC) 到项目内使用
started.md
文件:
# 快速上手 ## 安装 **With PNPM** ```bash $ pnpm i vue-amazing-ui # or $ pnpm add vue-amazing-ui ``` **With Yarn** ```bash $ yarn add vue-amazing-ui ``` **With NPM** ```bash $ npm i vue-amazing-ui ``` ## 使用 **Global** ```ts import { createApp } from 'vue' import App from './App.vue' import VueAmazingUI from 'vue-amazing-ui' import 'vue-amazing-ui/css' const app = createApp(App) app.use(VueAmazingUI) app.mount('#app') ``` **Local** ```vue import { Button } from 'vue-amazing-ui' import 'vue-amazing-ui/css' ```
在
components/
目录下分别创建组件对应md
文件
例如:编写
按钮 button
组件文档:
# 按钮 ## 何时使用 - 当需要添加一个操作按钮时 <script setup lang="ts"> import { ref } from 'vue' const loading = ref(true) function onClick (e: Event) { console.log('click') } </script> ## 基本使用 <div :class="$style['m-flex']"> <Button @click="onClick">Default</Button> <Button effect="reverse" @click="onClick">Reverse</Button> <Button type="primary" @click="onClick">Primary</Button> <Button type="danger" @click="onClick">Danger</Button> <Button disabled @click="onClick">Disabled</Button> </div> ::: details Show Code ```vue <script setup lang="ts"> function onClick (e: Event) { console.log('click') } </script> <template> <Button @click="onClick">Default</Button> <Button effect="reverse" @click="onClick">Reverse</Button> <Button type="primary" @click="onClick">Primary</Button> <Button type="danger" @click="onClick">Danger</Button> <Button disabled @click="onClick">Disabled</Button> </template> ``` ::: ## 大、中、小三种尺寸 <div :class="$style['m-flex']"> <Button size="small" @click="onClick">Small</Button> <Button @click="onClick">Default</Button> <Button size="large" @click="onClick">Large</Button> </div> ::: details Show Code ```vue <script setup lang="ts"> function onClick (e: Event) { console.log('click') } </script> <template> <Button size="small" @click="onClick">Small</Button> <Button @click="onClick">Default</Button> <Button size="large" @click="onClick">Large</Button> </template> ``` ::: ## 自定义样式 <Button :width="120" :height="40" :border-radius="8" size="large" @click="onClick"> <p style="font-size: 18px;">自定义样式</p> </Button> ::: details Show Code ```vue <script setup lang="ts"> function onClick (e: Event) { console.log('click') } </script> <template> <Button :width="120" :height="40" :border-radius="8" size="large" @click="onClick"> <p style="font-size: 18px;">自定义样式</p> </Button> </template> ``` ::: ## 加载中状态 <div :class="$style['m-flex']"> <Button :loading="loading" @click="onClick">Default</Button> <Button :loading="loading" type="primary" @click="onClick">Primary</Button> <Button :loading="loading" type="danger" @click="onClick">Danger</Button> </div> <div :class="$style['m-flex']" style="margin-top: 30px;"> <h3 :class="$style['u-h3']">Loading state: </h3> <Switch v-model:checked="loading" /> </div> ::: details Show Code ```vue <script setup lang="ts"> import { ref } from 'vue' const loading = ref(true) function onClick (e: Event) { console.log('click') } </script> <template> <Button :loading="loading" @click="onClick">Default</Button> <Button :loading="loading" type="primary" @click="onClick">Primary</Button> <Button :loading="loading" type="danger" @click="onClick">Danger</Button> <h3>Loading state: <Switch v-model:checked="loading" /></h3> </template> ``` ::: <style module> .m-flex { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; } .u-h3 { margin-top: 0 !important; } </style> ## APIs 参数 | 说明 | 类型 | 默认值 | 必传 -- | -- | -- | -- | -- name | 默认文本 | string | slot | '按钮' | false type | 类型 | 'default' | 'primary' | 'danger' | 'default' | false effect | 悬浮变化效果,只有 type 为 default 时,effect 才生效 | 'fade' | 'reverse' | '' size | 尺寸 | 'small' | 'middle' | 'large' | '_self' | false width | 宽度,优先级高于size属性,为0时自适应内容的宽度 | number | 0 | false height | 高度,优先级高于size属性 | number | 0 | false borderRadius | 圆角 | number | 5 | false route | 跳转目标URL地址 | {path?: string, query?: object} | {} | false target | 如何打开目标URL,设置 route 时生效 | '_self' | '_blank' | '_self' | false disabled | 是否禁用 | boolean | false | false loading | 是否加载中 | boolean | false | false center | 是否将按钮设置为块级元素并居中展示 | boolean | false | false ## Events 事件名称 | 说明 | 参数 -- | -- | -- click | 点击按钮时的回调,未设置 route 时生效 | (e: Event) => void
在项目根目录 创建
script/
目录,主要用于存放各种脚本文件,方便日后自动化开发流程!
创建
deploy.sh
用于打包静态网站,并部署到 Github
创建
publish.sh
用于打包升级组件库 ,并发布到 npm,同时自动升级项目内组件库依赖版本到最新
deploy.sh
文件:
# /bin/bash # 确保脚本抛出遇到的错误 set -e # 重新打包组件库 pnpm build # 打包生成静态文件 pnpm docs:build # 进入待发布的 dist/ 目录 cd docs/.vitepress/dist git init git add . git commit -m 'deploy' # 部署到 https://.github.io/ git push -f git@github.com:themusecatcher/vue-amazing-ui.git master:github-pages # 提交所有代码到github cd ../../../ git add . git cm -m 'update' git push
publish.sh
文件(需提前登录 npm 账户,否则无法直接发布):
# /bin/bash # 确保脚本抛出遇到的错误 set -e # 读取package.json中的version version=`jq -r .version package.json` # 打包构建 pnpm build # 发布到npm,pnpm(高性能的npm) pnpm publish # 升级 vue-amazing-ui 依赖版本 pnpm up vue-amazing-ui@$version # 提交版本更新代码到github git add . git cm -m "update $version" git push
"scripts": {
"docs:deploy": "sh script/deploy.sh",
"pub": "sh script/publish.sh"
}
pnpm docs:deploy
save 成功之后,点击 Visit site 打开查看网站:
查看内容
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。