前言
pinia是什么?
Pinia 是一个为 Vue.js 应用程序设计的状态管理库。它旨在简化和统一跨组件或页面共享状态的方式,提供了一个直观且强大的 API 来管理应用的全局状态。Pinia 的设计目标是让状态管理变得简单、可预测并且易于调试。
这个是官方文档:pinia.web3doc.top/大家可以到官方文档里具体查看。
正文
- Pinia的数据流转图
使用pinia的优点
-
去除了mutations,只有 state,getters和actions,其中actions支持了同步和异步操作
-
不会像Vuex那样有模块嵌套,Pinia只有store的概念,store之间可以相互使用,互不影响,达到模块扁平化的效果
-
更好地支持ts
-
更好地支持Vue2/Vue3
-
逻辑更加清晰,开发起来更加简单
-
可以创建多个全局仓库,不用像
Vuex一个store嵌套多个modules,结构复杂。 -
语法简单,不像Vuex需要记忆太多的API。
如何使用pinia
安装
yarn add pinia
# or
npm i pinia
导入,实例化,当做插件使用,和其他插件的使用套路差不多
import { createApp } from 'vue'
+import { createPinia } from 'pinia'
import App from './App.vue'
const app = createApp(App)
+ const pinia = createPinia()
+ app.use(pinia)
app.mount('#app')
创建仓库和使用仓库
在目录src/store/index.js下创建store
import { createPinia } from 'pinia'
const store = createPinia()
export default store
定义一个具体的store
创建目录src/store/user.js
import { defineStore } from 'pinia' // defineStore 是store的一部分
export const useUserStore = defineStore({
id: 'user',
state: () => { // 数据源
return {
userInfo: {
name: '张三',
age: 18,
sex: 'girl'
}
}
}
})
这段代码创建了一个 Store,名为 user,它包含了一个 userInfo 对象作为初始状态。可以在 Vue 组件中通过调用 useUserStore 函数来访问和修改这个 Store 的状态。
获取state
<template>
<div>{{userStore.userInfo.name}}</div>
</template>
<script setup>
import { useUserStore } from '@/store/user';
const userStore = useUserStore()
</script>
<style lang="css" scoped></style>
同样也可以通过使用computed获取state的值
const name = computed(() => userStore.userInfo.name)
还可以通过storeToRefs将state的值转化为响应式的Refs
const { userInfo } = storeToRefs(userStore)
修改state
在获取到store实例时,咱们可以直接修改state中的变量,但一般不建议这么做,因为这样不利于维护,而是通过在actions中定义一些方法来通过this访问该变量去修改。
import { defineStore } from 'pinia' // defineStore 是store的一部分
export const useUserStore = defineStore({
id: 'user',
state: () => { // 数据源
return {
userInfo: {
name: '张三',
age: 18,
sex: 'girl'
}
}
},
actions: { // 专门用来修改state
changeUserName(name) {
this.userInfo.name = name
}
}
})
通过调用actions中的咱们定义的方法来修改变量的值:
<template>
<button @click="changeName">修改仓库中的用户姓名</button>
</template>
<script setup>
import { useUserStore } from '@/store/user';
const userStore = useUserStore()
const changeName = () => {
// userStore.userInfo.name = '李四' // 不要这种代码
userStore.changeUserName('李四')
}
</script>
<style lang="css" scoped></style>
getters
在 Pinia 中,getters 被用于定义基于 Store 状态的派生数据。它们是响应式的,这意味着每当 Store 的状态发生变化时,相关的 getters 将会自动更新,所有依赖于这些 getters 的组件也会随之更新。类似于 Vue.js 中的 computed 属性.
import { defineStore } from 'pinia' // defineStore 是store的一部分
export const useUserStore = defineStore({
id: 'user',
state: () => { // 数据源
return {
userInfo: {
name: '张三',
age: 18,
sex: 'girl'
}
}
},
actions: { // 专门用来修改state
changeUserName(name) {
this.userInfo.name = name
}
},
getters: { // 仓库中的计算属性
afterAge(state) {
return state.userInfo.age + 10
}
}
})
<template>
<ul>
<li>十年后年龄:{{ userStore.afterAge }}</li> //28
</ul>
</template>
<script setup>
import { useUserStore } from '@/store/user'
const userStore = useUserStore()
</script>
<style lang="scss" scoped></style>
数据持久化
在前端中我们的数据是无法保存的,一但重新刷新了页面,数据就会重新回到初始状态,为了解决这个问题我们可以把数据存储在浏览器的本地存储当中,这就叫数据持久化。
通过安装插件pinia-plugin-persist 可以实现数据持久化功能。
npm i pinia-plugin-persist
如何使用
-
enabled: true:表明数据持久化功能是启用的。如果没有这行代码或设置为false,那么持久化将不会生效。 -
strategies数组:持久化策略定义了哪些数据路径(paths)需要被持久化以及使用哪种存储机制(storage)。-
paths: ['userInfo']:这里指定了userInfo这个状态路径应该被持久化。这意味着userInfo下的所有数据都会被序列化并存储起来。如果你有多个状态路径需要持久化,可以在这里添加更多的路径。 -
storage: localStorage:指定了使用localStorage作为持久化存储机制。localStorage是浏览器提供的一种持久化存储方案,它允许在用户的浏览器中存储数据,即使用户关闭浏览器,数据也不会丢失,除非用户主动清除。
-
import { defineStore } from 'pinia' // defineStore 是store的一部分
export const useUserStore = defineStore({
id: 'user',
state: () => { // 数据源
return {
userInfo: {
name: '张三',
age: 18,
sex: 'girl'
}
}
},
actions: { // 专门用来修改state
changeUserName(name) {
this.userInfo.name = name
}
},
getters: { // 仓库中的计算属性
afterAge(state) {
return state.userInfo.age + 10
}
},
persist: { // 开启数据持久化
enabled: true,
strategies: [
{
paths: ['userInfo'],
storage: localStorage
}
]
}
})
persist 对象配置了数据持久化策略。在这里,咱们启用了数据持久化功能,指定了 userInfo 路径的数据应该被持久化,并且使用 localStorage 作为存储机制。这意味着 userInfo 的数据将在浏览器的 localStorage 中保存,即使用户刷新页面或关闭浏览器,数据也不会丢失。
开启数据持久化
import { createPinia } from 'pinia'
import piniaPluginPersist from 'pinia-plugin-persist'
const store = createPinia()
store.use(piniaPluginPersist)
export default store
完成数据持久化操作之后可以在浏览器中看到,localStorage中的key为该store的id属性user,value为userInfo对象。
一些使用中遇到的问题和注意
- 异步操作的处理:Pinia尚未提供类似Vuex中
actions的处理异步操作的直接方式。在Pinia中,我们不得不采用async/await操作来处理异步请求。有时,这可能使我们的代码显得更加冗长和复杂。
import { defineStore } from 'pinia'
import axios from 'axios'
export const useUserStore = defineStore({
id: 'user',
state: () => ({
userData: {}
}),
actions: {
async fetchUser() {
const response = await axios.get('/api/user')
this.userData = response.data
}
}
})
2.为了从 store 中提取属性时保持其响应性,你需要使用 storeToRefs()。它将为每一个响应式属性创建引用。
import { useUserStore, storeToRefs } from '@/store/user'
export default {
setup() {
const user = useUserStore()
// 使用storeToRefs转化,确保状态响应性
const userToProps = storeToRefs(user)
return {
...userToProps
}
}
}
现在,可以直接在模板中以响应式方式使用状态和动作,例如name和changeName函数。storeToRefs函数确保这些值具有响应性,这意味着当store中的状态改变时,你的组件始终能够显示最新的状态。
<template>
<div>
<h1>{{ name }}</h1>
<button @click="changeName('New Name')">Change Name</button>
</div>
</template>
总之,storeToRefs是Pinia的关键特性之一,它使得我们能够在组件中能够直观并且以响应式的方式使用store数据。借助storeToRefs,咱们不需要在组件中引用完整的store,只需要引用我们需要的部分,这使得我们的代码更简洁,易于维护。因此,还是推荐使用storeToRefs在Piniastore和Vue组件之间建立响应式桥梁。
总结
今天咱们学习了一下pinia的基本用法,了解了数据的使用和处理,同时分享了一些使用中的注意,
storeToRefs是你在结合使用Pinia和Vue3时的重要工具。最后,希望本文能对你学习pinia有所帮助,可以帮忙点个免费的赞赞嘛,感谢感谢!