npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

vue-ui-docs

v1.2.0

Published

vue 2.x 组件库自动解析 Markdown 示例,自动构建发布到 `github-pages` 和 `npm`

Readme

VUE-UI-DOCS

vue 2.x 组件库自动解析 Markdown 示例,自动构建发布到 github-pagesnpm

旧版本代码

实现目标

代码示例格式:

:::snippet 通过 `v-button` 标签初始化按钮。

```html
<template>
  <div>
    <v-button>Default</v-button>
  </div>
</template>
```

:::

解析示例渲染:

代码解析示例

创建项目

  1. 全局安装 Vue CLI 更多内容查看官方文档
npm install -g @vue/cli
  1. vue ui 可视化操作,也可以通过 vue crate {project}
vue ui

启动CLI

  1. 创建项目

创建项目

  1. 预设配置

预设配置

  1. 手动配置

手动配置

  1. 详细配置

详细配置

  1. 安装依赖

安装依赖

  1. 启动项目

启动项目

  1. 访问地址

访问地址

  1. 浏览器访问

浏览器访问

结构调整

  1. 文件结构调整
├─site          //示例网站目录
│ └─components  //示例网站组件
│ └─router      //路由配置
│ │ └─index.js  //路由配置文件
│ └─views       //示例页面
│ │ └─Home.vue  //示例网站首页
│ └─App.vue     //项目入口
│ └─main.js     //启动文件
├─src           //源码目录
  1. 根目录创建 vue.config.js 配置
module.exports = {
  pages: {
    index: {
      entry: "site/main.js"
    }
  }
};
  1. 相关的依赖、路由配置进行调整,Home.vue 页面调整
<template>
  <h1>Home</h1>
</template>

<script>
export default {
  name: "Home"
};
</script>
  1. 页面访问

页面访问

组件开发

  1. Button 组件开发
<template>
  <button v-bind="$attrs" class="v-button" type="button" @click="handleClick">
    <span class="v-buttov--text">
      <slot>{{ text }}</slot>
    </span>
  </button>
</template>

<script>
  export default {
    name: "VButton",
    props: {
      text: String
    },
    methods: {
      handleClick(event) {
        this.$emit("click", event);
      }
    }
  };
</script>

<style lang="scss">
  .v-button {
    position: relative;
    display: inline-block;
    font-weight: 400;
    white-space: nowrap;
    text-align: center;
    background-image: none;
    border: 1px solid #41a259;
    background-color: #41a259;
    box-shadow: 0 2px 0 rgba(0, 0, 0, 0.015);
    transition: all 0.3s;
    user-select: none;
    height: 32px;
    min-width: 88px;
    padding: 0 16px;
    font-size: 14px;
    border-radius: 4px;
    color: #ffffff;
    outline: 0;
    font-family: inherit;
    cursor: pointer;

    &:active,
    &:focus {
      outline: 0;
    }
  }
</style>
  1. 安装配置 src/button/index.js
import Button from "./src/button";

Button.install = Vue => {
  Vue.component(Button.name, Button);
};

export default Button;
  1. 组件集成安装 src/index.js
import Button from "./button/index.js";

const components = [Button];

const install = Vue => {
  components.forEach(component => {
    Vue.use(component);
  });
};

export default {
  install
};
  1. 入口文件引入 site/main.js
import VueUIDocs from "../src/index";
Vue.use(VueUIDocs);

文档解析

  1. 文档示例组件开发 site/components/snippet.vue ,并且在 site/main.js 使用 Vue.component 全局注册
<template>
  <div class="vc-snippet">
    <div class="vc-snippet--demo">
      <!-- 代码生成vue示例 -->
      <slot name="source" />
    </div>
    <div class="vc-snippet--desc">
      <!-- 示例描述说明 -->
      <slot name="desc" />
      <span class="vc-snippet--icon-code" @click="showCode = !showCode">
        <img alt="code" :src="codeIconSrc" />
      </span>
    </div>
    <div v-show="showCode" class="vc-snippet--code">
      <!-- 示例代码高亮显示 -->
      <slot name="code" />
    </div>
  </div>
</template>

<script>
  import "highlight.js/styles/color-brewer.css";

  export default {
    data() {
      return {
        showCode: false
      };
    },
    computed: {
      codeIconSrc() {
        return this.showCode
          ? "https://gw.alipayobjects.com/zos/rmsportal/wSAkBuJFbdxsosKKpqyq.svg"
          : "https://gw.alipayobjects.com/zos/rmsportal/wSAkBuJFbdxsosKKpqyq.svg";
      }
    }
  };
</script>

