vuepress中实现代码折叠、高亮

最近在vuepress中撰写UI框架文档时发现在组件中插入演示代码没高亮,虽然在文档markdown中写代码有高亮但就无法实现折叠了,而且vuepress没有提供折叠代码的配置,因此实现一个折叠组件外加代码高亮的插件就十分有必要。

一、编写代码折叠mixin.js

/docs/.vuepress下创建mixin.js文件,编写代码折叠逻辑。

export default {
  data () {
    return {
      //每一个区域的高度
      codeParent: [],
      codeHeightArr: [],
      //每个区域的显示状态
      isShow: [],
    }
  },
  methods: {
    //根据子元素的高度 设置代码区域父元素的高度
    showCode (index) {
      this.$set(this.isShow, index, !this.isShow[index])
      this.$nextTick(() => {
        if (this.isShow[index] === true) {
          this.codeParent[index].style.height = +this.codeHeightArr[index] + 25 + 'px'
        } else {
          this.codeParent[index].style.height = 0
        }
      })
    },
    //得到所有代码区域的高度
    getCodesHeight () {
      const arr = document.getElementsByClassName('code-content-height')
      this.codeParent = document.getElementsByClassName('code-content')
      const arrLength = arr.length
      for (let i = 0; i < arrLength; i++) {
        this.codeHeightArr.push(arr[i].getBoundingClientRect().height)
        this.isShow.push(false)
      }
    },
  },
  mounted () {
    //异步获取当前组件内部 code区域的高度 以便于给点击的时候使用
    this.$nextTick(() => {
      this.getCodesHeight()
    })
  },
}

同目录下创建enhanceApp.js这里引入折叠代码的相关css应用于全局

import './public/index.scss'
export default ({
                  Vue, // VuePress 正在使用的 Vue 构造函数
                  // options, // 附加到根实例的一些选项
                  // router, // 当前应用的路由实例
                  // siteData // 站点元数据
                }) => {
// ...做一些其他的应用级别的优化
}

/doc/.vuepress/public创建index.scss

.theme-container.sidebar-open .sidebar {
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
  border: 0;
}
.sidebar, .navbar {
  z-index: 10000;
}

.component-wrapper {
  border: 1px solid #ebebeb;
  border-radius: 3px;
  transition: .2s;

  .component-wrapper-demo {
    padding: 24px 24px 15px 24px;
  }

  h4 {
    margin: 55px 0 20px;
  }

  &:hover {
    .lock-code .lock-code-word {
      font-size: 14px;
      transform: translateX(-40px);
      opacity: 1;
    }

    .lock-code .icon-down {
      transform: translateX(-40px);
    }

    box-shadow: 0 0 8px 0 rgba(232, 237, 250, .6), 0 2px 4px 0 rgba(232, 237, 250, .5);
  }

  .code-content {
    background-color: #fafafa;
    border-top: 1px solid #eaeefb;
    overflow: hidden;
    transition: height .2s;

    .code-content-height {
      .code-user-desc {
        background: #ffffff;
        margin: 10px 10px 0 10px;
        padding: 5px 10px;
        font-size: 14px;
        line-height: 26px;
        border: 1px solid #ebebeb;
        border-radius: 3px;
      }

      > pre {
        background: none;

        > code {
          color: #3182bd;
        }
      }
    }
  }

  .lock-code {
    border-top: 1px solid #eaeefb;
    height: 44px;
    box-sizing: border-box;
    background-color: #fff;
    border-bottom-left-radius: 4px;
    border-bottom-right-radius: 4px;
    text-align: center;
    margin-top: -1px;
    color: #d3dce6;
    cursor: pointer;
    position: relative;
    line-height: 44px;
    color: #d3dce6;

    &:hover {
      background-color: #f9fafc;

      .lock-code-word {
        color: #409eff;
      }

      .icon-down {
        fill: #409eff;
      }
    }

    .icon-down {
      transform: translateX(0px);
      transition: all .1s;
    }

    text-align: center;

    .lock-code-word {
      font-size: 0px;
      margin-left: 15px;
      display: inline-block;
      transition: all .1s;
      opacity: 0;
    }
  }
}

::-webkit-scrollbar {
  width: 8px;
  background-color: #f5f5f5;
}

::-webkit-scrollbar-thumb {
  border-radius: 6px;
  background-color: #ccc;
}

