# 文档搭建
# VuePress
- Vue 驱动的静态网站生成器。
- 以 Markdown 为中心的项目结构,以最少的配置帮助你专注于写作。
- 享受 Vue + webpack 的开发体验,可以在 Markdown 中使用 Vue 组件,又可以使用 Vue 来开发自定义主题。
- VuePress 会为每个页面预渲染生成静态的 HTML,同时,每个页面被加载的时候,将作为 SPA 运行。
# 项目生成和配置
安装
mkdir xqh-vue-ui-doc && cd xqh-vue-ui-doc npm init -y // 创建package.json npm install vuepress -D // 安装vuepress框架
在package.json中配置scripts
"scripts":{ "docs:dev": "vuepress dev docs", "docs:build": "vuepress build docs", }
项目目录
├─docs │ │─.vuepress │ │ components # demo | | styles # 文档展示样式 | | config.js # 配置 | | enhanceApp.js │ │ │ ├─components # 所有组件的文档 | | button.md │ │ │ └─README.md | │ .gitignore # 忽略文件 │ package-lock.json │ package.json │ README.md
配置入口界面
docs/README.md
--- home: true // 是否首页 actionText: 开始使用 // 首页文本 actionLink: /components/installation features: - title: xqh-vue-ui details: 一套基于 Vue.js 的高质量 UI 组件库 - title: 指南 details: 了解设计指南,帮助产品设计人员搭建逻辑清晰、结构合理且高效易用的产品。 - title: 组件demo details: xqh-vue-components 不定期更新~ footer: MIT Licensed | COPYRIGHT © 2021-2022 懒鱼 版权所有 ---
配置导航
docs/.vuepress/config.js
module.exports = { title: 'xqh-vue-ui', // 设置网站标题 description: 'xqh-vue-ui 是一款轻量、好用的 Vue 组件库', // 描述 // dest: './build', // 设置输出目录 port: 1234, // 端口 head: [['link', { rel: 'icon', href: 'logo.png' }]], // 设置 logo themeConfig: { // 主题配置 nav: [ // 头部导航条 { text: '组件', link: '/components/installation' }, ], // 为以下路由添加侧边栏 sidebar: { '/components/': [ { title: '快速上手', collapsable: false, children: ['/components/installation'] }, // 其他设置 ] } } }
覆盖默认样式
docs/.vuepress/styles/palette.styl
// 颜色 $accentColor = #ECC68B; $textColor = #4C506D; $borderColor = #E6E1D7; $codeBgColor = #fafafa; $arrowBgColor = #D4A46F; $badgeTipColor = #C1C19C; // $badgeWarningColor = darken(#ffe564, 35%) // $badgeErrorColor = #DA5961 // 布局 $navbarHeight = 4rem; $sidebarWidth = 15rem; $contentWidth = 900px; $homePageWidth = 1000px; .theme-default-content pre code, .theme-default-content pre[class*='language-'] code { color: #476582; }
应用级别的配置
docs/.vuepress/enhanceApp.js
下载插件和依赖:element-ui、highlight.js(代码高亮)、sass、sass-loader
link开发的组件库:这样就可以一边开发组件库,一边写文档啦,最终上线改为下载npm包并引入就可以了。
# 进入xqh-vue-ui项目,创建链接对象 npm link # 进入xqh-vue-ui-doc项目,建立xqh-vue-ui项目的链接 npm link xqh-vue-ui # 解除链接 npm unlink xqh-vue-ui
enhanceApp.js文件作为入口(启动当前的vuepress,这个文件就是当前项目的一个入口),框架规定的,名字不能改。这个文件用于添加组件Demo展示的优化的配置。
import Vue from 'vue'; import ElementUI from 'element-ui'; // 全局引入element-ui import 'element-ui/lib/theme-chalk/index.css'; import hljs from 'highlight.js'; // 代码高亮 import 'highlight.js/styles/googlecode.css'; import xqhVueUI from 'xqh-vue-ui' // 要编写对应的文档的包 import 'xqh-vue-ui/dist/xqh-vue-ui.css' // 引入组件库样式 // 全局注册指令 Vue.directive('highlight',function (el) { let blocks = el.querySelectorAll('pre code'); blocks.forEach((block)=>{ hljs.highlightBlock(block) }) }) export default ({ Vue }) => { Vue.use(ElementUI); Vue.use(xqhVueUI) }
# 代码块
docs/.vuepress/components/demo-block.vue
像elementui那种查看例子时,可以展开代码的功能
<template>
<div class="demo-block" :class="[blockClass, { 'hover': hovering }]" @mouseenter="hovering = true" @mouseleave="hovering = false">
<div style="padding:24px">
<ClientOnly>
<slot name="source"></slot>
</ClientOnly>
</div>
<div class="meta" ref="meta">
<div class="description" v-if="$slots.default">
<slot></slot>
</div>
<div class="highlight " v-highlight>
<slot name="highlight"></slot>
</div>
</div>
<div class="demo-block-control" ref="control" @click="isExpanded = !isExpanded">
<transition name="arrow-slide">
<i :class="[iconClass, { 'hovering': hovering }]"></i>
</transition>
<transition name="text-slide">
<span v-show="hovering">{{ controlText }}</span>
</transition>
</div>
</div>
</template>
<script type="text/babel">
export default {
data () {
return {
hovering: false,
isExpanded: false,
fixedControl: false,
scrollParent: null,
langConfig: {
"hide-text": "隐藏代码",
"show-text": "显示代码",
"button-text": "在线运行",
"tooltip-text": "前往 jsfiddle.net 运行此示例"
}
};
},
mounted () {
console.log(1)
console.log(this.$slots)
},
props: {
jsfiddle: Object,
default () {
return {};
}
},
methods: {
scrollHandler () {
const { top, bottom, left } = this.$refs.meta.getBoundingClientRect();
this.fixedControl = bottom > document.documentElement.clientHeight &&
top + 44 <= document.documentElement.clientHeight;
},
removeScrollHandler () {
this.scrollParent && this.scrollParent.removeEventListener('scroll', this.scrollHandler);
}
},
computed: {
lang () {
return this.$route.path.split('/')[1];
},
blockClass () {
return `demo-${this.lang} demo-${this.$router.currentRoute.path.split('/').pop()}`;
},
iconClass () {
return this.isExpanded ? 'el-icon-caret-top' : 'el-icon-caret-bottom';
},
controlText () {
return this.isExpanded ? this.langConfig['hide-text'] : this.langConfig['show-text'];
},
codeArea () {
return this.$el.getElementsByClassName('meta')[0];
},
codeAreaHeight () {
if (this.$el.getElementsByClassName('description').length > 0) {
return this.$el.getElementsByClassName('description')[0].clientHeight +
this.$el.getElementsByClassName('highlight')[0].clientHeight + 20;
}
return this.$el.getElementsByClassName('highlight')[0].clientHeight;
}
},
watch: {
isExpanded (val) {
this.codeArea.style.height = val ? `${this.codeAreaHeight + 1}px` : '0';
if (!val) {
this.fixedControl = false;
this.$refs.control.style.left = '0';
this.removeScrollHandler();
return;
}
setTimeout(() => {
this.scrollParent = document.querySelector('.page-component__scroll > .el-scrollbar__wrap');
this.scrollParent && this.scrollParent.addEventListener('scroll', this.scrollHandler);
this.scrollHandler();
}, 200);
}
},
mounted () {
this.$nextTick(() => {
let highlight = this.$el.getElementsByClassName('highlight')[0];
if (this.$el.getElementsByClassName('description').length === 0) {
highlight.style.width = '100%';
highlight.borderRight = 'none';
}
});
},
beforeDestroy () {
this.removeScrollHandler();
}
};
</script>
<style lang="scss">
.demo-block {
border: solid 1px #ebebeb;
border-radius: 3px;
transition: 0.2s;
&.hover {
box-shadow: 0 0 8px 0 rgba(232, 237, 250, 0.6),
0 2px 4px 0 rgba(232, 237, 250, 0.5);
}
code {
font-family: Menlo, Monaco, Consolas, Courier, monospace;
}
.demo-button {
float: right;
}
.source {
padding: 24px;
}
.meta {
background-color: #fafafa;
border-top: solid 1px #eaeefb;
overflow: hidden;
height: 0;
transition: height 0.2s;
}
.description {
padding: 20px;
box-sizing: border-box;
border: solid 1px #ebebeb;
border-radius: 3px;
font-size: 14px;
line-height: 22px;
color: #666;
word-break: break-word;
margin: 10px;
background-color: #fff;
p {
margin: 0;
line-height: 26px;
}
code {
color: #5e6d82;
background-color: #e6effb;
margin: 0 4px;
display: inline-block;
padding: 1px 5px;
font-size: 12px;
border-radius: 3px;
height: 18px;
line-height: 18px;
}
}
.highlight {
pre {
margin: 0;
}
code.hljs {
margin: 0;
border: none;
max-height: none;
border-radius: 0;
line-height: 1.8;
color: black;
&::before {
content: none;
}
}
}
.demo-block-control {
border-top: solid 1px #eaeefb;
height: 44px;
box-sizing: border-box;
background-color: #fff;
border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px;
text-align: center;
margin-top: -1px;
color: #d3dce6;
cursor: pointer;
position: relative;
&.is-fixed {
position: fixed;
bottom: 0;
width: 868px;
}
i {
font-size: 16px;
line-height: 44px;
transition: 0.3s;
&.hovering {
transform: translateX(-40px);
}
}
> span {
position: absolute;
transform: translateX(-30px);
font-size: 14px;
line-height: 44px;
transition: 0.3s;
display: inline-block;
}
&:hover {
color: #409eff;
background-color: #f9fafc;
}
& .text-slide-enter,
& .text-slide-leave-active {
opacity: 0;
transform: translateX(10px);
}
.control-button {
line-height: 26px;
position: absolute;
top: 0;
right: 0;
font-size: 14px;
padding-left: 5px;
padding-right: 25px;
}
}
}
</style>
# 编写对应组件Demo和md文档
以button组件为例
docs/.vuepress/components/button/basic.vue
- 文档中就可以用
<button-basic></button-basic>
组件了
<template>
<div class="button-basic">
<x-space>
<x-button type="default">Default</x-button>
<x-button type="primary">Primary</x-button>
<x-button type="link">Link</x-button>
<x-button type="ghost">Ghost</x-button>
<x-button type="delicate">Delicate</x-button>
</x-space>
<x-space>
<x-button type="default" status="success">success</x-button>
<x-button type="default" status="info">info</x-button>
<x-button type="default" status="warning">warning</x-button>
<x-button type="default" status="danger">danger</x-button>
</x-space>
<x-space>
<x-button type="primary" status="success">success</x-button>
<x-button type="primary" status="info">info</x-button>
<x-button type="primary" status="warning">warning</x-button>
<x-button type="primary" status="danger">danger</x-button>
</x-space>
<x-space>
<x-button type="primary" shape="square">square</x-button>
<x-button type="primary" shape="square" icon="search"></x-button>
<x-button type="primary" shape="round">round</x-button>
<x-button type="primary" shape="circle" icon="edit"></x-button>
</x-space>
</div>
</template>
docs/components/button.md
- 包括组件介绍、demo引用、参数介绍、事件介绍
# Button 按钮
网页常用 button 按钮,常用于响应一个事件或处理某个逻辑。
### 基础用法
<br/>
<demo-block>
:::slot source
<button-basic></button-basic>
:::
使用`type`、`status`和`shape`属性来定义 Button 的样式。
:::slot highlight
```html
<x-space>
<x-button type="default">Default</x-button>
<x-button type="primary">Primary</x-button>
<x-button type="link">Link</x-button>
<x-button type="ghost">Ghost</x-button>
<x-button type="delicate">Delicate</x-button>
</x-space>
<x-space>
<x-button type="default" status="success">success</x-button>
<x-button type="default" status="info">info</x-button>
<x-button type="default" status="warning">warning</x-button>
<x-button type="default" status="danger">danger</x-button>
</x-space>
<x-space>
<x-button type="primary" status="success">success</x-button>
<x-button type="primary" status="info">info</x-button>
<x-button type="primary" status="warning">warning</x-button>
<x-button type="primary" status="danger">danger</x-button>
</x-space>
<x-space>
<x-button type="primary" shape="square">square</x-button>
<x-button type="primary" shape="square" icon="search"></x-button>
<x-button type="primary" shape="round">round</x-button>
<x-button type="primary" shape="circle" icon="edit"></x-button>
</x-space>
```
:::
</demo-block>
### Attributes 参数
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
| :----------- | :------------- | :------ | :------------------------------------------ | :------ |
| type | 按钮类型 | String | default / primary / link / ghost / delicate | default |
| status | 按钮状态 | String | success / info / warning / danger | default |
| shape | 按钮形状 | String | square / round / circle | square |
| size | 按钮尺寸 | String | xs / ms / md / lg | md |
| icon | 图标按钮 | String | 和图标的值一样 | — |
| iconPosition | 图标位置 | String | left / right | left |
| loading | 是否为加载状态 | Boolean | — | false |
| disabled | 是否为禁用状态 | Boolean | — | false |
### Event 事件
| 事件名 | 说明 | 回调参数 |
| :----- | :--------------- | :------------- |
| click | 按钮在点击时触发 | (event: Event) |
运行npm run docs:dev
,访问 http://localhost:1234 (opens new window) 就可以看到文档了。