Я инициализировал редактор QuillJS в проекте Vue.js 3 (опция API), и вот код, присутствующий в компоненте:
<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' }]) // <= Error here
// this.quill.setText('') // <= Error here
this.quill.deleteText(0, this.quill.getLength()) // <= Error here
},
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>
<style scoped>
// ...
</style>
Когда я отправляю форму, вызывается метод handleSubmission(). Когда я пытаюсь удалить содержимое редактора, у меня возникает ошибка:
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)
Я пробовал несколько способов удаления контента из редактора, но у меня всегда одна и та же проблема...
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())
},



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Я нашел решение, но не думаю, что это очень хороший способ удалить контент из редактора:
handleSubmission() {
const message = this.quill.getContents()
this.$emit('new-message', message)
this.quill.root.innerHTML = ''
},
Я использовал this.quill.root.innerHTML = ''
Попробуйте этот крошечный компонент-оболочку, вы можете построить на нем свой редактор:
npm add [email protected] vue-quilly
# Or
pnpm add [email protected] vue-quilly
Импортируйте полную сборку Quill, если вам нужны все модули, или базовую сборку с минимально необходимыми модулями:
import Quill from 'quill' // Full build
import Quill from 'quill/core' // Core build
import { QuillyEditor } from 'vue-quilly'
Добавьте основные стили. Также импортируйте одну из тем Quill , если она вам нужна:
import 'quill/dist/quill.core.css' // Required
import 'quill/dist/quill.snow.css' // For snow theme (optional)
import 'quill/dist/quill.bubble.css' // For bubble theme (optional)
Определите параметры Quill :
const options = {
theme: 'snow', // If you need Quill theme
modules: {
toolbar: true,
},
placeholder: 'Compose an epic...',
readOnly: false
}
Инициализируем редактор:
const editor = ref<InstanceType<typeof QuillyEditor>>()
const model = ref<string>('<p>Hello Quilly!</p>')
// Quill instance
let quill: Quill | null = null
onMounted(() => {
quill = editor.value?.initialize(Quill)!
})
<QuillyEditor
ref = "editor"
v-model = "model"
:options = "options"
@text-change = "({ delta, oldContent, source }) => console.info('text-change', delta, oldContent, source)"
@selection-change = "({ range, oldRange, source }) => console.info('selection-change', range, oldRange, source)"
@editor-change = "(eventName) => console.info('editor-change', `eventName: ${eventName}`)"
@focus = "(quill) => console.info('focus', quill)"
@blur = "(quill) => console.info('blur', quill)"
@ready = "(quill) => console.info('ready', quill)"
/>
Используйте v-model для типа контента HTML. Вы можете установить контент в формате Delta, используя экземпляр Quill:
quill?.setContents(
new Delta()
.insert('Hello')
.insert('\n', { header: 1 })
.insert('Some ')
.insert('initial', { bold: true })
.insert(' ')
.insert('content', { underline: true })
.insert('\n')
)
Создание редакторов с помощью QullyEditorдемо