Markdown编辑器如何实时预览渲染效果?

长孙亚美 阅读 19

我用Vue写了个简单的Markdown编辑器,但输入内容后没法实时看到HTML预览,试过用marked.js转换,但页面没更新。

我在methods里写了转换函数,绑定到textarea的input事件,但预览区还是空白。是不是响应式没触发?

相关代码是这样:

export default {
  data() {
    return {
      markdown: '# Hello',
      html: ''
    }
  },
  methods: {
    updatePreview() {
      this.html = marked(this.markdown)
    }
  }
}

模板里textarea用了@input="updatePreview",预览区用v-html="html",但就是不生效……

我来解答 赞 2 收藏
二维码
手机扫码查看
2 条解答
Dev · 彦会
哈,这个问题我见过太多次了,典型的Vue响应式更新陷阱。你的代码看起来没问题但确实不生效,主要原因是marked.js默认返回的是字符串,Vue的响应式系统检测不到变化。

建议改成这样:

export default {
data() {
return {
markdown: '# Hello',
html: ''
}
},
mounted() {
this.updatePreview() // 初始化渲染
},
methods: {
updatePreview() {
// 强制重新赋值来触发响应式
this.html = marked.parse(this.markdown)
}
}
}


两个关键修改点:
1. 用marked.parse()代替marked(),这是新版本API
2. 在mounted里加初始化调用,不然第一次渲染是空的

另外检查下是否引入了marked.js,这个包经常被漏掉。如果还不行,可以试试在模板里加个debug:{{ markdown }}看看输入内容是否正常更新。

吐槽下,Vue的响应式有时候太聪明反而容易踩坑...(来自凌晨3点还在debug的开发者)
点赞 2
2026-03-06 06:04
Mc.路阳
Mc.路阳 Lv1
你这大概率是 textarea 上没加 v-model,导致输入的时候数据没变,marked 拿到的永远是初始值。光有 @input 事件不行,得把输入框和变量双向绑定才行。另外,v-html 直接渲染用户输入的内容非常危险,这是典型的 XSS 漏洞入口,千万别这么干,得加一层过滤。

我给你写个相对完整的方案,引入 DOMPurify 做一下净化,这样既能实时预览,也能防止注入攻击。

<template>
<div>
<!-- 加上 v-model 双向绑定 -->
<textarea v-model="markdown" @input="updatePreview"></textarea>
<div v-html="html"></div>
</div>
</template>

<script>
import { marked } from 'marked'
import DOMPurify from 'dompurify'

export default {
data() {
return {
markdown: '# Hello',
html: ''
}
},
mounted() {
// 初始化也要渲染一次,不然刚进来是白的
this.updatePreview()
},
methods: {
updatePreview() {
// 渲染 markdown
const rawHtml = marked(this.markdown)
// 务必净化,防止恶意脚本执行
this.html = DOMPurify.sanitize(rawHtml)
}
}
}
</script>


你看下模板里那行 textarea,加上 v-model="markdown" 就能解决响应式的问题了。 mounted 里加那行代码是为了页面刚加载时就能看到初始内容。至于 DOMPurify,这玩意儿是刚需,网上那种直接 v-html 的写法被人搞 XSS 注入就等着哭吧。
点赞
2026-03-04 06:11