什么时候应该使用pinia?
存储应该包含可以在整个应用程序中访问的数据 。 这包括在许多地方使用的数据,例如导航栏中显示的用户信息…
一、安装
npm install pinia
二、使用步骤
1.main.js中引入
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'
const pinia = createPinia()
const app = createApp(App)
app.use(pinia)
app.mount('#app')
2.创建store
store简单来说就是数据仓库,相当于一个容器,里边存放数据,方法。这里的数据所有的组件都可以访问和修改。
在store文件夹下创建一个存储用户信息的store文件,user.js
//使用pinia提供的defineStore()方法来创建一个store
import { defineStore } from "pinia";
// 第一个参数是应用程序中 store 的唯一 id, 第二个参数是配置对象
export const useUser = defineStore('user',{
state: ()=>{
return {
userName: "admin",
userAge: 18,
}
},
getters: {},
actions: {}
})
3.获取state值
这里使用 storeToRefs()
让获取到的store数据变成响应式的
<template>
<div>{{ userName }}</div>
<div>{{ userAge }}</div>
</template>
<script setup>
import { useUser } from "@/store/user.js";
import { storeToRefs } from "pinia";
const userStore = useUser();
const { userName, userAge } = storeToRefs(userStore);
</script>
4.修改,重置state值
1、直接userStore.userName = '123'
2、使用$patch({})
方法可以同时修改多个值
3、使用$reset()
方法重置
<template>
<div>{{ userName }}</div>
<div>{{ userAge }}</div>
<button @click="onEditUserName">只改变username</button>
<button @click="onPatch">批量修改username和userAge</button>
<button @click="onReset">重置state</button>
</template>
<script setup>
import { useUser } from "@/store/user.js";
import { storeToRefs } from "pinia";
const userStore = useUser();
const { userName, userAge } = storeToRefs(userStore);
//修改后其他组件引用这个值的也会变
const onEditUserName = () => {
userStore.userName = "editer";
};
//批量修改
const onPatch = () => {
userStore.$patch({
userName: "patchName",
userAge: 20,
});
};
//重置state,重置成初始值
const onReset = () => {
userStore.$reset();
};
</script>
5.getters
类似计算属性
1、user.js
//使用pinia提供的defineStore()方法来创建一个store
import { defineStore } from "pinia";
// 第一个参数是应用程序中 store 的唯一 id, 第二个参数是配置对象
export const useUser = defineStore('user',{
state: ()=>{
return {
userName: "admin",
userAge: 18,
}
},
getters: {
//年龄+1
getAddAge: (state)=>{
return state.userAge+1;
},
isAdult: (state)=>{
return state.userAge >= 18 ? '成年人' : '未成年'
},
//使用自身计算属性
getUserInfo: (state)=>{
return `姓名:${state.userName};年龄:${state.userAge};是否成年:${state.isAdult}`
},
//传参
getIsAdmin: ()=>{
return (name) => name == 'admin' ? '管理员' : '使用者'
}
},
actions: {}
})
2、在组件中使用getter方法
<template>
//18
<div>年龄:{{userAge}}</div>
//19
<div>年龄+1:{{userStore.getAddAge}}</div>
//详细信息
<div>详细信息:{{userStore.getUserInfo}}</div>
//是否管理员
<div>是否管理员:{{userStore.getIsAdmin('admin')}}</div>
</template>
<script setup>
import { useUser } from "@/store/user.js";
import { storeToRefs } from "pinia";
const userStore = useUser();
const { userName, userAge } = storeToRefs(userStore);
</script>
3、调用其他store文件里的getters方法
work.js
//使用pinia提供的defineStore()方法来创建一个store
import { defineStore } from "pinia";
// 第一个参数是应用程序中 store 的唯一 id, 第二个参数是配置对象
export const useWork = defineStore('work',{
state: ()=>{
return {
city:'beijing'
}
},
getters: {
getWorkInfo: (state)=>{
return '工作地点在'+ state.city;
}
},
actions: {}
})
在 user.js
里访问 work.js
的getters方法
user.js
//使用pinia提供的defineStore()方法来创建一个store
import { defineStore } from "pinia";
import { useWork } from './work.js'
// 第一个参数是应用程序中 store 的唯一 id, 第二个参数是配置对象
export const useUser = defineStore('user',{
state: ()=>{
return {
userName: "admin"
}
},
getters: {
getAddAge: (state)=>{
//使用 useWork
const workStore = useWork()
return state.userName + workStore.getWorkInfo
},
},
actions: {}
})
6.actions
user.js
//使用pinia提供的defineStore()方法来创建一个store
import { defineStore } from "pinia";
import { useWork } from './work.js'
// 第一个参数是应用程序中 store 的唯一 id, 第二个参数是配置对象
export const useUser = defineStore('user',{
state: ()=>{
return {
userName: "admin"
}
},
getters: {},
actions: {
//修改state中的userName
updateName(name){
this.userName = name;
}
}
})
vue页面
<template>
<div>姓名:{{userName}}</div>
<button @click="onUpdate('更新')">更新名字</button>
</template>
<script setup>
import { useUser } from "@/store/user.js";
import { storeToRefs } from "pinia";
const userStore = useUser();
const { userName } = storeToRefs(userStore);
//更新名字
const onUpdate = (name) => {
userStore.updateName(name);
};
</script>