Vue.js 3中QuillJS编辑器清空内容时报错:Cannot read properties of null
Vue3选项式API中QuillJS清空编辑器报错的解决方法
问题场景
在Vue3选项式API项目中集成Quill编辑器后,提交表单调用handleSubmission方法时,尝试通过deleteText、setText或setContents清空编辑器内容,均触发如下错误:
Uncaught TypeError: Cannot read properties of null (reading 'offset') at quill.js?v=b3144345:12600:26 at Array.map (<anonymous>) at Proxy.normalizedToRange (quill.js?v=b3144345:12597:31) at Proxy.getRange (quill.js?v=b3144345:12586:25) at Proxy.update (quill.js?v=b3144345:12723:43) at Proxy.update (quill.js?v=b3144345:13796:20) at Proxy.getSelection (quill.js?v=b3144345:13690:10) at Proxy.modify (quill.js?v=b3144345:13906:44) at Proxy.deleteText (quill.js?v=b3144345:13553:19) at Proxy.handleSubmission (AppChatContainer.vue:47:18)
组件核心代码如下:
<script> import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome' import Quill from 'quill' export default { name: 'AppChatContainer', components: { FontAwesomeIcon }, props: { messages: { type: Array, required: true, default: () => [] }, isSending: { type: Boolean, default: false } }, emits: ['new-message'], data() { return { quill: null } }, mounted() { this.quill = new Quill('#message', { theme: 'bubble', modules: { toolbar: [ ['bold', 'italic', { color: [] }], [{ list: 'ordered' }, { list: 'bullet' }] ] } }) }, methods: { handleSubmission() { const message = this.quill.getContents() this.$emit('new-message', message) // 以下三种方式均报错 // this.quill.setContents([{ insert: '\n' }]) // this.quill.setText(''); this.quill.deleteText(0, this.quill.getLength()) }, convertDeltaToHtml(delta) { const tempQuill = new Quill(document.createElement('div')) tempQuill.setContents(delta) return tempQuill.root.innerHTML } } } </script> <template> <form class="h-100 position-relative" @submit.prevent="handleSubmission"> <div class="flex-grow-1 overflow-y-scroll"> <div v-for="message in messages" :key="message.id" :class="`message mb-4 ${message.isAuthor ? 'author' : ''} ${message.isSending ? 'sending' : ''}`" > <div class="content" v-html="convertDeltaToHtml(message.content)" /> <small v-if="message.isSending" class="text-gray-700 fw-light d-block mt-1 ms-2 me-3"> Envois en cours... </small> <small v-else class="text-gray-700 fw-light d-block mt-1 ms-2 me-3"> {{ message.isAuthor ? 'Vous' : message.authorName }}, le {{ message.date }}</small > </div> </div> <div class="message-container"> <div id="message" /> <button type="submit" class="btn btn-amsom-green" :disabled="isSending"> <font-awesome-icon v-if="!isSending" icon="paper-plane" /> <div v-else class="spinner-border spinner-border-sm" role="status"> <span class="visually-hidden">Envois en cours...</span> </div> </button> </div> </form> </template>
解决方案
1. 修正清空范围 + 延迟执行
Quill编辑器默认会保留一个换行符(长度为1),如果删除范围包含这个默认换行符,会导致内部状态异常。同时,$emit后父组件可能触发DOM更新,用$nextTick延迟清空操作:
handleSubmission() { const message = this.quill.getContents() this.$emit('new-message', message) this.$nextTick(() => { // 只删除内容部分,保留默认换行符 this.quill.deleteText(0, this.quill.getLength() - 1) }) }
2. 改用Ref获取DOM元素初始化Quill(推荐)
直接使用ID选择器初始化Quill存在全局冲突风险,改用Vue的ref绑定DOM元素更可靠:
- 模板中修改编辑器容器:
<div ref="messageEditor" />
- 初始化Quill时使用ref获取元素:
mounted() { this.quill = new Quill(this.$refs.messageEditor, { theme: 'bubble', modules: { toolbar: [ ['bold', 'italic', { color: [] }], [{ list: 'ordered' }, { list: 'bullet' }] ] } }) }
3. 重置为默认空状态
如果上述方法无效,可直接将编辑器内容重置为Quill默认的空状态(仅保留一个换行符):
handleSubmission() { if (!this.quill || !this.quill.root) return const message = this.quill.getContents() this.$emit('new-message', message) this.quill.setContents([{ insert: '\n' }]) }
内容的提问来源于stack exchange,提问作者LuckyFox
相关产品推荐
相关产品推荐

