В 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.Для улучшения 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, эффективно загружать данные, управлять состояниями и обрабатывать ошибки без потери производительности.