2

近期新开项目,发现之前编写的组件不知道怎么用,要不看源码,要不就只能看以前的代码。所以找到Vue-styleguidist,把之前的组件都编写文档方便以后使用,就像看element-ui等组件库的文档一样,使大家的开发效率提升,推荐给各位。先上官方 demo 看看效果,多种样式供你选择。

起步

安装

npm安装

npm install --save-dev vue-styleguidist

如果使用的是Vue Cli,可以使用其插件

vue add styleguidist

配置你的样式风格

创建一个styleguide.config.js文件在package.json同一级目录,这个是你的配置文件,在这个文件里,你可以:

  • 指定Styleguidist到你的vue组件文件夹
  • 明确如何加载代码

如果使用了Vue cli可以跳过这个步骤。当安装vue-cli-plugin-styleguidist,styleguidist会从cli中获取相关内容,通知styleguidist组件目录

添加npm脚本方便使用

添加这些脚本到package.json:

{
  "scripts": {
     "styleguide": "vue-styleguidist server",
     "styleguide:build": "vue-styleguidist build"
  }
}

开始styleguidist

  • 运行npm run styleguide启动styleguide开发服务
  • 运行npm run styleguide:build构建一个固定版本

开始编写组件文档

编写组件文档

Vue styleguidist是基于组件源码和Readme文件中的注释声明进行生成组件文档。

代码注释

Vue styleguidist会显示组件中JSDoc注释内容

<template>
  <div class="Button">
    /* ... */
  </div>
</template>

<script>
  /**
   * The only true button.
   * @displayName Best Button
   */
  export default {
    name: 'Button',
    props: {
      /**
       * The color for the button.
       */
      color: {
        type: String,
        default: '#333'
      },
      /**
       * The size of the button
       * @values small, normal, large
       */
      size: {
        type: String,
        default: 'normal'
      },
      /**
       * Gets called when the user clicks on the button
       */
      onClick: {
        type: Function,
        default: event => {
          console.log('You have clicked me!', event.target)
        }
      }
    }
    /* ... */
  }
</script>

请注意使用了@displayName标签将该变组件名称,这是一个顶层的注释,必须出现在脚本标签export default之前。

如果组件中创建了自定义的v-model,你必须添加model标签在注释中

<script>
  export default {
    name: 'my-checkbox',
    props: {
      /**
       * @model
       */
      value: String
    }
  }
</script>

在vue组件中,对组件的prop设置限定有效值是很常见的。例如,size只能够接受smallmediumlarge。这种情况,使用@values标签。

Events

编写事件的文档,在其触发事件的代码上方添加注释。如果不紧邻触发事件的代码,将会被忽略。

在脚本块中

如果事件已经显式明确了,则不需要告诉styleguidist事件名称

/**
 * Success event.
 */
this.$emit('success')

常量也会被识别出来

/**
 * Success event.
 */
const success = 'succ'
this.$emit(success)

如果使用的事件名称从对象中取出,则需要使用@event标签

/**
 * Success event.
 *
 * @event success
 */
this.$emit(EVENTS.success)

如果时间传入的有参数或属性,使用@propety标签的描述它。也可以使用@arg或者@param

/**
 * Triggers when the number changes
 *
 * @property {number} newValue new value set
 * @property {number} oldValue value that was set before the change
 */
this.$emit('change', newValue, oldValue)

在template中

被直接用在v-on表达式中触发的事件将自动被检测到。为了更好地文档说明他们,可以在template中,在$emit被调用的代码行上面添加注释。
注释块内编写文档需要包含一行@event click。剩下的注释块那内容和在脚本中注释一样即可。
@property用来描述参数。

<div>
  <!--
    trigered on click
    @event click
    @property {object} demo - example
    @property {number} called - test called
  -->
  <button @click="$emit('click', test)"></button>
</div>

插槽slot

styleguidist将自动检测到插槽部分。在插槽前一行添加用@slot注释描述。

<template>
  <div class="modal">
    <div class="modal-container">
      <div class="modal-head">
        <!-- @slot Use this slot header -->
        <slot name="head"></slot>
      </div>
      <div class="modal-body">
        <!-- @slot Use this slot body -->
        <slot name="body"></slot>
      </div>
    </div>
  </div>
