美文网首页
Markdown中嵌入vue语法并渲染

Markdown中嵌入vue语法并渲染

作者: Homary | 来源:发表于2019-04-29 13:59 被阅读0次

最近阅读了element-ui的源码才知道像这类UI库的官方说明文档都是用markdown写的.

改造webpack配置

const markdownRender = require('markdown-it')();
...
{
    test: /\.md$/,
    use: [
      {
          loader: 'vue-loader'
      },
      {
        loader: 'vue-markdown-loader/lib/markdown-compiler',
        options: { 
              raw: true,
              preventExtract: true,
             use: [
            [
                require('markdown-it-container'),
                'demo',
                {
                    validate: function(params) {
                        return params.trim().match(/^demo\s+(.*)$/);
                    },

                    render: function(tokens, idx) {
                        if (tokens[idx].nesting === 1) {
                            // 1.获取第一行的内容使用markdown渲染html作为组件的描述
                            let demoInfo = tokens[idx].info
                                .trim()
                                .match(/^demo\s+(.*)$/);
                            let description =
                                demoInfo && demoInfo.length > 1
                                    ? demoInfo[1]
                                    : '';
                            let descriptionHTML = description
                                ? markdownRender.render(description)
                                : '';
                            // 2.获取代码块内的html和js代码
                            let content = tokens[idx + 1].content;
                            // 3.使用自定义开发组件【DemoBlock】来包裹内容并且渲染成案例和代码示例
                            return `<demo-block>
            <div class="source" slot="source">${content}</div>
            ${descriptionHTML}
            <div class="highlight" slot="highlight">`;
                        } else {
                            return '</div></demo-block>\n';
                        }
                    }
                }
            ]
         }
    }]
}

添加demo-block.vue

用于包含markdown文件

<template>
  <div class="demo-block">
    <div class="demo-block-source">
      <slot name="source"></slot>
      <span class="demo-block-code-icon"
        v-if="!$slots.default"
        @click="showCode=!showCode"><img alt="expand code"
          src="https://gw.alipayobjects.com/zos/rmsportal/wSAkBuJFbdxsosKKpqyq.svg"
          class="code-expand-icon-show"></span>
    </div>
    <div class="demo-block-meta"
      v-if="$slots.default">
      <slot></slot>
      <span v-if="$slots.default"
        class="demo-block-code-icon"
        @click="showCode=!showCode"><img alt="expand code"
          src="https://gw.alipayobjects.com/zos/rmsportal/wSAkBuJFbdxsosKKpqyq.svg"
          class="code-expand-icon-show"></span>
    </div>
    <div class="demo-block-code"
      v-show="showCode">
      <slot name="highlight"></slot>
    </div>
  </div>
</template>
<script type="text/babel">

export default {
  data() {
    return {
      showCode: false
    };
  }
};
</script>
<style>
.demo-block {
  border: 1px solid #ebedf0;
  border-radius: 2px;
  display: inline-block;
  width: 100%;
  position: relative;
  margin: 0 0 16px;
  -webkit-transition: all 0.2s;
  transition: all 0.2s;
  border-radius: 2px;
}
.demo-block p {
  padding: 0;
  margin: 0;
}
.demo-block .demo-block-code-icon {
  position: absolute;
  right: 16px;
  bottom: 14px;
  cursor: pointer;
  width: 18px;
  height: 18px;
  line-height: 18px;
  text-align: center;
}
.demo-block .demo-block-code-icon img {
  -webkit-transition: all 0.4s;
  transition: all 0.4s;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
  position: absolute;
  left: 0;
  top: 0;
  margin: 0;
  max-width: 100%;
  width: 100%;
  vertical-align: baseline;
  -webkit-box-shadow: none;
  box-shadow: none;
}
.demo-block .demo-block-source {
  border-bottom: 1px solid #ebedf0;
  padding: 20px 24px 20px;
  color: #444;
  position: relative;
  margin-bottom: -1px;
}
.demo-block .demo-block-meta {
  position: relative;
  padding: 12px 50px 12px 20px;
  border-radius: 0 0 2px 2px;
  -webkit-transition: background-color 0.4s;
  transition: background-color 0.4s;
  width: 100%;
  -webkit-box-sizing: border-box;
  box-sizing: border-box;
  font-size: 14px;
  color: #444;
  font-size: 14px;
  line-height: 2;
  border-radius: 0;
  border-bottom: 1px dashed #ebedf0;
  margin-bottom: -1px;
}
.demo-block .demo-block-meta code {
  color: #444;
  background-color: #e6effb;
  margin: 0 4px;
  display: inline-block;
  padding: 3px 7px;
  border-radius: 3px;
  height: 18px;
  line-height: 18px;
  font-family: Menlo, Monaco, Consolas, Courier, monospace;
  font-size: 14px;
}
.demo-block .demo-block-code {
  background-color: #f7f7f7;
  font-size: 0;
}
.demo-block .demo-block-code code {
  background-color: #f7f7f7;
  font-family: Consolas, Menlo, Courier, monospace;
  border: none;
  display: block;
  font-size: 14px;
  padding: 16px 32px;
}
.demo-block .demo-block-code pre {
  margin: 0;
  padding: 0;
}
.sh-checkbox {
  color: #444;
  font-weight: 500;
  font-size: 14px;
  position: relative;
  cursor: pointer;
  display: inline-block;
  white-space: nowrap;
  user-select: none;
}
</style>

引入并且全局注册

import DemoBlock from './demo-block/demo-block.vue';
Vue.component('demo-block', DemoBlock);

使用highlight.js高亮

import 'highlight.js/styles/color-brewer.css';  

定义router

import Vue from 'vue';
import VueRouter from 'vue-router';

Vue.use(VueRouter);

const router = new VueRouter({
    routes: [
        {
            path: '/button',
            name: 'button',
            title: 'Button 按钮',
            component: r =>
                require.ensure([], () => r(require('ui/docs/button.md')))
        }
    ]
});

export default router;

button.md

## Button 按钮

常用的操作按钮

### 基础用法 

按钮的基础用法

:::demo 通过`type`、`width`属性设置不同类型的按钮

```html
<template>
    <div>
        <dv-button>默认按钮</dv-button>
        <dv-button type="success">成功按钮</dv-button>
        <dv-button type="warning">警告按钮</dv-button>
        <dv-button type="danger">危险按钮</dv-button>
    </div>
    <div>
        <dv-button width="100px">默认按钮</dv-button>
        <dv-button type="success" width="100px">成功按钮</dv-button>
        <dv-button type="warning" width="100px">警告按钮</dv-button>
        <dv-button type="danger" width="100px">危险按钮</dv-button>
    </div>
</template>
\```  (去除这个斜杠)

:::

### Attributes
| 参数      | 说明    | 类型      | 可选值       | 默认值   |
|--------|--------   |---------- |-------------  |-------- |
| type   | 类型      | string    |   success / warning / danger / |—    |
| name   | name属性  | string    | — | —   |
| id     | id属性    | string    | — | —   |
| width  | 按钮宽度   | string    | — | 100%   |

效果图

image.png

button.mdgithub上的展示效果

image.png

相关文章

网友评论

      本文标题:Markdown中嵌入vue语法并渲染

      本文链接:https://www.haomeiwen.com/subject/apujnqtx.html