Vue3中如何在Quill富文本编辑器内显示默认回显值
Quill富文本编辑器回显已保存内容实现
现有功能状态
- 后台集成Quill编辑器后,内容输出后的前端渲染正常:写入加粗格式的
Description时,输出HTML为<p><strong>Description</strong></p>,前端通过以下代码即可正常渲染:
<div v-html="product.attributes.description"></div>
- 编辑器写入效果:

问题描述
需要将已保存的富文本内容加载回显到Quill编辑器内部(例如直接在编辑器中展示带加粗格式的Description,而非显示undefined),当前自定义text-editor组件代码如下,未实现正确的回显逻辑:
<template> <div class="form-control" v-bind:class="inputClasses" ref="editor"></div> </template> <script> import Quill from 'quill'; import 'quill/dist/quill.core.css'; import 'quill/dist/quill.bubble.css'; import 'quill/dist/quill.snow.css'; export default { props: { modelValue: { type: String, default: '' }, defaultValue: "", }, data() { return { editor: null, }; }, mounted() { var _this = this; this.editor = new Quill(this.$refs.editor, { modules: { toolbar: [ [{ header: [1, 2, 3, 4, false]} ], ["bold", "italic", "underline", "link", "image"], ], }, theme: "snow", formats: ["bold", "underline", "header", "italic", "link"], placeholder: this.placeholder }); this.editor.root.innerHTML = this.defaultValue; this.editor.on("text-change", function () { return _this.update(); }); }, methods: { update: function update() { this.$emit( "update:modelValue", this.editor.getText() ? this.editor.root.innerHTML : "" ); }, }, } </script>
修复方案
直接操作editor.root.innerHTML赋值不符合Quill的内容解析规则,同时组件缺少对外部传入值的监听、初始值读取逻辑有误,按以下规则修改即可:
- 初始化和更新编辑器内容时,使用Quill官方提供的
clipboard.dangerouslyPasteHTML方法,保证富文本格式被正确解析 - 新增
modelValue的监听逻辑,外部传入的已保存内容变化时自动同步到编辑器,同时加内部更新标记,避免和编辑器输入事件触发的更新形成循环 - 初始化时优先读取双向绑定的
modelValue作为初始内容,无modelValue时再读取defaultValue - 补全
formats配置中缺失的image项,和工具栏配置保持一致,避免图片内容无法正常保存回显
修复后的完整组件代码:
<template> <div class="form-control" v-bind:class="inputClasses" ref="editor"></div> </template> <script> import Quill from 'quill'; import 'quill/dist/quill.core.css'; import 'quill/dist/quill.bubble.css'; import 'quill/dist/quill.snow.css'; export default { props: { modelValue: { type: String, default: '' }, defaultValue: { type: String, default: "" }, placeholder: { type: String, default: '请输入内容' } }, data() { return { editor: null, isInternalUpdate: false }; }, watch: { modelValue(newVal) { if (!this.isInternalUpdate && newVal !== this.editor.root.innerHTML) { this.editor.clipboard.dangerouslyPasteHTML(newVal || this.defaultValue); } this.isInternalUpdate = false; } }, mounted() { this.editor = new Quill(this.$refs.editor, { modules: { toolbar: [ [{ header: [1, 2, 3, 4, false]} ], ["bold", "italic", "underline", "link", "image"], ], }, theme: "snow", formats: ["bold", "underline", "header", "italic", "link", "image"], placeholder: this.placeholder }); const initContent = this.modelValue || this.defaultValue; if (initContent) { this.editor.clipboard.dangerouslyPasteHTML(initContent); } this.editor.on("text-change", () => { this.isInternalUpdate = true; this.update(); }); }, methods: { update() { const content = this.editor.getText().trim() ? this.editor.root.innerHTML : ""; this.$emit("update:modelValue", content); }, }, } </script>
内容的提问来源于stack exchange,提问作者breking bed
相关产品推荐
相关产品推荐