</template>

除了在给插槽添加描述外,还可以对插槽绑定的属性编写文档。这些属性使用关键字@binding
格式要求如下:

<!--
  @binding {type} BindingName description of what the bindings is meant for
  -->

一个插槽文档的例子:

<div slot-scope="row" class="list-item1">
  {{row.item.text}}
  <!--
      @slot Menu Item footer
        @binding {object} icon icon of the menu item
        @binding {string} text text of the menu item
    -->
  <slot name="test" :icon="row.item.icon" :text="row.item.text" />
</div>

包含mixinextends

如果导入了minxinextends,也将会被styledist自动添加到你的组件文档中

使用案例和Readme文件

vue styleguidist将在组件的文件夹内查找例如Readme.md{组件名}.md的文件,将其展示在你的组件文档中作为示例文档。一些使用语言标签vue,js,jsx或者javascript的代码块将被作为vue组件渲染。
如果想忽略组件的readme文件,使用@example [none] doclet。这样也能够解决多个组件在同一个文件夹内共享一个readme文件。这样将防止示例被多次渲染。

<html>
<!--在这里插入内容-->
<pre>
Vue component example:

    <Button size="large">Push Me</Button>

One more with generic code fence:

<Button size="large">Push Me</Button>

You can disable an editor by passing a noeditor modifier:

<Button>Push Me</Button>

To render an example as highlighted source code add a static modifier:

<Button>Push Me</Button>

You can also initialize vue to construct more complex examples in two ways:

  1. Create a new Vue instance
const names = require('dog-names').all;

new Vue({
  data(){
    return {
      list: names
    }
  },
  template: `
    <div>
      <RandomButton :variants="list" />
    </div>
  `
})
  1. Single-file components with a language tag of vue (supports <style scoped>)
  <template>
    <div class="wrapper">
      <Button id="dog-name-button" @click.native="pushButton">Push Me</Button>
      <hr />
      <p class="text-name">Next Dog Name: </p>
    </div>
  </template>

  <script>
    const dogNames = require('dog-names').all;

    // You can also use 'exports.default = {}' style module exports.
    export default {
      data() {
        return { numClicks: 0, dogName: dogNames[0] };
      },
      methods: {
        pushButton() {
          this.numClicks += 1;
          this.dogName = dogNames[this.numClicks];
        }
      }
    }
  </script>

  <style scoped>
    .wrapper {
      background: blue;
    }
    .text-name {
      color: red;
    }
  </style>

Examples with all other languages are rendered only as highlighted source code, not an actual component:

<Button size="large">Push Me</Button>

Any Markdown is allowed _here_.
</pre>
</html>

你也可以添加自定义代码块<docs></docs>*.vue文件中,这样vue styleguidist也会创建描述文件。

使用注释添加外部示例

使用@example注释,添加外部示例文件。下面这个例子就是加载extra.examples.md文件的示例:

/**
 * Component is described here.
 *
 * @example ./extra.examples.md
 */
export default {
  name: 'Button'
  // ...
}

忽略示例文件

也可以使用@example来忽略关联到readme文件,这样能够防止多次渲染示例文。

/**
 * Component is described here.
 *
 * @example [none]
 */
export default {
  name: 'Button'
  // ...
}

公共方法

默认的组件中methods中的方法被视为私有的,是不会被公开的。可以使用JSDoc中@public标签让方法视为公开,并展示在文档中。

/**
 * Insert text at cursor position.
 *
 * @param {string} text
 * @public
 */
insertAtCursor(text) {
  // ...
}

忽略props

