Quasar Framework предоставляет гибкую систему управления состоянием
через Vuex или Composition API с использованием
pinia. Типизация stores является ключевым элементом при
разработке сложных приложений, поскольку она обеспечивает
безопасность типов, автодополнение и
предотвращает ошибки на этапе компиляции. Рассмотрим
детально подходы к типизации stores и практические рекомендации.
В Quasar с Vue 2/3 часто используется Vuex. Основная цель — определить структуру состояния, геттеров, мутаций и экшенов.
interface UserState {
id: number;
name: string;
email: string;
isLoggedIn: boolean;
}
const state: UserState = {
id: 0,
name: '',
email: '',
isLoggedIn: false
};
UserState задаёт строгую
структуру состояния.state в
геттерах и компонентах.import { MutationTree } from 'vuex';
const mutations: MutationTree<UserState> = {
setUser(state, payload: { id: number; name: string; email: string }) {
state.id = payload.id;
state.name = payload.name;
state.email = payload.email;
state.isLoggedIn = true;
},
logout(state) {
state.id = 0;
state.name = '';
state.email = '';
state.isLoggedIn = false;
}
};
MutationTree<UserState>
гарантирует, что все мутации соответствуют типу
состояния.payload, что
предотвращает передачу неверных данных.import { GetterTree } from 'vuex';
const getters: GetterTree<UserState, any> = {
userName: (state) => state.name,
isAuthenticated: (state) => state.isLoggedIn
};
GetterTree<UserState, RootState> обеспечивает
строгую проверку возвращаемых типов.import { ActionTree } from 'vuex';
const actions: ActionTree<UserState, any> = {
login({ commit }, payload: { id: number; name: string; email: string }) {
commit('setUser', payload);
},
logout({ commit }) {
commit('logout');
}
};
ActionTree<State, RootState>.Pinia — современная альтернатива Vuex, которая встроена в Quasar с Vue 3. Она поддерживает полную интеграцию TypeScript без дополнительной сложности.
import { defineStore } from 'pinia';
interface Todo {
id: number;
title: string;
completed: boolean;
}
interface TodoState {
todos: Todo[];
}
export const useTodoStore = defineStore('todo', {
state: (): TodoState => ({
todos: []
}),
getters: {
completedTodos: (state) => state.todos.filter(todo => todo.completed)
},
actions: {
addTodo(todo: Todo) {
this.todos.push(todo);
},
toggleTodo(id: number) {
const todo = this.todos.find(t => t.id === id);
if (todo) todo.completed = !todo.completed;
}
}
});
Todo и
TodoState задают строгую структуру данных.state, getters
и actions.actions автоматически получают правильные типы
для this.import { ref, computed } from 'vue';
import { defineStore } from 'pinia';
export const useCounterStore = defineStore('counter', () => {
const count = ref<number>(0);
const double = computed(() => count.value * 2);
function increment(amount: number) {
count.value += amount;
}
return { count, double, increment };
});
ref<number> и computed
позволяет явно указать тип состояния.increment гарантирует, что
передаваемые значения всегда соответствуют ожидаемому типу.defineStore с Pinia в новых
проектах. Типизация встроена и проще в поддержке.import { useTodoStore } from 'stores/todo';
export default {
setup() {
const todoStore = useTodoStore();
function addNewTodo() {
todoStore.addTodo({ id: 1, title: 'Learn Quasar', completed: false });
}
return { todoStore, addNewTodo };
}
};
todoStore.addTodo
принимает объект строго типа Todo.Типизация stores в Quasar является основой для устойчивых, масштабируемых и безопасных приложений, обеспечивая строгую проверку типов на каждом уровне управления состоянием.