Для начала необходимо установить Pinia в проект на Vue 3, где используется Element Plus. Pinia является официальной заменой Vuex и обеспечивает современный подход к управлению состоянием.
npm install pinia
После установки Pinia, необходимо подключить его в корневом файле
приложения main.js или main.ts:
import { createApp } from 'vue';
import { createPinia } from 'pinia';
import App from './App.vue';
import ElementPlus from 'element-plus';
import 'element-plus/dist/index.css';
const app = createApp(App);
const pinia = createPinia();
app.use(pinia);
app.use(ElementPlus);
app.mount('#app');
Теперь Pinia полностью интегрирован с приложением, и можно создавать хранилища для управления состоянием.
Хранилище создается с помощью функции defineStore. Для
управления элементами интерфейса Element Plus удобно хранить состояние,
например, модальных окон, уведомлений или таблиц.
import { defineStore } from 'pinia';
export const useUiStore = defineStore('ui', {
state: () => ({
dialogVisible: false,
loading: false,
notification: {
message: '',
type: 'success'
}
}),
actions: {
openDialog() {
this.dialogVisible = true;
},
closeDialog() {
this.dialogVisible = false;
},
setLoading(value) {
this.loading = value;
},
notify(message, type = 'success') {
this.notification.message = message;
this.notification.type = type;
}
}
});
Ключевые моменты:
state определяет реактивные свойства.actions содержат методы для изменения состояния.Компоненты Element Plus, такие как ElDialog, легко
управляются через хранилище Pinia:
<template>
<el-button @click="uiStore.openDialog">Открыть диалог</el-button>
<el-dialog :visible.sync="uiStore.dialogVisible" title="Пример">
<p>Содержимое диалога</p>
<span slot="footer" class="dialog-footer">
<el-button @click="uiStore.closeDialog">Закрыть</el-button>
</span>
</el-dialog>
</template>
<script setup>
import { useUiStore } from '@/stores/ui';
const uiStore = useUiStore();
</script>
Особенности интеграции:
:visible.sync связывает состояние диалога с реактивным
свойством хранилища.Element Plus предоставляет ElNotification для
отображения уведомлений:
import { ElNotification } from 'element-plus';
import { useUiStore } from '@/stores/ui';
const uiStore = useUiStore();
function showNotification() {
ElNotification({
title: 'Уведомление',
message: uiStore.notification.message,
type: uiStore.notification.type
});
}
Можно расширить хранилище Pinia, чтобы автоматически отображать уведомления при изменении состояния.
При работе с ElTable удобно хранить данные, состояние
загрузки и фильтры в хранилище Pinia:
import { defineStore } from 'pinia';
export const useTableStore = defineStore('table', {
state: () => ({
data: [],
loading: false,
filters: {}
}),
actions: {
async fetchData() {
this.loading = true;
try {
// пример запроса к API
const response = await fetch('/api/items');
this.data = await response.json();
} finally {
this.loading = false;
}
},
setFilter(key, value) {
this.filters[key] = value;
}
}
});
Компонент таблицы может использовать хранилище напрямую:
<template>
<el-table :data="tableStore.data" v-loading="tableStore.loading">
<el-table-column prop="name" label="Название" />
<el-table-column prop="price" label="Цена" />
</el-table>
</template>
<script setup>
import { useTableStore } from '@/stores/table';
const tableStore = useTableStore();
tableStore.fetchData();
</script>
Преимущества подхода:
Pinia предоставляет возможность отслеживать реактивные свойства с
помощью watch или store.$subscribe. Это
полезно для автоматического обновления компонентов Element Plus при
изменении состояния:
import { watch } from 'vue';
import { useUiStore } from '@/stores/ui';
const uiStore = useUiStore();
watch(() => uiStore.notification.message, (newMessage) => {
if (newMessage) {
ElNotification({
title: 'Уведомление',
message: newMessage,
type: uiStore.notification.type
});
}
});
Преимущество Pinia заключается в полной совместимости с Composition
API. Это позволяет использовать ref, computed
и другие реактивные инструменты для интеграции с Element Plus:
import { computed } from 'vue';
import { useTableStore } from '@/stores/table';
const tableStore = useTableStore();
const filteredData = computed(() => {
return tableStore.data.filter(item => item.name.includes(tableStore.filters.name || ''));
});
filteredData можно использовать напрямую в
ElTable, что делает реактивное обновление таблиц
максимально удобным.
actions для асинхронных операций, таких
как API-запросы.computed и watch для реактивного
взаимодействия с компонентами Element Plus.Интеграция Pinia с Element Plus обеспечивает высокую управляемость состояния и упрощает разработку сложных интерфейсов на Vue 3.