Markdown中嵌入vue語法并渲染

最近閱讀了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.獲取第一行的內(nèi)容使用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.獲取代碼塊內(nèi)的html和js代碼
                            let content = tokens[idx + 1].content;
                            // 3.使用自定義開發(fā)組件【DemoBlock】來包裹內(nèi)容并且渲染成案例和代碼示例
                            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>

引入并且全局注冊(cè)

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 按鈕

常用的操作按鈕

### 基礎(chǔ)用法 

按鈕的基礎(chǔ)用法

:::demo 通過`type`、`width`屬性設(shè)置不同類型的按鈕

```html
<template>
    <div>
        <dv-button>默認(rèn)按鈕</dv-button>
        <dv-button type="success">成功按鈕</dv-button>
        <dv-button type="warning">警告按鈕</dv-button>
        <dv-button type="danger">危險(xiǎn)按鈕</dv-button>
    </div>
    <div>
        <dv-button width="100px">默認(rèn)按鈕</dv-button>
        <dv-button type="success" width="100px">成功按鈕</dv-button>
        <dv-button type="warning" width="100px">警告按鈕</dv-button>
        <dv-button type="danger" width="100px">危險(xiǎn)按鈕</dv-button>
    </div>
</template>
\```  (去除這個(gè)斜杠)

:::

### Attributes
| 參數(shù)      | 說明    | 類型      | 可選值       | 默認(rèn)值   |
|--------|--------   |---------- |-------------  |-------- |
| type   | 類型      | string    |   success / warning / danger / |—    |
| name   | name屬性  | string    | — | —   |
| id     | id屬性    | string    | — | —   |
| width  | 按鈕寬度   | string    | — | 100%   |

效果圖

image.png

button.mdgithub上的展示效果

image.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 基于Vue的一些資料 內(nèi)容 UI組件 開發(fā)框架 實(shí)用庫 服務(wù)端 輔助工具 應(yīng)用實(shí)例 Demo示例 element★...
    嘗了又嘗閱讀 1,275評(píng)論 0 1
  • UI組件 element- 餓了么出品的Vue2的web UI工具套件 Vux- 基于Vue和WeUI的組件庫 m...
    柴東啊閱讀 15,953評(píng)論 2 140
  • UI組件 element- 餓了么出品的Vue2的web UI工具套件 Vux- 基于Vue和WeUI的組件庫 m...
    小姜先森o0O閱讀 10,096評(píng)論 0 72
  • UI組件 element- 餓了么出品的Vue2的web UI工具套件 Vux- 基于Vue和WeUI的組件庫 m...
    你猜_3214閱讀 11,332評(píng)論 0 118
  • UI組件 element- 餓了么出品的Vue2的web UI工具套件 Vux- 基于Vue和WeUI的組件庫 m...
    王喂馬_閱讀 6,578評(píng)論 1 77

友情鏈接更多精彩內(nèi)容