• VitePress全局组件封装


    前言

    VuePress 主题默认有 <CodeGroup> 组件用于切换代码很方便。
    如图所示:
    image

    痛点

    使用 VitePress 后,官方没有提供 <CodeGroup> 组件类似的方案。

    参考 VuePress 源码

    https://github.com/vuejs/vuepress/blob/38e98634af117f83b6a32c8ff42488d91b66f663/packages/%40vuepress/theme-default/global-components/CodeGroup.vue

    自己封装 CodeGroup

    项目下新建全局组件:components\CodeGroup.vue
    实现代码如下:

    <template>
      <ClientOnly>
        <div class="theme-code-group">
          <div class="theme-code-group__nav">
            <ul class="theme-code-group__ul">
              <li
                v-for="(tab, i) in codeTabs"
                :key="tab.title"
                class="theme-code-group__li"
              >
                <button
                  class="theme-code-group__nav-tab"
                  :class="{
                    'theme-code-group__nav-tab-active': i === activeCodeTabIndex,
                  }"
                  @click="changeCodeTab(i)"
                >
                  {{ tab.title }}
                </button>
              </li>
            </ul>
          </div>
          <slot />
          <pre v-if="codeTabs.length < 1" class="pre-blank"> // 没代码~ </pre>
        </div>
      </ClientOnly>
    </template>
    
    <script>
    export default {
      name: 'CodeGroup',
      data() {
        return {
          codeTabs: [],
          activeCodeTabIndex: -1,
        }
      },
      watch: {
        activeCodeTabIndex(index) {
          this.activateCodeTab(index)
        },
      },
      mounted() {
        this.loadTabs()
      },
      methods: {
        changeCodeTab(index) {
          this.activeCodeTabIndex = index
        },
        async loadTabs() {
          await this.$nextTick()
          this.codeTabs = (this.$slots.default() || [])
            .filter(slot => Boolean(slot.props))
            .map((slot, index) => {
              if (slot.props.active === '') {
                this.activeCodeTabIndex = index
              }
    
              return {
                title: slot.props.title,
                elm: slot.el,
              }
            })
    
          if (this.activeCodeTabIndex === -1 && this.codeTabs.length > 0) {
            this.activeCodeTabIndex = 0
          }
    
          this.activateCodeTab(0)
        },
        activateCodeTab(index) {
          this.codeTabs.forEach(tab => {
            if (tab.elm) {
              tab.elm.style.display = 'none'
            }
          })
    
          if (this.codeTabs[index]?.elm) {
            this.codeTabs[index].elm.style.display = 'block'
          }
        },
      },
    }
    </script>
    
    <style scoped>
    /* .theme-code-group {} */
    .theme-code-group__nav {
      margin-bottom: -35px;
      background-color: #282c34;
      padding-bottom: 22px;
      border-radius: 6px;
      padding-left: 10px;
      padding-top: 10px;
    }
    .theme-code-group__ul {
      margin: auto 0;
      padding-left: 0;
      display: flex;
      list-style: none;
    }
    .theme-code-group__li {
      margin-top: 0;
      margin-right: 10px;
    }
    .theme-code-group__nav-tab {
      border: 0;
      padding: 5px;
      cursor: pointer;
      background-color: transparent;
      font-size: 0.85em;
      line-height: 1.4;
      color: rgba(255, 255, 255, 0.9);
      font-weight: 600;
    }
    .theme-code-group__nav-tab-active {
      border-bottom: #42b983 1px solid;
    }
    .pre-blank {
      color: #42b983;
      margin: 0;
    }
    </style>
    
    

    全局注册组件

    新建主题配置文件:docs\.vitepress\theme\index.js
    VitePress 中注册全局组件:

    import DefaultTheme from 'vitepress/theme'
    import CodeGroup from '../../../components/CodeGroup.vue'
    
    export default {
      ...DefaultTheme,
      enhanceApp({ app }) {
        app.component('CodeGroup', CodeGroup)
      }
    }
    

    在 md 文档中使用

    注意:由于语法限制,以下代码统一缩进了一个 Tab 制表符,在使用时请删除 Tab 制表符。

    	# CodeGroup 自定义全局组件
    
    	## 测试 JS + TS
    
    	<CodeGroup>
    	  <div title="ts" active>
    
    	```ts{2}
    	// 注释
    	const add = (a: number, b: number): number => {
    	  return a + b
    	}
    	console.log(add(1, 2))
    	```
    
    	  </div>
    	  <div title="js">
    
    	```js{2}
    	// 注释
    	const add = (a, b) => {
    	  return a + b
    	}
    	console.log(add(1, 2))
    	```
    
    	  </div>
    	</CodeGroup>
    
    	## 测试 yarn + npm + pnpm 
    
    	<CodeGroup>
    	  <div title="yarn" active>
    
    	```sh
    	# install in your project
    	yarn add -D vitePress
    	```
    
    	  </div>
    	  <div title="npm">
    
    	```sh
    	# install in your project
    	npm install -D vitePress
    	```
    
    	  </div>
    	  <div title="pnpm">
    
    	```sh
    	# install in your project
    	pnpm install -D vitePress
    	```
    
    	  </div>
    	</CodeGroup>
    

    效果预览

    image

  • 相关阅读:
    [OS] 修改屏幕分辨率(用Remote Desktop Connection 或者 用工具:Remote Desktop Connection Manager)
    英文单词通用缩写表
    [Selenium] 怎样判断是否适合自动化测试
    [Selenium] Java代码获取,设置屏幕分辨率
    [Selenium] Java代码获取屏幕分辨率
    [Selenium] 最大化或自定义浏览器的大小
    跟我一起玩Win32开发(7):多边形窗口
    跟我一起玩Win32开发(5):具有单选标记的菜单
    跟我一起玩Win32开发(6):创建右键菜单
    跟我一起玩Win32开发(4):创建菜单
  • 原文地址:https://www.cnblogs.com/Megasu/p/16495251.html
Copyright © 2020-2023  润新知