美文网首页
vuepress中实现代码折叠、高亮

vuepress中实现代码折叠、高亮

作者: Adoins | 来源:发表于2019-06-24 13:27 被阅读0次

    最近在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

    相关文章

      网友评论

          本文标题:vuepress中实现代码折叠、高亮

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