<style lang="scss" scoped>
  .vc-snippet {
    position: relative;
    box-sizing: border-box;
    width: 100%;
    margin: 0 0 16px;
    border-radius: 4px;
    transition: all 0.2s;
    box-shadow: 0 6px 12px -2px rgba(0, 32, 128, 0.1), 0 0 0 1px #f0f2f7;
    background-color: #ffffff;
    text-align: left;
    margin-bottom: 30px;
  }

  .vc-snippet--demo {
    box-sizing: border-box;
    padding: 30px 35px;
    color: #333333;
    border-bottom: 1px solid #ebedf0;
    font-size: 12px;
  }

  .vc-snippet--desc {
    position: relative;
    box-sizing: border-box;
    width: 100%;
    min-height: 44px;
    padding: 10px 50px 10px 20px;
    font-size: 14px;
    transition: background-color 0.4s;
    line-height: 1.8;

    code {
      background: #e6effb;
      border-radius: 3px;
      color: #5e6d82;
      padding: 2px 8px;
    }
  }

  .vc-snippet--icon-code {
    position: absolute;
    right: 16px;
    bottom: 13px;
    width: 18px;
    height: 18px;
    line-height: 18px;
    text-align: center;
    cursor: pointer;

    > img {
      width: 18px;
      height: 18px;
    }
  }
  .vc-snippet--code {
    box-sizing: border-box;
    border-top: 1px solid #ebedf0;

    /deep/ {
      code {
        background: #f9f9f9;
        font-family: Consolas, Menlo, Courier, monospace;
        border: none;
        display: block;
        font-size: 14px;
        padding: 16px 32px;
        line-height: 1.5;
      }

      .hljs {
        padding: 0;
        margin: 0;
      }
    }
  }
</style>
  1. build/markdown-loader.js 解析 marokdown 为 vue 文件,并且自定义解析代码块 :::snippet {content} :::
const MarkdownIt = require("markdown-it");
const MarkdownItContainer = require("markdown-it-container");
const VueTemplateComplier = require("vue-template-compiler");
const hljs = require("highlight.js");
const { parse, compileTemplate } = require("@vue/component-compiler-utils");

module.exports = function(source) {
  // 需要解析成vue代码块集合
  const componentCodeList = [];
  let styleCodeList = [];
  const globalScript = [];
  // 初始还MarkdownIt用于转换md文件为html
  const markdownIt = MarkdownIt({
    html: true,
    xhtmlOut: true,
    // 将markdown中的代码块用hljs高亮显示
    highlight: function(str, lang) {
      if (lang && hljs.getLanguage(lang)) {
        return `<pre class="hljs"><code>${
          hljs.highlight(lang, str, true).value
        }</code></pre>`;
      }
      return `<pre class="hljs"><code>${markdownIt.utils.escapeHtml(
        str
      )}</code></pre>`;
    }
  });
  // 解析【:::tip:::】
  markdownIt.use(MarkdownItContainer, "tip");
  // 解析【:::warning:::】
  markdownIt.use(MarkdownItContainer, "warning");
  // 使用【markdown-it-container】插件解析【:::snippet :::】代码块为vue渲染
  markdownIt.use(MarkdownItContainer, "snippet", {
    // 验证代码块为【:::snippet :::】才进行渲染
    validate(params) {
      return params.trim().match(/^snippet\s*(.*)$/);
    },
    // 代码块渲染
    render(tokens, index) {
      const token = tokens[index];
      const tokenInfo = token.info.trim().match(/^snippet\s*(.*)$/);
      if (token.nesting === 1) {
        // 获取snippet第一行的表述内容
        const desc = tokenInfo && tokenInfo.length > 1 ? tokenInfo[1] : "";
        // 获取vue组件示例的代码
        const nextIndex = tokens[index + 1];
        let content = nextIndex.type === "fence" ? nextIndex.content : "";
        if (!/^<template>/.test(content)) {
          content = `<template><div>${content}</div></template>`;
        }

        // 将content解析为vue组件基本属性对象;
        let { template, script, styles } = parse({
          source: content,
          compiler: VueTemplateComplier,
          needMap: false
        });
        styleCodeList = styleCodeList.concat(styles);
        // 将template的转为render函数
        const { code } = compileTemplate({
          source: template.content,
          compiler: VueTemplateComplier
        });
        // 获取script的代码
        script = script ? script.content : "";
        if (script) {
          const [global, content] = script.split(/export\s+default/);
          globalScript.push(global.trim());
          script = `const exportJavaScript = ${content}`;
        } else {
          script = "const exportJavaScript = {};";
        }
        // 代码块解析将需要解析vue组件的存储,渲染html用组件名称替代
        const name = `vc-snippent-${componentCodeList.length}`;
        // 渲染组件代码添加到数据集合
        componentCodeList.push(`"${name}":(function () {
          ${code}
          ${script}
           return {
             ...exportJavaScript,
             render,
             staticRenderFns
          }
        })()`);
        // 将需要渲染的示例用vc-snippet组件包裹替换插槽显示示例效果
        return `<vc-snippet>
                  <div slot="desc">${markdownIt.render(desc)}</div>
                  <${name} slot="source" />
                  <div slot="code">`;
      }
      return `    </div>
                </vc-snippet> `;
    }
  });
  // 将所有转换好的代码字符串拼接成vue单组件template、script、style格式
  return `
        <template>
          <div class="vc-snippet-doc">
            ${markdownIt.render(source)}
          </div>
        </template>
        <script>
           ${globalScript.join(" ")}
           export default {
           name: 'vc-component-doc',
           components: {
            ${componentCodeList.join(",")}
           }
         }
       </script>
       <style lang='scss'>
         ${Array.from(styleCodeList, m => m.content).join("\n")}
       </style>`;
};
  1. vue.config.js 配置 webpack 加载器解析 .md 文件
