Фокус менеджмент

Фокус менеджмент в Vue.js представляет собой систему управления состоянием активности элементов интерфейса, обеспечивая правильное взаимодействие пользователя с приложением. Он особенно важен для сложных компонентов, форм и модальных окон, где контроль фокуса влияет на удобство использования и доступность.


Управление фокусом через директивы

Во Vue.js базовый способ работы с фокусом осуществляется через стандартные директивы и модификаторы событий. Основная директива — v-focus (пользовательская) или стандартная комбинация ref + mounted.

<template>
  <input ref="inputField" />
</template>

<script>
export default {
  mounted() {
    this.$refs.inputField.focus();
  }
};
</script>

Пояснение:

  • ref создаёт ссылку на DOM-элемент.
  • Метод focus() устанавливает курсор в указанный элемент после монтирования компонента.

Это обеспечивает автоматический фокус при загрузке компонента.


Реактивное управление фокусом

Vue.js позволяет динамически управлять фокусом с помощью реактивных переменных. Например, при переходе между формами или вкладками.

<template>
  <input :autofocus="isActive" />
</template>

<script>
import { ref, watch } from 'vue';

export default {
  setup() {
    const isActive = ref(false);

    watch(isActive, (newValue) => {
      if (newValue) {
        document.querySelector('input').focus();
      }
    });

    return { isActive };
  }
};
</script>

Ключевые моменты:

  • Использование реактивной переменной isActive позволяет программно контролировать фокус.
  • Слежение через watch обеспечивает своевременное срабатывание при изменении состояния.

Пользовательские директивы для фокуса

Для сложных сценариев удобно создавать собственные директивы. Например, автоматическая установка фокуса при определённых условиях.

// directives/focus.js
export default {
  mounted(el, binding) {
    if (binding.value) {
      el.focus();
    }
  },
  updated(el, binding) {
    if (binding.value) {
      el.focus();
    }
  }
};

Применение в компоненте:

<template>
  <input v-focus="shouldFocus" />
</template>

<script>
import focus from './directives/focus';
import { ref } from 'vue';

export default {
  directives: { focus },
  setup() {
    const shouldFocus = ref(true);
    return { shouldFocus };
  }
};
</script>

Особенности:

  • Директива реагирует на изменения значения и может повторно устанавливать фокус.
  • Упрощает повторное использование логики фокуса в разных компонентах.

Фокус внутри модальных окон

Модальные окна требуют особого внимания к фокусу, чтобы пользователь не мог покинуть окно с клавиатуры до закрытия. Практика включает:

  1. Установка фокуса на первый интерактивный элемент при открытии.
  2. Перенаправление табуляции внутри модального окна (trap focus).
  3. Возврат фокуса на инициирующий элемент после закрытия.

Пример реализации:

<template>
  <div v-if="isOpen" class="modal">
    <input ref="firstInput" />
    <button @click="closeModal">Закрыть</button>
  </div>
</template>

<script>
import { ref, onMounted } from 'vue';

export default {
  setup() {
    const isOpen = ref(true);
    const firstInput = ref(null);
    const activeElementBefore = ref(null);

    const closeModal = () => {
      isOpen.value = false;
      if (activeElementBefore.value) activeElementBefore.value.focus();
    };

    onMounted(() => {
      activeElementBefore.value = document.activeElement;
      if (firstInput.value) firstInput.value.focus();
    });

    return { isOpen, firstInput, closeModal };
  }
};
</script>

Принципы:

  • Сохраняется элемент, который был активен до открытия модального окна.
  • Фокус возвращается после закрытия, обеспечивая непрерывность взаимодействия.

Управление фокусом при динамических компонентах

Vue.js активно использует динамические компоненты (<component :is="...">). Для таких компонентов важно управлять фокусом при их замене или обновлении:

<component :is="currentComponent" @hook:mounted="setFocus" />

Метод setFocus может использовать ссылки или поиск элементов внутри компонента. Этот подход предотвращает потерю фокуса при смене содержимого.


Доступность (Accessibility) и фокус

Правильное управление фокусом напрямую связано с доступностью интерфейса (a11y). В Vue.js рекомендуется:

  • Использовать tabindex для управления порядком навигации по клавише Tab.
  • Устанавливать фокус на ошибки формы или важные уведомления.
  • Применять ARIA-атрибуты совместно с динамическим фокусом (aria-live, aria-modal).

Пример фокуса на ошибке формы:

<template>
  <input ref="emailInput" :class="{ error: hasError }" />
  <span v-if="hasError" role="alert">Ошибка ввода</span>
</template>

<script>
import { ref, watch } from 'vue';

export default {
  setup() {
    const emailInput = ref(null);
    const hasError = ref(false);

    watch(hasError, (value) => {
      if (value && emailInput.value) {
        emailInput.value.focus();
      }
    });

    return { emailInput, hasError };
  }
};
</script>

Важные аспекты:

  • Фокус перемещается на первый элемент с ошибкой.
  • Использование role="alert" совместно с фокусом повышает доступность для экранных читалок.

Фокус менеджмент в Vue.js позволяет создавать интуитивно понятный интерфейс, обеспечивая контроль над пользовательским взаимодействием и соблюдение принципов доступности. Реактивные переменные, пользовательские директивы и внимательное управление динамическими компонентами составляют основу эффективной работы с фокусом в сложных приложениях.