События компонентов

В Naive UI события компонентов играют ключевую роль в управлении интерактивностью и реактивностью пользовательского интерфейса. В отличие от стандартного DOM-события, Naive UI предоставляет собственный механизм эмиссии событий через свойства on и через функции emit, что позволяет более гибко и типизировано управлять поведением компонентов.


Эмиссия событий через emit

Каждый компонент Naive UI, созданный с помощью defineComponent или доступный из библиотеки, может вызывать события с помощью функции emit. Функция emit обычно передается в setup-функцию:

import { defineComponent } from 'vue';
import { NButton } from 'naive-ui';

export default defineComponent({
  components: { NButton },
  setup(props, { emit }) {
    const handleClick = () => {
      emit('custom-click', { timestamp: Date.now() });
    };

    return { handleClick };
  },
  template: `
    <n-button @click="handleClick">Нажми меня</n-button>
  `
});

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

  • Имя события (custom-click) может быть любым, но рекомендуется использовать камеру с дефисом для ясности.
  • Второй аргумент функции emit — это данные, которые будут переданы родительскому компоненту.
  • Эмиссия событий позволяет реализовать паттерн “child-to-parent communication”, аналогичный v-model.

Прослушивание событий

Для отслеживания событий компонента используется директива v-on (@) в шаблоне:

<n-button @custom-click="onButtonClick">Нажми меня</n-button>
methods: {
  onButtonClick(event) {
    console.log('Произошло событие:', event.timestamp);
  }
}

Особенности в Naive UI:

  • Многие компоненты уже имеют встроенные события, такие как update:value, change, focus, blur.
  • Для v-model Naive UI часто использует кастомные события вида update:modelValue.
  • Поддерживаются модификаторы событий, например .stop и .prevent.

События управления состоянием компонентов

Naive UI компоненты предоставляют специальные события для управления состоянием, которые упрощают реактивное связывание данных.

Пример с NInput:

<template>
  <n-input v-model:value="text" @focus="onFocus" @blur="onBlur" />
</template>

<script>
export default {
  data() {
    return { text: '' };
  },
  methods: {
    onFocus() {
      console.log('Поле ввода в фокусе');
    },
    onBlur() {
      console.log('Поле ввода потеряло фокус');
    }
  }
}
</script>

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

  • v-model:value автоматически связывает значение с событием update:value.
  • События focus и blur позволяют отслеживать пользовательское взаимодействие.
  • Аналогично для компонентов NCheckbox, NRadio, NSwitch существуют события update:value, change, которые помогают синхронизировать данные формы.

Динамическая подписка на события

Иногда требуется подписываться на события программно. В setup-функции можно использовать onMounted и ref для доступа к компоненту:

import { ref, onMounted } from 'vue';
import { NInput } from 'naive-ui';

export default {
  setup() {
    const inputRef = ref(null);

    onMounted(() => {
      inputRef.value?.$on('update:value', (val) => {
        console.log('Значение изменилось на:', val);
      });
    });

    return { inputRef };
  },
  template: `<n-input ref="inputRef" />`
};

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

  • Такой подход позволяет добавлять подписки динамически, особенно при работе с компонентами, создаваемыми через v-for.
  • Необходимо помнить о корректном удалении слушателей при демонтировании компонента, чтобы избежать утечек памяти.

Комбинирование событий и реактивных данных

В Naive UI часто используется реактивное управление состоянием через события:

<template>
  <n-switch v-model:value="isEnabled" @update:value="onToggle" />
</template>

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

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

    const onTog gle = (val) => {
      console.log('Переключатель изменен:', val);
    };

    return { isEnabled, onToggle };
  }
}
</script>

Выводы:

  • v-model и событие update:value работают синхронно.
  • Можно выполнять дополнительные действия при изменении состояния компонента.
  • Такой подход обеспечивает чистую реактивную архитектуру, отделяя визуальную часть от бизнес-логики.

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

Для более сложных компонентов рекомендуется определять события через defineEmits:

import { defineComponent, defineEmits } from 'vue';

export default defineComponent({
  setup() {
    const emit = defineEmits(['submit', 'cancel']);

    const handleSubmit = () => {
      emit('submit', { success: true });
    };

    const handleCancel = () => {
      emit('cancel');
    };

    return { handleSubmit, handleCancel };
  }
});

Преимущества:

  • Явная декларация событий повышает читаемость и типизацию.
  • Позволяет использовать TypeScript для строгой проверки данных события.
  • Удобно при создании библиотечных или переиспользуемых компонентов.

Особенности событий в NDataTable и NForm

Компоненты Naive UI, такие как NDataTable и NForm, имеют специфические события для работы с данными:

  • NDataTable: sort, filter, page-change
  • NForm: validate, submit, reset

Пример использования NForm:

<n-form ref="formRef" @submit="onSubmit">
  <n-form-item label="Имя">
    <n-input v-model:value="name" />
  </n-form-item>
</n-form>

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

export default {
  setup() {
    const formRef = ref(null);
    const name = ref('');

    const onSub mit = (values) => {
      console.log('Форма отправлена с данными:', values);
    };

    return { formRef, name, onSubmit };
  }
}
</script>
  • Событие submit передает все значения формы, что упрощает обработку и интеграцию с внешними API.
  • Внутренние события в таких компонентах позволяют контролировать сортировку, фильтрацию и валидацию без лишнего кода.

Практические советы

  1. Использовать v-model для двусторонней привязки, когда это возможно.
  2. Для кастомных событий соблюдать консистентность имен (camelCase внутри setup, kebab-case в шаблоне).
  3. В сложных компонентах объявлять события через defineEmits для улучшенной типизации.
  4. Для динамически создаваемых компонентов использовать ссылки (ref) и подписки на события.
  5. Всегда помнить о чистке подписчиков при демонтировании компонентов.

Система событий Naive UI обеспечивает гибкий, чистый и реактивный подход к управлению взаимодействиями внутри интерфейса, позволяя создавать как простые, так и сложные компоненты с прозрачной архитектурой.