module.exports = {
  pages: {
    index: {
      // 入口文件
      entry: "site/main.js"
    }
  },
  chainWebpack: config => {
    // 解析Markdown文件转成vue组件
    config.module
      .rule("md")
      .test(/\.md/)
      .use("vue-loader")
      .loader("vue-loader")
      .options({
        compilerOptions: {
          preserveWhitespace: false
        }
      })
      .end()
      .use("markdown-loader")
      .loader(require("path").resolve(__dirname, "./build/markdown-loader.js"))
      .end();
  }
};
  1. 文档编写 src/button/index.md
# Button 按钮

按钮用于开始一个即时操作。

## 基础用法

:::snippet 通过 `v-button` 标签初始化按钮。

```html
<template>
  <div>
    <v-button>Default</v-button>
  </div>
</template>
```

:::

## 文本设置

:::snippet 通过 `text` 设置按钮文本。

```html
<template>
  <div>
    <v-button text="Default"></v-button>
  </div>
</template>
```

:::

## 事件绑定

:::snippet 绑定 `click` 事件。

```html
<template>
  <div>
    <v-button text="Default" @click="handleButtonClick"></v-button>
  </div>
</template>

<script>
  export default {
    methods: {
      handleButtonClick() {
        alert(1);
      }
    }
  };
</script>
```

:::

## Button Attributes

| 参数 | 说明     | 类型   | 可选值 | 默认值 |
| ---- | -------- | ------ | ------ | ------ |
| text | 按钮文本 | String | —      | —      |

## Button Events

| 事件名称 | 说明     | 回调参数 |
| -------- | -------- | -------- |
| click    | 单击触发 | event    |

## Button Slots

| 名称 | 说明     |
| ---- | -------- |
| —    | 按钮内容 |
  1. 路由配置
 ...
 {
   path: "/component/button",
   name: "component-button",
   component: () => import("../../src/button/index.md")
 }
 ...
  1. 浏览器访问

代码示例

Travis 自动构建

  1. Github 授权配置 https://github.com/settings/tokens 并且记录 GITHUB_TOKEN 的值

GITHUB_TOKEN

  1. NPM 创建一个 token 授权码,记录该授权码

NPM_TOKEN

  1. githbub 授权访问 https://www.travis-ci.org

Travis 开启项目

  1. Travis 环境变量设置

| 变量 | 描述 | | :----------- | :---------------------- | | GITHUB_TOKEN | Github 生成的授权 Token | | NPM_EMAIL | NPM 注册邮箱 | | NPM_TOKEN | NPM 授权 Token |

Travis 环境变量

  1. 构建配置文件 .travis.yml 具体配置参考 https://docs.travis-ci.com
# 编译环境
language: node_js

# Node 版本
node_js:
  - "10"

# 安装依赖
install:
  - npm install

# 代码编译
script:
  - npm run build
  - npm run release

# 发布配置
deploy:
  # 发布到 gh-pages
  - provider: pages
    local_dir: dist
    skip_cleanup: true
    github_token: $GITHUB_TOKEN
    keep_history: true
    on:
      branch: master
  # 发布到 npm
  - provider: npm
    email: $NPM_EMAIL
    api_key: $NPM_TOKEN
    skip_cleanup: true
    on:
      tags: true
      branch: master
  1. 项目构建 vue.config.js
// vue.config.js 部署路径调整
...
publicPath: process.env.NODE_ENV !== "production" ? "/" : "/vue-ui-docs",
...
// site/router/index.js 路由调整
...
base: process.env.NODE_ENV !== "production" ? "/" : "/vue-ui-docs",
...
  1. package.json 添加 script 打包发布指令
...
"release": "vue-cli-service build --dest lib --target lib src/index.js",
...
  1. Git 新增标签 v1.0.0 提交推送代码,触发自动构建

Travis 自动构建

  1. Github-Pages 访问 https://kitorv.github.io/vue-ui-docs

Github 示例

  1. NPM 安装包 https://www.npmjs.com/package/vue-ui-docs

NPM 安装包