[Vue3] MarkDown(md)文件生成html页面分享

分享下如何通过MarkDown(.md)文件直接生成页面内容的方法。

呈现形式

  • 最终实现效果:将写好的xxx.md文件放到项目中,编译,即可通过url访问到,并正确渲染

举个栗子

  1. xxx.md放入/src/pages文件夹中:

/my-vue3-ts-project  
|--- src/
|    |--- pages/
|    |    |--- code-repo-exchange.md      # 将md文件放在这里
|    |--- App.vue

  1. 编译nr dev(即npm/pnpm/yarn run dev),通过domain/code-repo-exchange即可访问:

    [Vue3] MarkDown(md)文件生成html页面分享

戳这里体验实际效果

下面对实则现方式进行说明:

项目环境

Vue3 | VueRouter | Vite | vitesse | Typescript

"dependencies": {
    "vue": "^3.3.10",
    "vue-router": "^4.2.5"
  },

实现方式

接下来我会列出在项目中需要新增的内容,修改点旁的注释如果看不清楚可以先跳过。

由于新增的内容技术角度不完全一致,详细解释在后续实现思路里再说明

  1. 安装依赖

下方提到的内容都要添加:

// package.json
"devDependencies": {
    "@unhead/vue": "^1.8.10",                  // vue中给markdown文件添加header
    "github-markdown-css": "^5.5.0",        // markdown通用样式
    "markdown-it-anchor": "^8.6.7",          // 为Markdown标题生成唯一的ID,实现导航
    "markdown-it-highlightjs": "^4.0.1",     // 代码块高亮样式
    "markdown-it-prism": "^2.3.0",            // 代码块高亮样式,和highlightjs功能一致。用一个就行了,我最终没用这个
    "unplugin-vue-markdown": "^0.25.2", // 实现markdown的核心库,内部分装了markdown-it
  },

PS:

  • dependenciesdevDependencies两个文件夹,从实现角度装在哪个文件夹都可以
  • 我的安装工具是ni,缘由是我用npm,pnpm,yarn装,要么慢,要么报错。
    也可能项目一开始就是用ni装的,只有ni才比较顺利。
  1. Vite修改配置
    引入Markdown及样式,并修改vuevue router插件

// vite.config.ts

// Markdown related
import Markdown from "unplugin-vue-markdown/vite"
import MarkdownItAnchor from "markdown-it-anchor"
import markdownItHighlightjs from "markdown-it-highlightjs"

