Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

搭建组件库文档 #4

Open
YIngChenIt opened this issue Jun 12, 2020 · 0 comments
Open

搭建组件库文档 #4

YIngChenIt opened this issue Jun 12, 2020 · 0 comments

Comments

@YIngChenIt
Copy link
Owner

YIngChenIt commented Jun 12, 2020

搭建组件库文档

12312

背景

前段时间一直在弄组件库,为了更方便同事使用组件库,文档是必须有的,所以我使用vue-press来实现我们的组件库文档,这里记录一下一些关键步骤

搭建

搭建侧边栏配置

我们在docs/.vuepress下建立config.js文件

module.exports = {
    title: 'cnhis-ui', // 设置网站标题
    description: '坐标前端组件库', //描述
    dest: './build', // 设置输出目录
    port: 1234, //端口
    themeConfig: { //主题配置
        nav: [{
                text: '主页',
                link: '/'
            }, // 导航条
        ],
        // 为以下路由添加侧边栏
        sidebar: {
            '/components/': [{
                    collapsable: true,
                    children: [
                        'input'
                    ]
                }
            ]
        }
    }
}

覆盖文档默认样式

我们在docs/.vuepress下建立styles文件夹,并且新建一个palette.styl文件

$codeBgColor = #fafafa // 代码背景颜色

$accentColor = #3eaf7c
$textColor = #2c3e50

$borderColor = #eaecef
$arrowBgColor = #ccc
$badgeTipColor = #42b983
$badgeWarningColor = darken(#ffe564, 35%)
$badgeErrorColor = #DA5961

.content pre{  margin: 0!important;}

.theme-default-content:not(.custom){
    max-width: 1000px !important;
}

封装高亮文档组件

我们在docs/.vuepress下建立components文件夹,并且新建一个demo-block.vue文件

<template>
  <div
    class="demo-block"
    :class="[blockClass, { 'hover': hovering }]"
    @mouseenter="hovering = true"
    @mouseleave="hovering = false">
    <div style="padding:24px">
        <slot name="source"></slot>
    </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>

<style lang="scss">
  .demo-block {
    border: solid 1px #ebebeb;
    border-radius: 3px;
    transition: .2s;
    &.hover {
      box-shadow: 0 0 8px 0 rgba(232, 237, 250, .6), 0 2px 4px 0 rgba(232, 237, 250, .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 .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: .3s;
        &.hovering {
          transform: translateX(-40px);
        }
      }

      > span {
        position: absolute;
        transform: translateX(-30px);
        font-size: 14px;
        line-height: 44px;
        transition: .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>

<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 运行此示例"
        }
      };
    },

    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>

注册高亮组件

我们在docs/.vuepress下建立enhanceApp.js文件

import Vue from 'vue';
import Element from 'element-ui'; // 引入elementUi
import 'element-ui/lib/theme-chalk/index.css'

import hljs from 'highlight.js'
import 'highlight.js/styles/googlecode.css' //样式文件

import cnhis from 'cnhis-ui' // 要编写对应的文档的包
import 'cnhis-ui/dist/cnhis-ui.css'
Vue.directive('highlight',function (el) {
  let blocks = el.querySelectorAll('pre code');
  blocks.forEach((block)=>{
    hljs.highlightBlock(block)
  })
})
export default ({
  Vue,
  options, 
  router,
  siteData
}) => {
  Vue.use(Element);
  Vue.use(cnhis)
}

编写每个文件的文档

我们在docs下建立components文件夹,用来存放我们全部组件的文档,这里放一下如何使用封装好的文档高亮组件来搭起来

# Input组件
量表Input组件
## 基础用法
基础的Input用法。

<demo-block>
::: slot source
<input-test1></input-test1>
:::

::: slot highlight
```html
<cnhis-input       
    title="身份证号"
    @input="e => change('idCard', e)"
    v-model="idCard"
    maxlength="18"
    placeholder="请输入身份证号"
    :required="true"></cnhis-input>
export default {
  name: "test1",
  data() {
    return {
      mobile: ""
    };
  },
  methods: {
    change(e) {
      this.$message({
        message: e,
        type: "success"
      });
    }
  }
};

:::

是否必选

是否必选用法

::: slot source :::

使用required属性来定义是否必选

::: slot highlight

<cnhis-input
    title="身份证号"
    v-model="idCard"
    placeholder="请输入身份证号"
    :required="true"
    ></cnhis-input>

:::

是否禁用

是否禁用用法

::: slot source :::

使用required属性来定义是否必选

::: slot highlight

<cnhis-input
      title="身份证号"
      v-model="idCard"
      placeholder="请输入身份证号"
      :required="true"
      :disabled="true"
    ></cnhis-input>

:::

输入最大值

输入最大值用法

::: slot source :::

使用maxlength属性来定义是否必选

::: slot highlight

<cnhis-input
    title="身份证号"
    v-model="idCard"
    placeholder="请输入身份证号"
    maxlength="18"
    :required="true"
    ></cnhis-input>

:::

参数类型

参数|说明|类型|可选值|默认值
:-|:-|:-|:-|:-|:-
maxlength|最大长度| String/Number | - | 140
placeholder|输入框默认提示|String | - | 请输入
type|输入框类型|String|-|text
title|标题|String | - | ""
disabled|禁用状态|Boolean | - | false
required|是否必选|Boolean | - | false
color|字体颜色|String | - | ""


## 总结
其实都是对`vuepress` 的一些使用方法,难点在于封装显示的高亮组件
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant