Композиционные функции (composables)

Композиционные функции (composables) — это функция, которая инкапсулирует реактивную логику и может быть повторно использована в нескольких компонентах Vue. В контексте Element Plus composables позволяют интегрировать функциональность компонентов с реактивными данными и методами без дублирования кода.

Реактивность и ref

Для работы с composables используется реактивная система Vue. Наиболее часто применяются ref и reactive:

import { ref, reactive } from 'vue';

export function useInput() {
  const value = ref('');
  const error = ref(null);

  function validate() {
    error.value = value.value.length > 0 ? null : 'Поле обязательно для заполнения';
  }

  return { value, error, validate };
}

Здесь useInput является composable, который можно подключить к любому компоненту с формой или полем ввода. Он управляет состоянием значения и ошибки, а также предоставляет метод validate() для проверки.

Использование composables с компонентами Element Plus

В Element Plus многие компоненты поддерживают работу с реактивными значениями напрямую через v-model:

<template>
  <el-input
    v-model="input.value"
    @blur="input.validate"
    placeholder="Введите текст"
  />
  <span v-if="input.error" class="error">{{ input.error }}</span>
</template>

<script setup>
import { useInput } from './composables/useInput';

const input = useInput();
</script>

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

Использование реактивных объектов

Для более сложных данных можно применять reactive:

import { reactive } from 'vue';

export function useForm() {
  const form = reactive({
    username: '',
    email: '',
    password: ''
  });

  function reset() {
    form.username = '';
    form.email = '';
    form.password = '';
  }

  return { form, reset };
}

При подключении к Element Plus Form:

<template>
  <el-form :model="form.form">
    <el-form-item label="Имя пользователя">
      <el-input v-model="form.form.username" />
    </el-form-item>
    <el-form-item label="Email">
      <el-input v-model="form.form.email" />
    </el-form-item>
    <el-button type="primary" @click="form.reset">Сбросить</el-button>
  </el-form>
</template>

<script setup>
import { useForm } from './composables/useForm';

const form = useForm();
</script>

Работа с Element Plus компонентами через composables

Element Plus предоставляет composables для своих компонентов, такие как:

  • useMessage — для всплывающих сообщений;
  • useDialog — для управления диалогами;
  • useLoading — для создания индикаторов загрузки.

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

import { useMessage } from 'element-plus';

export function useNotifier() {
  const message = useMessage();

  function success(msg) {
    message.success(msg);
  }

  function error(msg) {
    message.error(msg);
  }

  return { success, error };
}

В компоненте:

<template>
  <el-button type="success" @click="notify.success('Операция выполнена')">
    Показать сообщение
  </el-button>
</template>

<script setup>
import { useNotifier } from './composables/useNotifier';

const notify = useNotifier();
</script>

Создание универсальных composables

Composables позволяют инкапсулировать повторяющиеся действия:

  • Работа с модальными окнами:
import { ref } from 'vue';

export function useDialog() {
  const visible = ref(false);

  function open() {
    visible.value = true;
  }

  function close() {
    visible.value = false;
  }

  return { visible, open, close };
}
  • Использование с компонентом ElDialog:
<template>
  <el-dialog :visible.sync="dialog.visible">
    <p>Содержимое диалога</p>
    <span slot="footer">
      <el-button @click="dialog.close">Закрыть</el-button>
    </span>
  </el-dialog>

  <el-button type="primary" @click="dialog.open">Открыть диалог</el-button>
</template>

<script setup>
import { useDialog } from './composables/useDialog';

const dialog = useDialog();
</script>

Составные composables

Composables могут быть вложенными. Например, форма с уведомлением:

import { useForm } from './useForm';
import { useNotifier } from './useNotifier';

export function useUserForm() {
  const form = useForm();
  const notifier = useNotifier();

  function submit() {
    if (!form.form.username || !form.form.email) {
      notifier.error('Заполните все поля');
      return;
    }
    notifier.success('Форма отправлена');
  }

  return { form, submit };
}

Это позволяет создавать комплексные, но легко поддерживаемые модули логики для компонентов Element Plus.

Рекомендации по структуре

  1. Выделять логику в отдельные файлы composables (useXYZ.js или useXYZ.ts).
  2. Возвращать объекты с реактивными свойствами и методами.
  3. Использовать composables Element Plus, когда возможно, для интеграции с UI-функциями.
  4. Следить за чистотой composables, чтобы не смешивать состояние разных компонентов.

Composables становятся основой для построения масштабируемых приложений на Vue с Element Plus, позволяя разделять логику и интерфейс и облегчать тестирование и повторное использование кода.