从 Vue-cli 开始构建 UI 库到 Markdown 生成文档和演示案例 (2)

代码块示例

:::demo ### 描述标题 ```html <template> <img src="http://i.loli.net/2017/08/21/599a521472424.jpg" /> </template> <script> console.log(1) </script> ``` ::: ```

将示例的markdown编译成以下效果

从 Vue-cli 开始构建 UI 库到 Markdown 生成文档和演示案例

上面为代码执行示例,中间为描述信息,底部为代码示例

开发一个demo-block用于显示代码块的组件

<template> <div> <div> <slot></slot> <span v-if="!$slots.default" @click="showCode=!showCode"><img alt="expand code" src="http://gw.alipayobjects.com/zos/rmsportal/wSAkBuJFbdxsosKKpqyq.svg"></span> </div> <div v-if="$slots.default"> <slot></slot> <span v-if="$slots.default" @click="showCode=!showCode"><img alt="expand code" src="http://gw.alipayobjects.com/zos/rmsportal/wSAkBuJFbdxsosKKpqyq.svg"></span> </div> <div v-show="showCode"> <slot></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>

vue-markdown-loader依赖了highlight在App.vue的样式中引用进行代码着色,风格参照highlight.js自己引用

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

在main.js配置全局安装组件,让每个md文件都可以自动编译成 vue 组件并且渲染代码块

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

webpack.base.conf.js配置vue-markdown-loader的options属性

将demo代码块解析,在 markdown 用demo-block组件包裹

安装npm install markdown-it-container --save-dev

对 options 进行配置完成效果渲染

const markdownRender = require('markdown-it')(); { test: /\.md$/, loader: 'vue-markdown-loader', options: { 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 slot="source">${content}</div> ${descriptionHTML} <div slot="highlight">`; } else { return '</div></demo-block>\n'; } } }] ] } }

重新运行npm run dev得到预期的效果

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zgzspd.html