在VitePress中实现内联Vue组件

本文同步在个人博客shymean.com上,欢迎关注

由于掘金上面不支持mdx,所以部分演示功能会有问题,可以移步原文章

VitePress默认就支持在markdown中使用Vue组件,唯一的缺点是需要单独将SFC组件文件引入。

本文将探究一种新的方式,直接在markdown文档中编写Vue组件。

背景

VitePress默认执行在markdown文件中使用vue组件,参考文档:在 Markdown 使用 Vue

对于有前端经验的开发者来说,这个功能可以增强整个文档的交互,也是我非常喜欢VitePress的特性之一。

唯一的缺点是:引入的组件需要单独使用文件来进行管理

vue 复制代码
<script setup>
import CustomComponent from '../../components/CustomComponent.vue'
</script>

比如上面这段写法,你需要手动管理这些外部组件,大概的流程可能是:创建一个components目录,然后将这个CustomComponent.vue组件实现。

如果这个组件会在大多数markdown文件中使用,这样做是很正常的事情。

但在使用VitePress搭建自己的博客站点时发现,markdown中的某些组件,往往只会跟当前的文档内容插入该组件时的上下文联系紧密,用于演示该文档的特定内容。

对于这种用途的组件,将他们放在单独的文件里面,然后通过script setup引入注册,感觉上并不是一种很好的做法:当单独阅读组件内容时,可能会丢失markdown文档中的上下文部分。

对于一个分类比较杂乱的博客来说,看起来需要一种更好的管理这些外部组件的方式。

因此,我决定开发一种类似于内联的vue代码块语法,可以直接在markdown中以SFC代码块的方法直接编写组件,这样就不需要手动管理外部组件文件,以及导入他们的逻辑了。

暂且将这种特殊的vue代码块语法称作内联Vue组件

配置

component开启内联

正常编写一个vue代码块,会使用下面的语法

python 复制代码
'''vue
<template>
  <button>原始code</button>
</template>
'''

内联Vue组件,是在vue代码块的基础上,通过一个JSON字符串配置component字段为true来开启的

xml 复制代码
'''vue { "component": true } 
<script setup lang="ts">
import { add } from './util'
const onClick = ()=>{
    alert("click me")
}
</script>

<template>
  <button class="bg-red-100" @click="onClick">click me</button>
</template>

<style scoped>
button {
    color: red;
}
</style>
'''

上述的{ "component": true }会将vue代码块进行扩展,通过vite插件构建为一个在markdown里面运行的vue SFC组件,不需要引入任何的外部文件!!

当前页面就是由这个功能来实现的,不出意外的话,你可以在下面看见一个通过该方式渲染的内联组件。

(由于掘金上面不支持mdx,所以部分演示功能会有问题,使用图片进行了代替,可以移步原文章查看具体效果)

内联组件跟单独创建的SFC文件完全相同,可以访问当前开发环境,比如tsunocss、其他组件或工具模块等。

name组件名

还支持另外一个name的字段,指定之后,sfc代码块会编译成对应名称的组件,然后你可以使用该组件名,在本页面的其他地方进行复用

当然,你需要保证该组件名在当前文档下唯一

python 复制代码
'''vue { "component": true, "name": "Demo" }
here your sfc code
'''

一些内容之后,通过组件名复用

<Demo />

通过<componentName />的形式调用,就像是引入了一个外部组件

下面演示了复用在上一个章节定义的内联组件,你应该会看见一个与上面完全一样的组件渲染节点。

lazy

在默认情况下,开启了component:true的代码块,会直接在该代码块的位置渲染出对应的组件。

这是sfc代码块最常见的场景,即不需要从外部引入模块文件,就可以为当前模块编写组件。

如果在某种情况下,你希望先编写代码,但是不希望立即渲染,可以手动打开lazy:true配置项。

python 复制代码
'''vue { "component": true, "name": "Demo2", "lazy": false }
here your sfc code
'''

一些内容之后,通过组件名手动渲染

<Demo2 />

开启后,你需要手动通过name来编写组件标签进行渲染。

源文件中,这里有一段代码,但没有立即渲染。

(这里有一大段内联组件代码)

vue 复制代码
<script setup lang="ts">
import { add }from'./util'
const onClick = ()=>{
    alert("click me")
}
</script>

<template>
  <button class="bg-red-100" @click="onClick">click me demo2</button>
</template>

<style scoped>
button {
    color: red;
}
</style>

你需要手动编写<Demo2 />标签,之后该组件才会渲染

导入代码片段

同时展示交互组件和对应源码是比较常见的需求,vitepress提供了导入代码片段的功能

bash 复制代码
<<< @/filepath

由于上述sfc组件并不存在对应的组件,为了兼容该语法,定制了一个特殊的>>>语法

arduino 复制代码
>>> virtual:xxComponentName

比如展示上面的Demo2组件源码,路径修改为virtual:Demo2,就会展示如下源码

xml 复制代码
<script setup lang="ts">
import { add }from'./util'
const onClick = ()=>{
    alert("click me")
}
</script>

<template>
  <button class="bg-red-100" @click="onClick">click me demo2</button>
</template>

<style scoped>
button {
    color: red;
}
</style>

使用

该功能目前已发布到npm上面,源代码位于github上面

安装

arduino 复制代码
// npm
npm i vite-plugin-vitepres-inline-sfc -D
// pnpm 
pnpm i vite-plugin-vitepres-inline-sfc -D

.vitepress/config.mts中作为vite插件引入

js 复制代码
import { defineConfig } from 'vitepress'
import inlineSFC from 'vite-plugin-vitepres-inline-sfc'

export default defineConfig({
  ... other vitepress config
  vite: {
    plugins:[
      inlineSFC()
    ]
  }
})

我已经自己的博客中尝试使用该功能,目前体验下来还不错,可以在一个markdown文件中编写内容和交互组件,不需要额外管理单独的组件文件。

如果有什么问题,或者新功能建议,欢迎在issue或者评论区讨论交流。

相关推荐
懒大王爱吃狼1 小时前
Python教程:python枚举类定义和使用
开发语言·前端·javascript·python·python基础·python编程·python书籍
逐·風5 小时前
unity关于自定义渲染、内存管理、性能调优、复杂物理模拟、并行计算以及插件开发
前端·unity·c#
Devil枫5 小时前
Vue 3 单元测试与E2E测试
前端·vue.js·单元测试
尚梦6 小时前
uni-app 封装刘海状态栏(适用小程序, h5, 头条小程序)
前端·小程序·uni-app
GIS程序媛—椰子6 小时前
【Vue 全家桶】6、vue-router 路由(更新中)
前端·vue.js
前端青山7 小时前
Node.js-增强 API 安全性和性能优化
开发语言·前端·javascript·性能优化·前端框架·node.js
毕业设计制作和分享7 小时前
ssm《数据库系统原理》课程平台的设计与实现+vue
前端·数据库·vue.js·oracle·mybatis
程序媛小果7 小时前
基于java+SpringBoot+Vue的旅游管理系统设计与实现
java·vue.js·spring boot
从兄8 小时前
vue 使用docx-preview 预览替换文档内的特定变量
javascript·vue.js·ecmascript
凉辰9 小时前
设计模式 策略模式 场景Vue (技术提升)
vue.js·设计模式·策略模式