Skip to content

Events ​

The QuillyEditor component emits various events that allow you to respond to user interactions and content changes.

Event List ​

All events are fully typed for TypeScript support.

update:modelValue ​

Emitted when the editor content changes (for v-model binding).

Type:

typescript
(value: string) => void

Parameters:

  • value: string - The updated HTML content

Example:

vue
<script setup lang="ts">
const content = ref('')

const onUpdate = (value: string) => {
  console.log('Content updated:', value)
}
</script>

<template>
  <QuillyEditor 
    v-model="content"
    @update:model-value="onUpdate"
  />
</template>

text-change ​

Emitted when the editor content changes (text, formatting, or both).

Type:

typescript
({
  delta: Delta
  oldContent: Delta
  source: EmitterSource
}) => void

Parameters:

  • delta: Delta - Change delta representing the modifications
  • oldContent: Delta - Previous editor content as Delta
  • source: EmitterSource - Source of the change ('user', 'api', or 'silent')

Example:

vue
<script setup lang="ts">
import type { Delta, EmitterSource } from 'quill/core'

const onTextChange = ({ 
  delta, 
  oldContent, 
  source 
}: { 
  delta: Delta
  oldContent: Delta
  source: EmitterSource 
}) => {
  if (source === 'user') {
    console.log('User made changes:', delta)
  }
}
</script>

<template>
  <QuillyEditor @text-change="onTextChange" />
</template>

Use cases:

  • Track user edits
  • Implement auto-save functionality
  • Sync content to server
  • Trigger validation

selection-change ​

Emitted when the user selection (cursor position or text selection) changes.

Type:

typescript
({
  range: Range
  oldRange: Range
  source: EmitterSource
}) => void

Parameters:

  • range: Range - New selection range (null when editor loses focus)
  • oldRange: Range - Previous selection range
  • source: EmitterSource - Source of the change

Range type:

typescript
interface Range {
  index: number  // Starting position
  length: number // Length of selection (0 for cursor)
}

Example:

vue
<script setup lang="ts">
import type { Range, EmitterSource } from 'quill/core'

const onSelectionChange = ({ 
  range, 
  oldRange, 
  source 
}: { 
  range: Range
  oldRange: Range
  source: EmitterSource 
}) => {
  if (range) {
    if (range.length === 0) {
      console.log('Cursor at position:', range.index)
    } else {
      console.log('Selection from', range.index, 'to', range.index + range.length)
    }
  } else {
    console.log('Editor lost focus')
  }
}
</script>

<template>
  <QuillyEditor @selection-change="onSelectionChange" />
</template>

Use cases:

  • Show custom formatting toolbar
  • Display character/word count for selection
  • Implement custom context menus
  • Track cursor position

editor-change ​

Emitted for both text and selection changes. Useful when you need to respond to any editor change.

Type:

typescript
(eventName: 'text-change' | 'selection-change') => void

Parameters:

  • eventName: 'text-change' | 'selection-change' - Type of change

Example:

vue
<script setup lang="ts">
const onEditorChange = (eventName: 'text-change' | 'selection-change') => {
  console.log('Editor changed:', eventName)
  // Perform actions common to both events
}
</script>

<template>
  <QuillyEditor @editor-change="onEditorChange" />
</template>

ready ​

Emitted when the Quill editor is fully initialized and ready to use.

Type:

typescript
(quill: Quill) => void

Parameters:

  • quill: Quill - The initialized Quill instance

Example:

vue
<script setup lang="ts">
import type Quill from 'quill'

const onReady = (quill: Quill) => {
  console.log('Editor ready!', quill)
  
  // Perform initial setup
  quill.setSelection(0, 0)
  quill.focus()
}
</script>

<template>
  <QuillyEditor @ready="onReady" />
</template>

Use cases:

  • Initial editor configuration
  • Set initial focus
  • Load saved selection
  • Register custom formats

focus ​

Emitted when the editor gains focus.

Type:

typescript
(quill: Quill) => void

Parameters:

  • quill: Quill - The Quill instance

Example:

vue
<script setup lang="ts">
import type Quill from 'quill'

const onFocus = (quill: Quill) => {
  console.log('Editor focused')
  // Show formatting toolbar, etc.
}
</script>

<template>
  <QuillyEditor @focus="onFocus" />
</template>

blur ​

Emitted when the editor loses focus.

Type:

typescript
(quill: Quill) => void

Parameters:

  • quill: Quill - The Quill instance

Example:

vue
<script setup lang="ts">
import type Quill from 'quill'

const onBlur = (quill: Quill) => {
  console.log('Editor blurred')
  // Auto-save content, hide toolbar, etc.
}
</script>

<template>
  <QuillyEditor @blur="onBlur" />
</template>

Use cases:

  • Auto-save on blur
  • Hide custom toolbars
  • Validate content
  • Update preview

Complete Example ​

Example using all events together:

vue
<script setup lang="ts">
import { ref } from 'vue'
import { QuillyEditor } from 'vue-quilly'
import type Quill from 'quill'
import type { Delta, Range, EmitterSource } from 'quill/core'

const content = ref('')
const isFocused = ref(false)
const selectionInfo = ref('')

const onUpdate = (value: string) => {
  console.log('✅ Content updated')
}

const onTextChange = ({ delta, source }: {
  delta: Delta
  oldContent: Delta
  source: EmitterSource
}) => {
  if (source === 'user') {
    console.log('✏️ User edited content')
  }
}

const onSelectionChange = ({ range }: {
  range: Range
  oldRange: Range
  source: EmitterSource
}) => {
  if (range) {
    if (range.length === 0) {
      selectionInfo.value = `Cursor at ${range.index}`
    } else {
      selectionInfo.value = `Selected ${range.length} characters`
    }
  }
}

const onEditorChange = (eventName: 'text-change' | 'selection-change') => {
  console.log('📝 Editor changed:', eventName)
}

const onReady = (quill: Quill) => {
  console.log('🚀 Editor ready!')
}

const onFocus = () => {
  isFocused.value = true
  console.log('👁️ Editor focused')
}

const onBlur = () => {
  isFocused.value = false
  console.log('💤 Editor blurred')
}
</script>

<template>
  <div>
    <div class="status">
      <span>{{ isFocused ? '🟢 Focused' : '⚫ Not focused' }}</span>
      <span>{{ selectionInfo }}</span>
    </div>
    
    <QuillyEditor
      v-model="content"
      @update:model-value="onUpdate"
      @text-change="onTextChange"
      @selection-change="onSelectionChange"
      @editor-change="onEditorChange"
      @ready="onReady"
      @focus="onFocus"
      @blur="onBlur"
    />
  </div>
</template>

Event Sources ​

The source parameter in events indicates how the change was triggered:

SourceDescription
'user'User interaction (typing, clicking, etc.)
'api'Programmatic change via Quill API
'silent'Change that shouldn't trigger handlers

Example:

typescript
const onTextChange = ({ source }: { source: EmitterSource }) => {
  if (source === 'user') {
    // Only react to user changes
    autoSave()
  }
}

See Also ​