::-webkit-scrollbar-track {
  border-radius: 6px;
  background-color: #f5f5f5;
}

之后便可以在文件中使用啦,/docs/.vuepress/components下创建demo.vue

<template>
  <div class="demo">
    <h2>创建组件文档模板</h2>
    <p>组件描述</p>
    <h3>组件功能名字</h3>
    <p>组件功能描述</p>
    <div class="component-wrapper">
      <div class="component-wrapper-demo">
        组件展示位置
      </div>
      <div class="code-content" style="height: 0;">
        <div class="code-content-height">
          <!-- <div class="code-user-desc">
            组件描述说明
          </div> -->
          <pre><code class="vue">{{codeStr}}</code></pre>
        </div>
      </div>
      <div class="lock-code" @click="showCode(0)" ref="xxx">
        <w-icon class="icon-down" :name="isShow[0] === false ? 'down' : 'up'"></w-icon>
        <span class="lock-code-word">{{isShow[0] === false ? '显示代码' : '隐藏代码'}}</span>
      </div>
    </div>

    <h3>attributes</h3>
    <p>组件参数说明后期扩展</p>
  </div>
</template>

<script>
  import WIcon from '../../../src/icon/icon'
  import mixin from '../mixin'
  export default {
    name: 'demo',
    mixins: [mixin],
    components: {
      WIcon,
    },
    data() {
      return {
        codeStr: `
          <g-button>默认按钮</g-button>
        `.replace(/^\s*/gm, '').trim(),
      }
    }
  }
</script>

<style lang="scss" scoped>

</style>

文档配置中引入此组件展示即可,效果如图:

image

可点击显示隐藏代码

二、高亮代码

在组件中插入代码想使得代码语法高亮可以用highlight插件

1. 安装

yarn add -D highlight.js

2. 全局引入

enhanceApp.js中 引入highlight插件,这里使用与element-ui一样的color-brewer主题

import './public/index.scss'
//代码高亮文件引入
import Vue from 'vue'
import hljs from 'highlight.js'
//样式文件,这里我选的是sublime样式,文件里面还有其他样式可供选择
import 'highlight.js/styles/color-brewer.css' 
Vue.directive('highlight',function (el) {
  let blocks = el.querySelectorAll('pre code');
      blocks.forEach((block)=>{
      hljs.highlightBlock(block)
  })
})
export default ({
                  Vue, // VuePress 正在使用的 Vue 构造函数
                  // options, // 附加到根实例的一些选项
                  // router, // 当前应用的路由实例
                  // siteData // 站点元数据
                }) => {
// ...做一些其他的应用级别的优化
}

3. 使用

之后在包装代码的外层div加上v-highlight指令,并在code标签标明代码模板类型为html/javascript/css

      <div class="code-content" v-highlight style="height: 0;">
        <div class="code-content-height">
          <!-- <div class="code-user-desc">
            组件描述说明
          </div> -->
          <pre><code class="html">{{codeStr}}</code></pre>
        </div>
      </div>

4. 效果

image

仿element-ui的风格,其他主题可以到highlight的官方文档中寻找highlight​github.com

总结

这是本人用vuepress写的UI框架文档,可供参考.🚲 EchoWheel UI​zyqq.github.io

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,047评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,807评论 3 386
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,501评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,839评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,951评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,117评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,188评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,929评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,372评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,679评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,837评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,536评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,168评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,886评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,129评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,665评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,739评论 2 351

推荐阅读更多精彩内容

  • 前言 从 9 月份开始,vuepress 源码进行了重新设计和拆分。先是开了个 next 分支,后来又合并到 ma...
    云峰yf阅读 3,110评论 0 2
  • 原创《有暖阳的冬天》发表在《中国安全生产报》“副刊”栏目20150205 今年的冬天不冷,我几乎找不到记忆...
    络浅微阅读 114评论 0 1
  • 如果我是风,你恰好是冬天,那我会悄悄的路过;如果我是风,你恰好是秋天,我会迎面对你说:幸会!
    三里春风三里路阅读 412评论 0 1
  • How many roads must a man walk down, Before you call h...
    eryoung2阅读 214评论 0 0
  • 面对我 日渐消退的记忆 我不知所措 我不知该给自己 还是给岁月 一记耳光 把云霄响彻 是给岁月 还是自己 我忘了
    微雨凭栏阅读 182评论 0 2