# vue组件编写文档如何一份代码既显示UI样式,又显示文件源代码?

# 前言


在编写组件文档的时候,需要在一个页面同时展示组件的UI样式和编写组件的源代码。


最简单的做法是写两份代码,一份展示UI,一份展示源代码,但是这样维护起来很麻烦,每次改动都要修改两份代码。


# 问题描述


有没有好方法可以在只写一份代码的情况下实现上述功能呢?


有当然是有,不过踩了一些坑。


# 问题分析


最开始我想的是通过js获取UI展示部分的代码,然后通过js创建元素,添加到文件末尾。


但是这有一个问题是,只能获取到html元素,对于script的部分不能显示,也就对整个组件的使用方法不是很清晰。


于是我就换个思路,获取整个vue文件的源代码,然后显示。


这个思路是可行的,唯一的问题是如何获取整个vue文件的源码。


# 解决方案


通过 Google 找到了一个解决方案:通过使用 ajax 来获取本地vue文件。


具体代码如下,详细步骤见注释:


function getCode(fileName) {
   let src = `/source/app/docs/${fileName}.vue`;
   /**
    * <div class="docs-code"></div> 就是展示代码的区域
    * 至于为什么加
<pre><code></code></pre>? 
    * 1、是因为高亮显示使用了 highlight.js插件,这个插件要求
<pre><code></code></pre> 之前的代码才会被高亮。
    * 2、并且因为有了pre标签,所以代码中的空格换行等格式才得以保留。
    */
   let docsCode = $('<div class="docs-code">
<pre><code></code></pre></div>');

   // 创建一个新的xhr对象
   let xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP');
   xhr.open('GET', src);
   // 指定返回的数据为纯文本格式
   xhr.responseType = 'text'; // 如果不兼容,可采用 xhr.overrideMimeType('text/plain;charset=utf-8'); 
   xhr.send();
   xhr.onreadystatechange = function () {
       if (xhr.readyState === 4 && xhr.status === 200) {
           // 将获取的vue文件源码插入到code标签中
           docsCode.find('code').text(xhr.responseText);
           // 将代码插入到vue文件尾部
           docsCode.appendTo($('.' + fileName));
           // 代码高亮显示函数
           Vue.prototype.$highlight();
       } else {
           docsCode.find('code').text('获取文件源代码失败。');
       }
   };
} 


如此,我的一份代码即可显示组件UI,亦可显示组件源代码本身。


我把代码高亮和获取封装成vue插件的形式,在每个vue组件中的mounted调用即可:


import Vue from 'vue';
import Hljs from 'highlight.js';
import 'highlight.js/styles/github.css';

let Highlight = {};
Highlight.install = function (Vue, options) {
   Vue.prototype.$highlight = () => {
       $('pre code').each(function (i, element) {
           // element.innerHTML = element.innerHTML.replace(/&/g, "&").replace(//g, ">").replace(/"/g, """).replace(/'/g, "'");
           Hljs.highlightBlock(element);
       });
   };

   // 获取docs-button.vue源代码
   Vue.prototype.$getCode = (name) => {
       let src = `/source/app/docs/${name}.vue`;
       // 有了pre可以显示源代码中的空格和换行
       let docsCode = $('<div class="docs-code">
<pre><code></code></pre></div>');

       // 创建一个新的xhr对象
       let xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP');
       xhr.open('GET', src);
       xhr.responseType = 'text';
       xhr.send();
       xhr.onreadystatechange = function () {
           if (xhr.readyState === 4 && xhr.status === 200) {
               docsCode.find('code').text(xhr.responseText);
               docsCode.appendTo($('.' + name));
               // 代码高亮显示
               Vue.prototype.$highlight();
           } else {
               docsCode.find('code').text('获取文件源代码失败。');
           }
       };
   };
};
export default Highlight; 


示例如下图:


# 参考链接