1、首先安装pinia
yarn add pinia
# 或使用npm
npm install pinia
2、在项目的src目录下新建store文件夹,然后store目录下新建index.js / index.ts :
我这里是index,js
import { createPinia } from "pinia"
// 创建 Pinia 实例
const pinia = createPinia()
// 导出 Pinia 实例以便将其与应用程序实例关联
export default pinia
3、 接着在项目入口文件main.js 或 main.ts 引入并使用:
import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import router from './router/router'
import store from './store/index'
createApp(App)
.use(router)
.use(store)
.mount('#app')
4、然后使用defineStore来定义状态存储模块,一般使用useXXXXXStore 来约定俗成的命名规范, 我这里是user.js:
import { defineStore } from "pinia"
export const useUserStore = defineStore({
//id 是为了更好地区分模块
id: 'user',
state: () => ({
name: 'Tony',
age: 18,
count: 0
}),
getters: {
doubleCount: (state) => state.count * 2,
},
actions: {
// 定义操作或异步请求
increment() {
// 这里访问state的数据不再是state.XXX,而是通过this
this.count++
}
}
})
5、在组件内使用store:
<template>
<div>
<h3>我是测试pinia状态存储的组件,我有一个子组件</h3>
<div>userStore里的state数据:</div>
<span>姓名: {{ name }}</span> <span>年龄: {{ age }}</span>
<div><button @click="handleIncre">修改count:</button>count: {{ count }}</div>
<!-- 直接调用getters的方法 -->
<div> Double count is: {{ doubleCount }}</div>
</div>
</template>
js:
<script setup>
import { ref, reactive } from 'vue'
import TestChild1 from './component/TestChild1.vue'
import { useUserStore } from '../../store/user';
import { storeToRefs } from 'pinia'
const userStore = useUserStore()
// 通过storeToRefs包裹,解构出来的属性/方法才有响应式
const { name, age, count, doubleCount} = storeToRefs(userStore)
// console.log('userStore:', userStore.name, userStore.age, userStore.count)
// console.log(name.value, age.value, count.value);
// 调用store的actions的increment方法
const handleIncre = () => {
userStore.increment()
}
</script>
解构store的变量或方法时,如果没有通过storeToRefs包裹,就失去了响应式:
具有响应式:
6、在store中定义异步获取用户信息方法:
6.1 首先新建一个api文件夹定义模拟异步登录获取用户登录信息接口方法:
~~src/api/index
// 模拟异步登录获取用户信息
const loginUser = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve({
name: 'Tony',
age: 18
})
}, 2000)
})
}
export default {
loginUser
}
6.2 在store,user.js中:
引入api文件,在actions中定义getUserInfo方法,异步查询时,通常都是async和await一起搭配使用的。
import { defineStore } from "pinia"
import API from '../api/index'
export const useUserStore = defineStore({
//id 是为了更好地区分模块
id: 'user',
state: () => ({
name: 'Tony',
age: 18,
count: 0,
userInfo: {}
}),
getters: {
doubleCount: (state) => state.count * 2,
},
actions: {
// 定义操作或异步请求
increment() {
// 这里访问state的数据不再是state.XXX,而是通过this
this.count++
},
// 在actions中异步获取loginUser的数据
async getUserInfo() {
this.userInfo = await API.loginUser()
console.log('user-info', this.userInfo);
}
}
})
6.3 在vue组件中使用:
<!-- 点击---异步登录获取userInfo -->
<button @click="getUser">异步登录获取userInfo</button>
<div>userInfo: {{ userInfo }}</div>
// 调用store的actions的getUserInfo方法异步获取用户登录信息
const getUser = () => {
userStore.getUserInfo()
}
7、此外,在actions中,方法也可以互相调用:
在actions中定义updateUserName方法,通过传入的新名字newName去改变state中的userInfo的name
actions: {
// 定义操作或异步请求
increment() {
// 这里访问state的数据不再是state.XXX,而是通过this
this.count++
},
// 在actions中异步获取loginUser的数据
async getUserInfo(newName) {
this.userInfo = await API.loginUser()
console.log('user-info', this.userInfo);
this.updateUserName(newName)
},
updateUserName(name) {
if(name) {
this.userInfo.name = name
}
}
}
组件内调用actions的getUserInfo方法时传入newName:
// 调用store的actions的getUserInfo方法异步获取用户登录信息
const newName = ref('小白很白')
const getUser = () => {
userStore.getUserInfo(newName.value)
}
8、pinia数据持久化
数据持久化之前,刷新页面,pinia的数据会丢失,跟vuex一样,但是pinia做数据持久化是可以通过插件快速完成。
该插件的默认配置如下:
- 使用 localStorage 进行存储
- store.$id 作为 storage 默认的 key
- 使用 JSON.stringify/JSON.parse 进行序列化/反序列化
- 整个
state
默认将被持久化’
8.1 pnpm安装:
pnpm i pinia-plugin-persistedstate
8.2 将插件添加到 pinia 实例上:
~~store/index:
import { createPinia } from "pinia"
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
// 创建 Pinia 实例
const pinia = createPinia()
pinia.use(piniaPluginPersistedstate)
// 导出 Pinia 实例以便将其与应用程序实例关联
export default pinia
8.3 在对应的store中,将 persist
选项设置为 true
。
import { defineStore } from "pinia"
import API from '../api/index'
export const useUserStore = defineStore({
//id 是为了更好地区分模块
id: 'user',
state: () => ({
name: 'Tony',
age: 18,
count: 0,
userInfo: {
name: '',
age: null,
info:[
]
}
}),
getters: {
doubleCount: (state) => state.count * 2,
},
actions: {
// 定义操作或异步请求
...
// 在actions中异步获取loginUser的数据
...
},
persist: true,
})
现在,你的整个 Store 将使用默认持久化配置保存。
控制台Application 的 localStorage如图:
9、pinia的modules模块化:
9.1 先在store目录下创建modules文件夹,把之前的user.js复制到里面,在创建个counter.js文件:
9.2 把对应的user.js和counter.js文件的方法和属性修好,导出给外面组件使用:
~user.js:
import { defineStore } from "pinia"
import API from '@/api/index'
export const useUserStore = defineStore({
//id 是为了更好地区分模块
id: 'user',
state: () => ({
name: 'Tony',
age: 18,
count: 0,
userInfo: {
name: '',
age: null,
info:[
]
}
}),
getters: {
doubleCount: (state) => state.count * 2,
},
actions: {
// 定义操作或异步请求
increment() {
// 这里访问state的数据不再是state.XXX,而是通过this
this.count++
},
// 在actions中异步获取loginUser的数据
async getUserInfo(newName) {
this.userInfo = await API.loginUser()
console.log('user-info', this.userInfo);
this.updateUserName(newName)
},
updateUserName(name) {
if(name) {
this.userInfo.name = name
}
}
},
persist: true,
})
~counter.js:
import { defineStore} from 'pinia'
export const useCounterStore = defineStore({
id: 'counter',
state: () => ({
counterCount: 21
}),
getters: {
tenCount: (state) => {
return state.counterCount *10
}
},
actions: {
decrement() {
this.counterCount--
}
},
// 持久化
persist: true,
})
9.3 main.js
模块化统一导出
import { createPinia } from "pinia"
// pinia持久化插件
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
// 创建 Pinia 实例
const pinia = createPinia()
pinia.use(piniaPluginPersistedstate)
// 导出 Pinia 实例以便将其与应用程序实例关联
export default pinia
// 模块化导出
// import { useUserStore } from '@/store/modules/user.js'
// export { useUserStore }
// import { useCounterStore } from '@/store/modules/counter.js'
// export { useCounterStore }
// 模块化统一导出,简写
export * from './modules/user'
export * from './modules/counter'
9.4 在页面中使用
先引入store/index
// import { useUserStore } from '../../store/user';
import { useUserStore, useCounterStore } from '../../store/index'
通过storeToRefs解构出counterCount, tenCount属性,方法可直接调用
// store的模块化使用,调用useCounterStore的属性/方法
const counterStore = useCounterStore()
const { counterCount, tenCount } = storeToRefs(counterStore)
const handleDecre = () => {
counterStore.decrement()
}
模板:
<div>################################ start ==> pinia modules模块化 #############################</div>
<!-- store的模块化使用,调用useCounterStore的counterCount属性 -->
<div>counterStore的counterCount:{{ counterCount }}</div>
<button @click="handleDecre">修改counterCount</button>
<div>10倍counterCount:{{ tenCount }}</div>
<div>################################ end ==> pinia modules模块化 #############################</div>
效果:
以上就是pinia的vue3使用。
标签:count,管理器,name,----,state,pinia,vue3,import,store From: https://blog.csdn.net/weixin_48420104/article/details/139243310