vue3工程中使用vditor完成markdown渲染并防止xss攻击
vue3工程中使用vditor完成markdown渲染并防止xss攻击
- 背景
- 环境
- 解决方案
- 引入依赖
 
- 组件封装
- 实现效果
背景
做oj系统时,题目使用的时markdown语法字符串,前端查看时需要将markdown转html再渲染到页面上。
环境
- vite
- vue3
- pnpm
解决方案
引入依赖
pnpm install vditor dompurify
- vditor用于完成markdown转html
- dompurify用于去除恶意代码
组件封装
<script setup lang="ts">
import Vditor from 'vditor'
import 'vditor/dist/index.css'
import { onMounted, ref, watch } from 'vue'
import DOMPurify from 'dompurify'
const contentEditor = ref()
const previewContent = ref('')
// 注册事件
const emit = defineEmits(['update:modelValue'])
// 父组件传来的值
const props = defineProps({
  modelValue: {
    type: String,
    default: '',
  },
})
onMounted(() => {
  contentEditor.value = new Vditor('mdEdit', {
    height: 360,
    width: '100%',
    toolbarConfig: {
      pin: true,
    },
    value: props.modelValue,
    mode: 'sv', // 使用分屏预览模式
    toolbar: [
      'emoji',
      'headings',
      'bold',
      'italic',
      'strike',
      '|',
      'line',
      'quote',
      'list',
      'ordered-list',
      'check',
      'outdent',
      'indent',
      'code',
      'inline-code',
      'insert-after',
      'insert-before',
      'undo',
      'redo',
      'link',
      'table',
      'fullscreen',
      'outline',
    ],
    cache: {
      enable: false,
    },
    // 失去焦点时触发
    blur(value: string) {
      // 触发事件,给父组件传值
      emit('update:modelValue', value)
    },
    after() {
      getSafeHtml()
    },
  })
})
// 定义用于获取安全html的函数
function getSafeHtml() {
  previewContent.value = DOMPurify.sanitize(contentEditor.value.getHTML())
}
// 监视modelValue实现双向数据绑定
watch(
  () => props.modelValue,
  (newValue) => {
    contentEditor.value.setValue(newValue)
    getSafeHtml()
  },
)
</script>
<template>
  <div>
    <div id="mdEdit" v-show="false" />
    <div v-html="previewContent" class="preview"></div>
  </div>
</template>
<style scoped>
.preview {
  margin-top: 20px;
  padding: 10px;
  border: 1px solid #ccc;
  border-radius: 5px;
  background-color: #f9f9f9;
}
</style>
实现效果