export default defineConfig({
  plugins: [
    // Vue为新增,之前Vue是配置在VueMacros中,目前为了md文件,删除了VueMacros的相关配置
    Vue({
      include: [/.vue$/, /.md$/], 
    }),
    // 整个Markdown都是新增内容
    Markdown({
      headEnabled: true,
      markdownItOptions: {
        html: true,
        linkify: true,
        typographer: true,
      },
      // A function providing the Markdown It instance gets the ability to apply custom settings/plugins
      markdownItSetup(md) {
        md.use(MarkdownItAnchor)
        md.use(markdownItHighlightjs)
      },
      wrapperClasses: "markdown-body", // markdown-body是一个class类,将和github-markdown-css包对应
    }),
    // 注释所有VueMacros的配置,VueMacros和Vue两个会起冲突
    // 可能在VueMacros里也能实现Markdown,但又是一个技术,而且当前包含的内容还不多,暂时就不管了
    // VueMacros({
    //   defineOptions: false,
    //   defineModels: false,
    //   plugins: {
    //     vue: Vue({
    //       script: {
    //         propsDestructure: true,
    //         defineModel: true,
    //       },
    //     }),
    //   },
    // }),

    // VueRouter需新增配置{ extensions: [".vue", ".md"] }
    // https://github.com/posva/unplugin-vue-router
    VueRouter({ extensions: [".vue", ".md"] }),
})

  1. main.ts 新增

// 以下内容均为样式相关
import { createHead } from "@unhead/vue" 
import "github-markdown-css"
import "highlight.js/styles/default.css"

const head = createHead() 
app.use(head) 

  1. pages中添加*.md文件

/my-vue3-ts-project  
|--- src/
|    |--- pages/
|    |    |--- code-repo-exchange.md      # 将md文件放在这里
|    |--- App.vue

4.1 在当前组件中渲染Markdown

<script setup>
import HelloWorld from "~/pages/code-repo-exchange.md"
</script>

<template>
  <HelloWorld class="markdown-body" />
</template>

上面这几部即所有修改内容,完成后应该就能成功。

实现思路

为了实现以上效果,需要集成3个主要技术到项目中:

[Vue3] MarkDown(md)文件生成html页面分享

1. markdown核心

unplugin-vue-markdown

这个库是实现markdown的核心库,协助vue封装markdown-it。
markdown-it是一项更泛用的技术,是一个用于解析和转换 Markdown 文档的 JavaScript 库,适用于其他JavasSript框架(包含nodejs)场景。
unplugin-vueVue官方团队大佬的作品啦,品质有保证。

  • unplugin-vue-markdown Git主页 ,其中包含了Vue3使用中核心引入逻辑
  • markdown-it官网,该网站更多是方法论,对本项目语法基本不适用

2. markdown样式

样式是单独引入的。一开始我以为markdown-it已经足够了,但实则并不包含样式,这点在markdown核心提到的相关文档中也没有明确提到,所以一开始走了写弯路。

  • github-markdown-css
  • markdown-it-prism
  • markdown-it-anchor
  • markdown-it-highlightjs

这4个库为markdown进行解析,提供渲染形式的样式库。没有这几个库的话,markdown-it只会渲染到页面上一些平平的文字,并没有字体大小或颜色高亮。

重点在下面这行配置

// vite.config.ts
export default defineConfig({
  plugins: [
    Markdown({
      // Class names for the wrapper div
      wrapperClasses: "markdown-body", // markdown-body是一个class类,将和github-markdown-css包对应
    })
]})

上文中的这个markdown-body,会伴随整个markdown文档加载到DOM的class中,但并没有为其定义具体的css样式。

[Vue3] MarkDown(md)文件生成html页面分享

于是再查找资料后,发现要引入github-markdown-cssmarkdown-it-highlightjs,从而才能渲染。
github-markdown-css提供文档样式,markdown-it-highlightjs则对代码样式进行加强。

同时,markdown-it-highlightjs是为vue框架而编写的,本身基于vanillar

3. VueRouter扩展

VueRouter本身是不会引入*.md的,好在vitesse足够强劲,稍微修改就能加入。
需要注意的是,以下内容和和unplugin-vue-markdownGit主页修改方式不同。

// vite.config.ts
export default defineConfig({
  plugins: [
    // 注释所有VueMacros的配置,VueMacros和Vue两个会起冲突,导致编译过不去
    // 可能在VueMacros里也能实现Markdown,但又是一个技术,而且当前包含的内容还不多,暂时就不管了
    // VueMacros({
    //   defineOptions: false,
    //   defineModels: false,
    //   plugins: {
    //     vue: Vue({
    //       script: {
    //         propsDestructure: true,
    //         defineModel: true,
    //       },
    //     }),
    //   },
    // }),

    // VueRouter需新增配置{ extensions: [".vue", ".md"] }
    // https://github.com/posva/unplugin-vue-router
    VueRouter({ extensions: [".vue", ".md"] }),
})

Git主页是这样的:

import Vue from  @vitejs/plugin-vue 
import Markdown from  unplugin-vue-markdown/vite 
import Pages from  vite-plugin-pages 

export default {
  plugins: [
    Vue({
      include: [/.vue$/, /.md$/],
    }),
    Pages({
      extensions: [ vue ,  md ],
    }),
    Markdown()
  ],
}

上图中有两个不同:

  1. VueMacros配置删除。VueMacros基于unplugin-vue-macros库,但由于和Vue节点会产生冲突,具体缘由还不清楚,文档内容有些多我就没有继续深究。
  2. VueRouter({ extensions: [“.vue”, “.md”] })修改,基于unplugin-vue-router库。和官网指引的库vite-plugin-pages写法也有不同,
  3. unplugin-vue-router配置详见Github主页

我的项目本身基于vitesse-lite,可能有更优雅的解法。

  • @unhead/vue: 这个库是为了给*.md加上<head>头,但目前我项目里还没用上

总结

要方便得将Markdown引入到项目中,上述三点(Markdown核心,Markdown样式,VueRouter扩展)缺一不可。实现起来不算简单,但一旦实现后来,对于项目来说是超级方便的,尤其适合个人网站的项目,可以通过Markdown快速排版并进行发布,超级节省时间精力。

后续计划对md的seo再进行学习。

附录

体验地址
项目base->vitesse-lite
unplugin-vue-router
unplugin-vue-markdown
antfu大佬个人网站

© 版权声明

相关文章

暂无评论

您必须登录才能参与评论!
立即登录
none
暂无评论...