一、和vuex对比
- 没有mutations。只有state、getters、actions(支持异步和同步)
- 分模块不需要modules(vuex需要)
- 体积更小(性能更好)
- 完整的 ts 支持
二、安装
pnpm i pinia
三、使用
- 创建 pinia 实例
在src目录下新建store文件夹,并创建index.ts文件。
src/store/index.ts
import type { App } from 'vue'
import { createPinia } from 'pinia'
const store = createPinia();
export function setupStore(app: App<Element>) {
app.use(store)
}
export { store }
- 在main.ts中引入
import { createApp } from 'vue'
import { setupStore } from '@/store';
import App from '@/App.vue'
const app = createApp(App)
// 配置 store
setupStore(app);
app.mount('#app')
- 定义store。
- 在store文件夹下新建modules文件夹,并创建你所需要的store文件。比如:
store/modules/user.ts - store 是用
defineStore()定义的,它的第一个参数要求是一个独一无二的名字
//user.ts
import { defineStore } from 'pinia';
import type { UserInfo } from '#/store';
interface UserState {
userInfo: Nullable<UserInfo>,
roles: [],
token?: string,
refreshToken?: string
}
export const useUserStore = defineStore('app-user', {
state: (): UserState => ({
userInfo: null,
roles: [],
token: undefined,
refreshToken: undefined
}),
getters: {
getUserInfo(state): UserInfo {
return state.userInfo || getAuthCache<UserInfo>(USER_INFO_KEY) || {};
}
}
actions: {
//登录
async login() {
try {
const data = await loginApi(params);
//存token
} catch(error) {
return Promise.reject(error)
}
}
}
})
- ts中使用(通过actions修改state里的数据)-推荐
//登录页面
import { useUserStore } from '/@/store/modules/user';
const userStore = useUserStore();
const handleLogin = function() {
try {
const userInfo = await userStore.login(params);
//登录成功跳转默认页面(首页)
} catch(eror) {
}
}
5.组件模板中使用state里的数据
<template>
<h1>早安, {{ userinfo.name }}</h1>
</template>
<script lang="ts" setup>
import { computed } from 'vue';
import { useUserStore } from '@/store/modules/user';
const userStore = useUserStore();
const userinfo = computed(() => userStore.getUserInfo);
</script>
- 其他修改state里的值的方法
import { storeToRefs} from 'pinia'
import { useUserStore } from '/@/store/modules/user';
const userStore = useUserStore();
//1.直接修改(不推荐)
// const { name, people, getNames } = useUserStore 会丢失响应式
// storeToRefs只能把state里面的数据变为单独的响应式的ref 但是不能解构 actions 中的方法
let { token } = storeToRefs(userStore); //通过storeToRefs包裹,解决响应式丢失
token.value = 'hhhh';
useUserStore.token = 'hhhh'
//2.$patch修改
userStore.$patch({
token: 'hhhhh'
})
//3.$patch修改(批量更新)
userStore.$patch((state)=>{
state.token = '123456'
})
- 重置state
import { useUserStore } from '/@/store/modules/user';
const userStore = useUserStore();
userStore.$reset()