Создаем хук useCaretRestore для удобной работы с полями ввода в Vue 3

от автора

в
Время чтения: 2 мин.

В этой статье я покажу, как создать полезный хук useCaretRestore, который сохраняет позицию курсора при изменении содержимого input-полей. Это особенно полезно при работе с текстовыми редакторами, формами и другими элементами ввода.

Зачем нужен этот хук?

Когда мы программно изменяем значение input-поля, курсор обычно перескакивает в конец. Это раздражает пользователей, особенно если они редактируют текст в середине поля. Наш хук решает эту проблему.

Реализация хука

Создадим файл useCaretRestore.ts:

import { nextTick } from 'vue'
import type { Ref } from 'vue'

export function useCaretRestore(inputRef: Ref<HTMLInputElement | null>) {
  function withCaretRestore(callback: () => void) {
    // Запоминаем текущую позицию курсора
    const caretPosition = inputRef.value?.selectionStart

    // Если поле не существует, ничего не делаем
    if (caretPosition === undefined) return

    // Выполняем переданную функцию
    callback()

    // После обновления DOM возвращаем курсор на место
    nextTick(() => {
      inputRef.value?.setSelectionRange(caretPosition, caretPosition)
    })
  }

  return { withCaretRestore }
}

Простые примеры использования

1. Вставка текста по кнопке

Добавим кнопку для вставки стандартного текста:

<script setup>
import { ref } from 'vue'
import { useCaretRestore } from './useCaretRestore'

const inputRef = ref(null)
const message = ref('')
const { withCaretRestore } = useCaretRestore(inputRef)

function insertGreeting() {
  withCaretRestore(() => {
    message.value += 'Здравствуйте! '
  })
}
</script>

<template>
  <input ref="inputRef" v-model="message" placeholder="Введите сообщение">
  <button @click="insertGreeting">Добавить приветствие</button>
</template>

2. Вставка смайликов

Создадим кнопки для быстрой вставки эмодзи:

<script setup>
const comment = ref('')
const inputRef = ref(null)
const { withCaretRestore } = useCaretRestore(inputRef)

function insertEmoji(emoji: string) {
  withCaretRestore(() => {
    comment.value += emoji
  })
}
</script>

<template>
  <input ref="inputRef" v-model="comment" placeholder="Оставьте комментарий">
  <button @click="insertEmoji('😊')">😊</button>
  <button @click="insertEmoji('👍')">👍</button>
  <button @click="insertEmoji('❤️')">❤️</button>
</template>

Как это работает?

  1. Когда пользователь нажимает кнопку, хук запоминает текущее положение курсора
  2. Выполняется переданная функция (например, вставка текста)
  3. После обновления DOM хук возвращает курсор на прежнюю позицию

Преимущества нашего решения

  • Простота использования: Достаточно обернуть изменение в withCaretRestore
  • Универсальность: Работает с любыми input-элементами
  • Автоматическая очистка: Не нужно беспокоиться о подписках на события

Заключение

Хук useCaretRestore — это небольшой, но полезный инструмент, который сделает работу с формами более удобной для пользователей. Попробуйте использовать его в своих проектах!


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Сколько будет 5 + 7?