pinia基础

187 阅读3分钟

前言

Pinia.js 是新一代的状态管理器,由 Vue.js团队中成员所开发的,是下一代的 Vuex。 具体使用方法查看pinia

Pinia.js 有如下特点:
  • 完整的 typescript 的支持;
  • 足够轻量,压缩后的体积只有1.6kb;
  • 去除 mutations,只有 state,getters,actions(这是我最喜欢的一个特点);
  • actions 支持同步和异步;
  • 没有模块嵌套,只有 store 的概念,store 之间可以自由使用,更好的代码分割;
  • 无需手动添加 store,store 一旦创建便会自动添加;

安装

pnpm i pinia -S

使用

创建Store

新建src/store/index.js文件;

// 创建store
import { createPinia } from 'pinia';
const store = createPinia();
export default store;

创建State

新建src/store/user.js文件;

// 创建state
import { defineStore } from 'pinia';
export default defineStore({
    id: 'user', // id必填,且需要唯一
    state: () => ({
        size: 'small',
        token: '',
    }),
});

使用State

<template>
  <div>{{ userState.size }}</div>
</template>

<script setup name=''>
import user from '@/store/user';
const userState = user();
</script>

修改State

<template>
  <div>{{ userState.size }}</div>
</template>

<script setup name=''>
import user from '@/store/user';
const userState = user();
userState.size = '修改state';
</script>

可以直接修改state的属性值,但是不建议直接修改,建议使用actions去修改stateactions的方法中可以直接通过this访问属性。

import { defineStore } from 'pinia';
export default defineStore({
    id: 'user', // id必填,且需要唯一
    state: () => ({
        size: 'small',
        token: '',
    }),
    actions: {
        updateSize(item) {
            this.size = item
        }
    }
});

Getters

如果使用state属性层级较深,则可以使用getters方便获取,或者,对原始state属性数据进行二次操作并返回。

import { defineStore } from 'pinia';
export default defineStore({
    id: 'user', // id必填,且需要唯一
    state: () => ({
        size: 'small',
        token: '',
        userInfo:{
            userId:'aa'
        }
    }),
    getters: {
       getUserId: (state) => state.userInfo.userId,
    }
});
// 使用方法同state属性
userState.getUserId

Actions

// actions中可以执行同步和异步任务
import { defineStore } from 'pinia';
import { authLogin } from '@/api/public';
export default defineStore({
    id: 'user', // id必填,且需要唯一
    state: () => ({
        size: 'small',
        token: '',
    }),
    actions: {
        // 同步任务
        updateSize(item) {
            this.size = item
        }
        // 异步任务
        Login(data) {
            return new Promise((resolve, reject) => {
                authLogin(data)
                    .then((res) => {
                        this.token = res?.data?.tk;
                        resolve(this.token);
                    })
                    .catch((error) => {
                        reject(error);
                    });
            });
        },
    }
});

Action的相互调用

1、同一个 state 中 action 间的相互调用,直接用 this 访问即可。

import { defineStore } from 'pinia';
import { authLogin } from '@/api/public';
export default defineStore({
    id: 'user', // id必填,且需要唯一
    state: () => ({
        size: 'small',
        token: '',
    }),
    actions: {
        // 同步任务
        updateSize(item) {
            this.size = item
        }
        // 异步任务
        Login(data) {
            return new Promise((resolve, reject) => {
                authLogin(data)
                    .then((res) => {
                        this.token = res?.data?.tk;
                        this.updateSize('同一个state中action 间的相互调用')
                        resolve(this.token);
                    })
                    .catch((error) => {
                        reject(error);
                    });
            });
        },
    }
});

2、在 action 里调用其他 state 里的 action ,引入对应的 store 后即可访问其内部的方法了。

import { defineStore } from 'pinia';
import { authLogin } from '@/api/public';
import user from './user';
export default defineStore({
    id: 'guarder', // id必填,且需要唯一
    actions: {
        // 同步任务
        updateSizeFn(item) {
            user().updateSize(item)
        }
    }
});

数据持久化

插件 pinia-plugin-persist 可以辅助实现数据持久化功能。

安装

pnpm i pinia-plugin-persist -S

使用

// 创建store
import { createPinia } from 'pinia';
// 数据持久化
import piniaPluginPersist from 'pinia-plugin-persist';

const store = createPinia();
store.use(piniaPluginPersist);

export default store;

配置

在对应需要数据持久化的state进行响应的配置

import { defineStore } from 'pinia';
import { authLogin } from '@/api/public';
export default defineStore({
    id: 'user', // id必填,且需要唯一
    state: () => ({
        size: 'small',
        token: '',
        userInfo:{
            userId:'aa'
        }
    }),
    getters: {
       getUserId: (state) => state.userInfo.userId,
    }
    actions: {
        // 同步任务
        updateSize(item) {
            this.size = item
        }
        // 异步任务
        Login(data) {
            return new Promise((resolve, reject) => {
                authLogin(data)
                    .then((res) => {
                        this.token = res?.data?.tk;
                        resolve(this.token);
                    })
                    .catch((error) => {
                        reject(error);
                    });
            });
        },
    },
       // 开启数据缓存,数据默认存在 sessionStorage 里,并且会以 store 的 id 作为 key。
    persist: {
        enabled: true,
        // 在 strategies 里自定义 key 值,并将存放位置由 sessionStorage 改为 localStorage。
        strategies: [
            {
                key: 'user',
                storage: localStorage,
                // 默认所有 state 都会进行缓存,通过 paths 指定要持久化的字段,其他的则不会进行持久化。
                paths: ['size', 'token'],
            },
        ],
    },
});