> For the complete documentation index, see [llms.txt](https://capsbold.gitbook.io/guide/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://capsbold.gitbook.io/guide/vue/pinia.md).

# Pinia

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

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. Нам нужно наиболее предсказуемое поведение приложений.

```typescript
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, а также для создания фильтров для данных.

```typescript
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

```typescript
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. Мы должны сразу понимать что за сущность мы принимаем в событии.
