Загрузка данных

В Element Plus загрузка данных является одной из ключевых задач при построении интерактивных интерфейсов. Компоненты, поддерживающие асинхронное получение данных, позволяют строить динамические таблицы, списки, формы и выпадающие элементы. Рассмотрим основные подходы и практические приёмы работы с загрузкой данных в JavaScript с использованием этой библиотеки.


Использование компонента ElTable с асинхронными данными

Компонент ElTable часто применяется для отображения больших наборов данных. Для асинхронной загрузки данных обычно применяется комбинация axios или встроенного fetch с реактивными переменными Vue.

Пример базовой структуры:

<template>
  <el-table :data="tableData" style="width: 100%">
    <el-table-column prop="id" label="ID" width="80" />
    <el-table-column prop="name" label="Имя" />
    <el-table-column prop="email" label="Email" />
  </el-table>
</template>

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

export default {
  setup() {
    const tableData = ref([]);

    const fetchData = async () => {
      try {
        const response = await axios.get('https://jsonplaceholder.typicode.com/users');
        tableData.value = response.data;
      } catch (error) {
        console.error('Ошибка загрузки данных:', error);
      }
    };

    onMounted(fetchData);

    return { tableData };
  },
};
</script>

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

  • Используется реактивная переменная ref для хранения данных.
  • Асинхронная функция fetchData вызывается внутри onMounted, что обеспечивает загрузку данных после инициализации компонента.
  • Компонент ElTable автоматически обновляет отображение при изменении tableData.

Пагинация с загрузкой данных по страницам

Для работы с большими массивами данных часто требуется ленивая загрузка или постраничная пагинация. В Element Plus это реализуется через компонент ElPagination:

<template>
  <el-table :data="pagedData">
    <el-table-column prop="id" label="ID" />
    <el-table-column prop="title" label="Заголовок" />
  </el-table>
  <el-pagination
    :current-page="currentPage"
    :page-size="pageSize"
    :total="totalItems"
    layout="prev, pager, next"
    @current-change="handlePageChange"
  />
</template>

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

export default {
  setup() {
    const currentPage = ref(1);
    const pageSize = ref(5);
    const totalItems = ref(0);
    const pagedData = ref([]);

    const fetchPageData = async (page) => {
      try {
        const response = await axios.get(`https://jsonplaceholder.typicode.com/posts?_page=${page}&_limit=${pageSize.value}`);
        pagedData.value = response.data;
        totalItems.value = Number(response.headers['x-total-count']);
      } catch (error) {
        console.error('Ошибка загрузки страницы:', error);
      }
    };

    const handlePageChange = (page) => {
      currentPage.value = page;
      fetchPageData(page);
    };

    onMounted(() => fetchPageData(currentPage.value));

    return { pagedData, currentPage, pageSize, totalItems, handlePageChange };
  },
};
</script>

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

  • Используется заголовок x-total-count для определения общего числа элементов.
  • handlePageChange автоматически обновляет таблицу при смене страницы.
  • Такой подход позволяет экономить ресурсы при работе с тысячами записей.

Загрузка данных в селекты и автодополнение

Для компонентов ElSelect и ElAutocomplete часто требуется динамическая загрузка опций. Пример с автодополнением:

<template>
  <el-autocomplete
    v-model="query"
    :fetch-suggestions="querySearch"
    placeholder="Введите имя пользователя"
  />
</template>

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

export default {
  setup() {
    const query = ref('');

    const querySearch = async (queryString, callback) => {
      try {
        const response = await axios.get('https://jsonplaceholder.typicode.com/users');
        const results = response.data.filter(user =>
          user.name.toLowerCase().includes(queryString.toLowerCase())
        );
        callback(results.map(user => ({ value: user.name })));
      } catch (error) {
        console.error('Ошибка загрузки данных автодополнения:', error);
      }
    };

    return { query, querySearch };
  },
};
</script>

Примечания:

  • fetch-suggestions принимает функцию с аргументами queryString и callback.
  • Фильтрация данных может быть выполнена как на клиентской стороне, так и на сервере для экономии трафика.
  • callback формирует массив объектов с ключом value, который компонент использует для отображения.

Загрузка файлов с ElUpload

Компонент ElUpload предназначен для отправки файлов на сервер и поддерживает асинхронную обработку, drag-and-drop, множественный выбор файлов.

Пример базовой конфигурации:

<template>
  <el-upload
    class="upload-demo"
    action="https://jsonplaceholder.typicode.com/posts/"
    :on-success="handleSuccess"
    :on-error="handleError"
    :multiple="true"
    :limit="3"
  >
    <el-button>Загрузить файл</el-button>
  </el-upload>
</template>

<script>
export default {
  setup() {
    const handleSuccess = (response, file) => {
      console.log('Файл успешно загружен:', file.name);
    };

    const handleError = (error, file) => {
      console.error('Ошибка загрузки файла:', file.name, error);
    };

    return { handleSuccess, handleError };
  },
};
</script>

Важные моменты:

  • Атрибут action указывает URL сервера для загрузки.
  • on-success и on-error позволяют обрабатывать результат загрузки.
  • Можно задавать ограничения на количество файлов через limit и включать множественный выбор через multiple.

Использование загрузчиков (Loading) при асинхронных запросах

Для улучшения UX при загрузке данных рекомендуется использовать ElLoading, который блокирует интерфейс до завершения асинхронного запроса.

import { ElLoading } from 'element-plus';
import axios from 'axios';

const loadData = async () => {
  const loading = ElLoading.service({ text: 'Загрузка данных...' });
  try {
    const response = await axios.get('/api/data');
    return response.data;
  } catch (error) {
    console.error('Ошибка загрузки:', error);
  } finally {
    loading.close();
  }
};

Преимущества использования ElLoading:

  • Визуальная индикация процесса загрузки.
  • Предотвращает взаимодействие пользователя с интерфейсом до завершения операции.
  • Легко интегрируется с любыми асинхронными функциями.

Поддержка реактивности и кеширования

Для оптимизации многократной загрузки данных рекомендуется хранить полученные данные в реактивных переменных и использовать их повторно. В связке с Vue Composition API можно создать отдельный composable для управления загрузкой:

import { ref } from 'vue';
import axios from 'axios';

export function useDataLoader(url) {
  const data = ref([]);
  const loading = ref(false);
  const error = ref(null);

  const load = async () => {
    loading.value = true;
    try {
      const response = await axios.get(url);
      data.value = response.data;
    } catch (err) {
      error.value = err;
    } finally {
      loading.value = false;
    }
  };

  return { data, loading, error, load };
}

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


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