Text Editor
Полнофункциональный текстовый редактор с возможностями Word: стили шрифтов, выбор цветов, чек-листы, таблицы, вставка изображений и видео, эмодзи, поиск и замена, сноски, печать, полноэкранный режим и многое другое. Построен на contenteditable без внешних зависимостей.
<script setup>
import { ref } from 'vue'
const content = ref('')
</script>
<template>
<VxTextEditor v-model="content" placeholder="Write something amazing..." />
</template>With Initial Content
<template>
<VxTextEditor v-model="content" />
</template>Image Upload with beforeUpload
Проп beforeUpload получает выбранный объект File. Ваша функция должна загрузить его на сервер и вернуть URL изображения. Редактор вставит изображение, как только URL будет получен.
<script setup>
import { ref } from 'vue'
const content = ref('')
async function handleUpload(file) {
// Upload file to your server
const formData = new FormData()
formData.append('image', file)
const response = await fetch('/api/upload', {
method: 'POST',
body: formData,
})
const data = await response.json()
// Return the URL — the editor inserts <img src="url">
return data.url
}
</script>
<template>
<VxTextEditor
v-model="content"
:before-upload="handleUpload"
:max-file-size="5 * 1024 * 1024"
@upload-error="(err, file) => console.error(err, file)"
/>
</template>Как это работает:
- Пользователь нажимает кнопку изображения на панели → вкладка «Upload» → выбирает файл с диска
- Вызывается
beforeUpload(file)с исходным объектомFile - Ваша функция загружает его на сервер и возвращает строку URL
- Редактор вставляет
<img src="returned-url">в позицию курсора
Также поддерживается:
- Drag & drop — перетащите изображения прямо в редактор
- Вставка из буфера — вставьте изображения из буфера обмена (скриншоты, скопированные изображения)
- Вкладка URL — введите URL изображения вручную в качестве запасного варианта
Resizable Images
Щёлкните по любому изображению в редакторе, чтобы выбрать его. Тяните угловые или боковые маркеры, чтобы изменить размер. Нажмите Delete или Backspace, чтобы удалить выбранное изображение.
<template>
<VxTextEditor v-model="content" :before-upload="handleUpload" />
<!-- Click any inserted image to select it, then drag handles to resize -->
</template>Table
Нажмите кнопку таблицы на панели инструментов, чтобы открыть выбор сетки. Наведите курсор для выбора размера и щёлкните, чтобы вставить.
<template>
<VxTextEditor v-model="content" />
</template>Контекстное меню (правый клик) на любой ячейке:
- Вставить строку выше / ниже
- Вставить столбец слева / справа
- Объединить ячейку справа — объединяет с соседней ячейкой справа (увеличивает colspan)
- Объединить ячейку снизу — объединяет с ячейкой ниже (увеличивает rowspan)
- Разделить ячейку — появляется, когда colspan > 1 или rowspan > 1, разделяет объединённую ячейку обратно
- Управление Colspan / Rowspan — кнопки +/- для установки точных значений
- Удалить строку / столбец / таблицу
Изменение размера столбца — наведите курсор рядом с границей столбца, чтобы увидеть курсор изменения размера, затем тяните.
Font Family & Size
Используйте выпадающие списки семейства и размера шрифта для изменения типографики. Сначала выделите текст, затем выберите шрифт или размер.
<template>
<VxTextEditor
v-model="content"
:toolbar="['fontFamily', 'fontSize', '|', 'bold', 'italic', '|', 'undo', 'redo']"
/>
</template>Text & Highlight Color
Применяйте цвет текста или цвет фонового выделения к выделенному тексту. Выбирайте из 80 предустановленных цветов.
<template>
<VxTextEditor
v-model="content"
:toolbar="['bold', 'italic', '|', 'textColor', 'highlightColor', '|', 'undo', 'redo']"
/>
</template>Checklist
Создавайте интерактивные чек-листы. Щёлкните область флажка, чтобы переключить элементы.
<template>
<VxTextEditor
v-model="content"
:toolbar="['checklist', '|', 'bulletList', 'orderedList', '|', 'bold', 'italic', '|', 'undo', 'redo']"
/>
</template>Video Embed
Встраивайте видео с YouTube или Vimeo. Нажмите кнопку видео, вставьте URL, и редактор добавит адаптивный iframe.
<template>
<VxTextEditor
v-model="content"
:toolbar="['video', 'image', 'link', '|', 'bold', 'italic', '|', 'undo', 'redo']"
/>
</template>Import & Export
Импортируйте документы Word (.docx/.doc), экспортируйте в Word или в PDF. Кнопки на панели инструментов используют Vexel Icons.
<script setup>
import { ref } from 'vue'
const content = ref('')
</script>
<template>
<VxTextEditor
v-model="content"
:toolbar="[
'bold', 'italic', 'underline', '|',
'heading1', 'heading2', '|',
'bulletList', 'orderedList', '|',
'importWord', 'exportWord', 'exportPdf',
]"
/>
</template>Возможности:
- Импорт Word — Нажмите значок импорта, чтобы выбрать файл
.docxили.doc. Содержимое разбирается и вставляется в редактор. - Экспорт Word — Загружает содержимое редактора в виде совместимого с Word файла
.docс корректным форматированием, таблицами и стилями. - Экспорт PDF — Открывает диалог печати браузера для сохранения в PDF с чистой таблицей стилей для печати.
Full-Featured
Включены все Word-подобные элементы панели инструментов — стили шрифтов, цвета, списки, медиа, эмодзи, специальные символы, поиск и замена, сноски, разрывы страниц, печать и полноэкранный режим.
<template>
<VxTextEditor v-model="content" :before-upload="handleUpload" show-word-count show-character-count />
</template>Custom Toolbar
Передайте собственный массив элементов панели инструментов. Используйте '|' для разделителей.
<template>
<VxTextEditor
v-model="content"
:toolbar="['bold', 'italic', 'underline', '|', 'bulletList', 'orderedList', '|', 'image', 'link', '|', 'undo', 'redo']"
:before-upload="handleUpload"
/>
</template>No Toolbar
Установите :toolbar="false", чтобы полностью скрыть панель инструментов. Сочетания клавиш продолжают работать.
<template>
<VxTextEditor v-model="content" :toolbar="false" />
</template>Word & Character Count
<template>
<VxTextEditor v-model="content" show-word-count show-character-count />
</template>Min / Max Height
<template>
<VxTextEditor v-model="content" min-height="100px" max-height="300px" />
</template>Read Only
<template>
<VxTextEditor v-model="content" readonly />
</template>Disabled
<template>
<VxTextEditor model-value="<p>Disabled content</p>" disabled />
</template>HTML Output
<script setup>
import { ref } from 'vue'
const content = ref('')
</script>
<template>
<VxTextEditor v-model="content" />
<pre>{{ content }}</pre>
</template>Toolbar Items
Все доступные элементы панели инструментов:
| Item | Description |
|---|---|
fontFamily | Выпадающий список семейства шрифтов (Arial, Times New Roman, Georgia и т. д.) |
fontSize | Выпадающий список размера шрифта (8px – 72px) |
bold | Жирный текст |
italic | Курсив |
underline | Подчёркнутый текст |
strikethrough | Зачёркнутый текст |
heading1 – heading6 | Заголовки уровней 1–6 |
textColor | Выбор цвета текста (80 предустановленных цветов) |
highlightColor | Выбор цвета фонового выделения |
bulletList | Маркированный список |
orderedList | Нумерованный список |
checklist | Интерактивный чек-лист с флажками |
blockquote | Цитата |
code | Инлайн-код |
codeBlock | Блок кода |
link | Вставить/редактировать ссылку |
image | Загрузить изображение или вставить по URL |
video | Встроить видео с YouTube или Vimeo |
table | Вставить таблицу через сетку выбора; правый клик по ячейкам для действий со строками/столбцами/объединением |
emoji | Выбор эмодзи (80 эмодзи) |
specialChars | Выбор специальных символов (60 символов) |
alignLeft | Выровнять по левому краю |
alignCenter | Выровнять по центру |
alignRight | Выровнять по правому краю |
alignJustify | Выровнять по ширине |
indent | Увеличить отступ |
outdent | Уменьшить отступ |
lineHeight | Выбор межстрочного интервала (1.0 – 3.0) |
horizontalRule | Горизонтальная линия |
pageBreak | Вставить разрыв страницы |
footnote | Вставить нумерованную сноску |
subscript | Нижний индекс |
superscript | Верхний индекс |
findReplace | Панель поиска и замены с навигацией вперёд/назад |
undo | Отменить |
redo | Повторить |
clear | Очистить форматирование |
print | Печать содержимого редактора |
fullscreen | Переключить полноэкранный режим редактирования |
| | Разделитель |
Props
| Prop | Type | Default | Description |
|---|---|---|---|
modelValue | string | '' | HTML-содержимое (v-model) |
placeholder | string | 'Start writing...' | Текст подсказки |
disabled | boolean | false | Отключить редактор |
readonly | boolean | false | Режим «только для чтения» |
toolbar | TextEditorToolbarItem[] | false | Default toolbar | Конфигурация панели инструментов |
minHeight | string | '200px' | Минимальная высота редактора |
maxHeight | string | undefined | Максимальная высота редактора (включает прокрутку) |
showCharacterCount | boolean | false | Показывать счётчик символов |
showWordCount | boolean | false | Показывать счётчик слов |
autofocus | boolean | false | Автофокус при монтировании |
beforeUpload | (file: File) => Promise<string> | string | undefined | Обработчик загрузки — получает файл, должен вернуть URL изображения |
accept | string | 'image/*' | Допустимые типы файлов для поля загрузки |
maxFileSize | number | undefined | Максимальный размер файла в байтах |
Events
| Event | Payload | Description |
|---|---|---|
update:modelValue | string | Вызывается при изменении содержимого |
focus | FocusEvent | Вызывается, когда редактор получает фокус |
blur | FocusEvent | Вызывается, когда редактор теряет фокус |
change | string | Вызывается при изменении содержимого |
uploadError | (error: Error, file: File) | Вызывается при ошибке загрузки изображения или превышении лимита размера |
Exposed Methods
| Method | Description |
|---|---|
focus() | Сфокусировать редактор |
blur() | Снять фокус с редактора |
getHTML() | Получить текущее HTML-содержимое |
getText() | Получить текущий обычный текст |
exec(command, value?) | Выполнить команду документа |