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


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://capsbold.gitbook.io/guide/vue/pinia.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
