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>