默认情况下,组件中的所有属性props被认为是公开发的。在极少数情况下,想要只在文档中的移除部分属性说明。为此,可以使用JSDoc的@ignore标签注释在属性前面,用于标记在文档中移除它。

  props: {
    /**
    * @ignore
    */
    color: {
      type: String,
      default: '#333'
    }

使用JSDoc标签

在编写组件、属性或方法文档时,可以使用以下JSDoc标签

  • @deprecated
  • @seelink
  • @author
  • @since
  • @version

displayName

除上面这些标签以外,可以使用@displayName来该变组件在你的文档中显示的名称。但是看到他的名称被修改后,你在调用使用时,也需要使用被命名的名称,名称中的空格和符号在使用时不需要。举个例子,如果展示的名称被修改:

/**
 * @displayName Wonderful Button
 **/

要在示例中引用它时,就需要使用<WonderfulButton/>

方法的注释

当编写方法的文档时,你可以使用:

  • @param@arg@argument
  • @event
  • @public
<template>
  <!-- -->
</template>

<script>
  /**
   * The only true button.
   * @version 1.0.1
   */
  export default {
    name: 'Button',
    props: {
      /**
       * The color for the button.
       * @see See [Wikipedia](https://en.wikipedia.org/wiki/Web_colors#HTML_color_names)
       * @see See [MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value) for a list of color names
       */
      color: {
        type: String,
        default: '#333'
      },
      /**
       * The size of the button
       * `small, normal, large`
       * @since Version 1.0.1
       */
      size: {
        type: String,
        default: 'normal'
      },
      /**
       * Gets called when the user clicks on the button
       */
      onClick: {
        type: Function,
        default: event => {
          console.log('You have clicked me!', event.target)
        }
      }
    },
    methods: {
      /**
       * Gets called when the user clicks on the button
       *
       * @param {SyntheticEvent} event The react `SyntheticEvent`
       * @param {Number} num Numbers of examples
       * @public This is a public method
       */
      launch(event, num) {
        /* ... */
      },
      // ...
      ignoreMethod() {
        /**
         * Success event.
         *
         * @event success
         * @type {object}
         */
        this.$emit('success', {})
      }
    }
    /* ... */
  }
</script>

组合组件

列表组件或者表格组件常常需要写成一个组合的api。例如,一个下拉菜单可读性强的编写方法是

<DropDown>
  <Choice val="1">value 1</Choice>
  <Choice val="2">value 2</Choice>
</DropDown>

要优于使用属性

<DropDown :choices="[{val:1,text:'value 1'}, {val:2,text:'value 2'}]"/>

vue styleguidist提供编写这种情况的方式:在主组件中添加@require。现在这个下拉菜单的组件是这样:

<template>
  <select>
    <slot />
  </select>
</template>
<script>
/**
 * @requires ./Choice.vue
 */
export default {
  name: 'DropDown'
}
</script>

定位你的组件并组织你的文档样式

相关配置将会在styleguidist.config.js中进行编写。

定位组件

styleguidist使用glob pattern匹配查询你的组件,默认情况下,查询的是src/components/**/*.vue。下面这个例子,能够检测到如src/components/Button/Button.vue.

module.exports = {
  components: 'src/components/**/[A-Z]*.vue'
}

但不会监测同时文件夹__tests__

注意:所有的路径都是对配置文件的相对路径。
注意:使用getComponentPathLine配置项将该变组件文档下显示的组件路径。
提示:使用ignore配置项可能排除你不想在文档中看到的文件。

加载和暴露组件

styleguidist默认情况下在你文档的示例展示中加载你的组件并暴露给全局。如果不想因此造成全局污染,可以使用locallyRegisterCompenents,这样就能保证你的组件只在该组件的ReadMe.md文件和<docs>块中注册。

分组

给你的组件进行分组在文档中展示。每个分组都包含以下部分(所有的字段都是可选的):

  • name——分组标题
  • content——包含分组概述内容Markdown文件的路径
  • components——这个和根节点下components配置项相同,可以为一个或多个glob pattern字符串,组件路径数组,或者是个返回组件路径数组或golb pattern字符串数组的函数。
  • sections——子分组的数组(支持循环嵌套)
  • exampleMode——文档中代码示例的标签初始化状态,决定是否展开。
  • usageMode——文档中属性和方法的标签初始化状态,决定是否展开
  • ignore——不应包含在分组中文件路径的glob pattern的字符串或数组
  • href——一个导航路径
  • external——如果设置,连接将在新窗口打开

张淼
422 声望23 粉丝