vitepress中实现在线编写

最近又在倒腾vitepress,想着能不能在线编写文档,然后直接上传,然后就有了这篇文档(这就是用在线编写功能写的)。

顺便把之前的网站精简一下,因为有些方法,官方已经提供了,就不用自己写了,然后又新加了一些功能。

初始化项目的步奏看看官网,重点说一下如何实现在线编写的,该功能只是我自己的一个想法,如果大佬们有更好的方法,欢迎提供一下。

MarkDown编辑器

编辑器我选用的是md-editor-v3,使用简单,功能完善。

安装

javascript 复制代码
pnpm i md-editor-v3

用法

vue 复制代码
<template>
  <MdEditor v-model="text" />
</template>

<script setup>
import { ref } from 'vue';
import { MdEditor } from 'md-editor-v3';
import 'md-editor-v3/lib/style.css';

const text = ref('# Hello Editor');
</script>

vitepress中使用

vitepress是可以直接在md文件中写vue3的,所以这里可以直接新建一个md文件,然后引入组件。

vue 复制代码
// editor.md
<script setup>
import editor from '../.vitepress/components/editor.vue'
</script>
<editor />
vue 复制代码
<!-- editor.vue -->
<script setup>
import { ref, computed } from 'vue';
import { MdEditor } from 'md-editor-v3';
import 'md-editor-v3/lib/style.css';
import { useData } from 'vitepress';

const content = ref('# Hello Editor');
const theme = computed(()=>useData().isDark.value ? 'dark' : 'light')

const handleSave = () => {
  // 请求保存接口
  ...
}
</script>
<template>
  <MdEditor v-model="content" :theme="theme"/>
  <button class="save-btn" @click="handleSave">保存</button>
</template>
<style>
.save-btn{
  float: right;
  margin-top: 10px;
}
</style>

保存

说一下我的整个想法,我是在前端请求保存以后,后端(nodejs)直接把传过来的数据保存到vitepress对应的文件夹下,整个的数据格式就是一个markdown形式的字符串,然后切换到vitepress目录下运行npm run build。

关键代码

获取数据,拼接处理

javascript 复制代码
  // 前端传过来的 text: 文档标题,link:文件名(vitepress用于跳转),content:文档内容
  const params = ctx.request.body
  const dates = dayjs(new Date).format('YYYY-MM-DD')
  const fileName = `${params.link}.md`
  // vitepress对应的文件夹
  const toFilePath = path.resolve(__dirname, '../../../Woung/docs/blog');
  // 需要保存的当前文件路径
  const filePath = path.join(toFilePath, fileName)
  let msg = ''
  // 拼接文档frontmatter
  let markdown = `---
title: ${params.text}
author: Younglina
date:  ${dates}
categories:
- 文档
tags:
- 记录
---
${params.content}
`

保存数据,重新打包

javascript 复制代码
fs.writeFile(filePath, markdown, 'utf-8', (err) => {
  if (err) {
    ctx.body = {
      "code": 200,
      "message": err
    }
  }

  // 处理vitepress的sidebar,我的vitepress是把sidebar抽离出了一个json文件
  const sidebarPath = path.resolve(__dirname, '../../../Woung/docs/.vitepress/sidebar.json');
  // 读取文件内容
  fs.readFile(sidebarPath, 'utf8', (err, data) => {
    if (err) {
      console.error('Error reading file:', err);
      return;
    }

    const sidebar = JSON.parse(data)
    const blogs = sidebar['/blog/'].items[0].items
    // 把当前文件信息存储到sidebar中,并覆盖原文件
    blogs.push({ text: params.text, link: params.link })
    fs.writeFile(sidebarPath, JSON.stringify(sidebar), 'utf-8', (err) => {
      if (err) {
        console.error(err)
      }
    })
  });

  // 最后使用nodejs的child_process,切换到vitepress根目录,执行build
  const buildPath = path.resolve(__dirname, '../../../Woung');
  const command = `cd ${buildPath} && npm run build`;

  exec(command, (error, stdout, stderr) => {
    if (error) {
      console.error('Error executing command:', error);
      return;
    }

    console.log('Command executed successfully:', stdout);
  });
})

效果

觉得编写的地方小,编辑器有全屏的功能

相关推荐
一 乐3 小时前
民宿|基于java的民宿推荐系统(源码+数据库+文档)
java·前端·数据库·vue.js·论文·源码
BillKu3 小时前
Vue3 + TypeScript + Element Plus 表格行按钮不触发 row-click 事件、不触发勾选行,只执行按钮的 click 事件
vue.js·elementui·typescript
小前端大牛马3 小时前
react中hook和高阶组件的选型
前端·javascript·vue.js
萌萌哒草头将军5 小时前
🚀🚀🚀VSCode 发布 1.101 版本,Copilot 更全能!
前端·vue.js·react.js
摇摇奶昔x7 小时前
Vue.js 中 “require is not defined“
前端·javascript·vue.js
sunbyte8 小时前
50天50个小项目 (Vue3 + Tailwindcss V4) ✨ | RandomChoicePicker(标签生成)
前端·javascript·vue.js
z_y_j2299704389 小时前
vue前端项目打包和部署
前端·javascript·vue.js
lbchenxy9 小时前
antd vue a-range-picker如何设置不能选择当前和之后的时间,包含时分秒
前端·javascript·vue.js
前端小白从0开始9 小时前
前端基础知识ES6系列 - 01(var、let、const之间的区别)
前端·javascript·vue.js·es6
前端呆猿11 小时前
Vuex:Vue.js 应用程序的状态管理模式
android·vue.js·flutter