vue3+rust个人博客建站日记4-Vditor搞定MarkDown

即然是个人博客,那么绝对不能丢给自己一个大大的输入框敷衍了事。如果真是这样,现在就可以宣布项目到此结束了。如今没人享受用输入框写博客。作为一个有追求的程序员,作品就要紧跟潮流。

后来,Markdown 的崛起逐步改变了大家的排版方式。再加上我们其他几个项目都是面向程序员用户的,所以迁移到 md 上也是大势所趋。 ——Vditor文档

给个人博客嵌入MarkDownb编辑器,即便设备上没有支持MarkDown格式的文本编辑器,我们仍然能随时随地优雅的编写博客。这里的MarkDown组件,选择了Vditor,由思源笔记团队开源的浏览器端 Markdown 编辑器,MIT开源协议(几乎是最为宽松的开源协议),感谢思源团队的无私分享。
在这里插入图片描述
为了让我们的博客有良好的编辑和阅读体验,需要做两件工作:

  1. 封装Vditor编辑器组件
  2. 封装Vditor预览器组件
    ps: 做好黑夜模式适配

在 src/components/目录下创建MarkDownEdit.vue、MarkDownRead.vue

封装Vditor编辑器组件

MarkDownEdit.vue

因为Vditor的初始化完成后,vue无法监听到Vditor对象内参数的变化,所以我们需要用一些小技巧来告诉框架刷新状态,以完成黑夜模式的变化。创建一个computed参数active,让其计算被pinia托管的参数active,一旦active变化,则调用setTheme()方法设置 主题。
这里先设置pinia
在src/stores/目录下创建themeSwitch.js,内容如下

import { ref, computed } from 'vue'
import { defineStore } from 'pinia'

export const useThemeSwitch = defineStore('themeSwitch', () => {
    const active = ref(false)
    function changeActive(newActive){
        this.active = newActive
    }

    return { active, changeActive }
})

然后编写MarkDownEdit.vue

  <script setup >
  import { ref, onMounted,computed } from 'vue';
  import Vditor from 'vditor';
  import 'vditor/dist/index.css';
  const vditor = ref(null);
  const props = defineProps(['active'])
  const active = computed({
    get(){
      if(vditor.value!=null)
      {
        console.log(props.active)
        const mode = props.active?'dark':'classic'
        vditor.value.setTheme(mode,mode)
      }
      return props.active;
    },
  })

  let content = ''
  let width = 0;
  let height = 0;
  function ReInitVidor() {
    width = window.innerWidth*0.92  < 600 ? 600 : window.innerWidth*0.92 ;
    height = window.innerHeight * 0.9;
    vditor.value = new Vditor('vditor', {
      mode:'sv',
      preview:{},
      icon:'material',
      height:height,
      width:width,
      placeholder:"君子藏器于身,待时而动",
      counter:{
        enable:true,
      },
      preview:{
        actions:[]
      },
      input:(value) => {
        content = value
      },
      after: () => {
      // vditor.value is a instance of Vditor now and thus can be safely used here
         vditor.value.setValue(content);
      },
    });
  }
  onMounted(() => {
    window.addEventListener('resize', ReInitVidor)
    ReInitVidor();
    
  });
  </script>
<template>
    <div style="display: flex;flex-direction: row;justify-content: center;">
    <!-- 一定要在html的部分插入active,
    vue框架才会去真正监听并计算active参数-->
      <div hidden>active: {{ active }}</div>
      <div id="vditor" ></div>
    </div>
  </template>
封装Vditor预览器组件
<template>
    <div>
      <div hidden>{{active}} </div>
      <div id="vditor" ></div>
    </div>
  </template>
  
  <script setup >
  import { onMounted,computed, } from 'vue';
  import Vditor from 'vditor';
  import 'vditor/dist/index.css';
  const props = defineProps(['active'])
  let active = computed({
    get(){
      return props.active;
    },
  })
  const IPreviewOptions = {
      theme:{current:props.active?"dark":"light"},
      mode:"dark",
      speech:{"enable":true}
  }
    const mdStr=`## 💡 简介

[Vditor](https://b3log.org/vditor) 是一款浏览器端的 Markdown 编辑器,支持所见即所得(富文本)、即时渲染(类似 Typora)和分屏预览模式。它使用 TypeScript 实现,支持原生 JavaScript、Vue、React、Angular,提供[桌面版](https://b3log.org/siyuan)。`
  
  function ReInitVidor() {
    Vditor.preview(
        document.getElementById('vditor'),
        mdStr,IPreviewOptions);
  }
  
  onMounted(() => {
    addEventListener("resize",ReInitVidor)
    ReInitVidor();
  });
  </script>
使用组件

在src/views/目录下创建BlogEditView.vue、BlogReadView.vue文件

BlogEditView.vue
<script setup>
    import MarkDownEdit from '../components/MarkDownEdit.vue';
    import { useThemeSwitch } from '../stores/themeSwitch';
    const themeSwitcher = useThemeSwitch()
</script>

<template>
    <mark-down-edit :active="themeSwitcher.active"></mark-down-edit>
</template>
BlogReadView.vue

因为vditor.preview没有提供setTheme这种好用的函数。所以我们在active值改变后,要告诉vue框架强制刷新组件。这里使用:key=“”参数,组件会监听key参数是否变化,变化则刷新组件。

<script setup>
    import MarkDownRead from '../components/MarkDownRead.vue';
    import { NSpace } from 'naive-ui';
    import { useThemeSwitch } from '../stores/themeSwitch';
    const themeSwitcher = useThemeSwitch()
</script>
<template>
    <n-space         
        style="height: 100%;" 
        justify="center" 
        size="large"
        >
        <mark-down-read class="blog-read-preview" :key="themeSwitcher.active" :active="themeSwitcher.active"></mark-down-read>
    </n-space>
</template>

<style>
.blog-read-preview{
    margin-inline: 15vw;
    max-width: 900px;
}
</style>
最终效果
编辑器

在这里插入图片描述在这里插入图片描述

预览器

在这里插入图片描述

在这里插入图片描述

暂时的休息

当前只是一种简单的封装,方便组织前端代码结构,在实现功能时,会按需进一步修改相关代码。

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值