🍍Pinia

Руководство по использованию Pinia & TypeScript

Когда использовать?

Pinia используем, когда приложение требует особого контроля и мониторинга данных. В иных случаях будет достаточно самописных db.js файлов или глобальных прототипов Vue.

Также Pinia используется вместо Vuex особенно тогда, когда в проекте используется TypeScript.

Разделение бизнес-логики и интерфейса

Pinia запрещено использовать для управления элементами интерфейса (например, добавлять флаги и индикаторы для модальных окон, пагинации, кнопок и т.п.)

Pinia используется только для хранения бизнес-логики приложения: пользователи, настройки, ключи и т.п...

Структура папок

  • store

    • users

      • actions.ts

      • getters.ts

      • index.ts

      • state.ts

    • other-store

state

Если мы работаем с API и храним полученные от него данные, то они должны оставаться в том же виде, в котором мы их получили с сервера - неизменными. Если какие-либо данные нам нужны в отсортированном виде (либо любом другом), то добавляем в getters новое значение.

Данные из state могут использоваться для чтения в любом месте Vue приложения.

Старайтесь избегать изменений свойств объектов из state. Нам нужно наиболее предсказуемое поведение приложений.

import User from '~/models/user.model';

export interface UserState {
  users: User[],
  user: User|null
}

export const useUsersStore = defineStore('users', {
  state: (): UserState => {
    return {
      users: [],
      user: null
    }
  },
  
  // getters, actions...
});

getters

Геттеры мы используем только для получения данных из state, а также для создания фильтров для данных.

import User from '~/models/user.model';

export interface UserState {
  users: User[],
  user: User|null
}

export const useUsersStore = defineStore('users', {
  // state, actions...

  getters: {
    allUsers({ users }: UserState) {
      return users;
    },
    
    vipUsers: ({ users }: UserState) => (isVip: boolean) => {
      return users.filter((user) => user.is_vip === isVip );
    }
  }
});

actions

import User from '~/models/user.model';
import api from '~/api';
import { showTooltip } from '~/utils';

export interface UserState {
  users: User[],
  user: User|null
}

export const useUsersStore = defineStore('users', {
  // state...

  actions: {
    setUsers(users: User[]) {
      this.users = users;
    },
    
    async loginUser(login: string, password: string) {
      try {
        this.user = await api.login({ login, password });
        showTooltip(`Welcome back ${this.user.name}!`);
      } catch (error) {
        showTooltip(error);
        return error;
      }
    },
  },
  
  // getters...
});

Мы никогда не передаём название параметра как payload. Мы должны сразу понимать что за сущность мы принимаем в событии.

Last updated