Pinia--新一代状态管理神器,看完这篇迅速上手!
什么是pinia
Pinia 是一个为 Vue.js 设计的状态管理库,它的设计目标是提供一个简单且直观的 API,同时保持高性能和灵活性。Pinia 通常被看作是 Vuex 的一个替代方案,尤其是在 Vue 3 的背景下,它提供了一些改进和增强的功能。
从官方文档的描述中我们可以总结出pinia的一些特点:
- TypeScript 集成:Pinia.js 完美兼容 TypeScript。
- 极致轻巧:压缩后仅占 1.6KB,对应用的加载时间和性能影响微乎其微,确保了高效的用户体验。
- 精简的状态管理模型:摒弃了传统的 mutations 概念,专注于 state、getters 和 actions,简化了状态更新的逻辑,使代码更易于理解和维护。
- 灵活的 action 执行:actions 支持同步和异步操作,为开发者提供了更大的灵活性,能够轻松处理各种业务需求,包括复杂的异步请求。
- 扁平化的 store 结构:Pinia.js 采用了单一的 store 概念,消除了模块嵌套的复杂性,store 之间可以直接交互,促进了代码的模块化和复用。
- 自动化的 store 注册:一旦 store 被定义,它就会自动注册并可用,无需显式的手动注册过程,简化了开发流程,提升了开发效率。
安装pinia
npm install pinia
npm install pinia
这条命令是用来在你的 Node.js 项目中安装 Pinia 库。
创建store
在目录src/store/index.js下创建store
import { createPinia } from 'pinia'
const store = createPinia()
export default store
这段代码在 Vue.js 应用中创建并导出一个 Pinia Store 实例,具体解释如下:
-
导入
createPinia
:import { createPinia } from 'pinia'
这行代码从pinia
包中导入了createPinia
函数。createPinia
是一个工厂函数,用于初始化一个新的 Pinia Store 实例。
-
创建 Store 实例:
const store = createPinia()
这里调用了createPinia
函数,创建了一个新的 Pinia Store 实例,并将其赋值给store
变量。这个store
实例包含了 Pinia 的所有核心功能,如状态管理、actions 和 getters 的定义。
-
导出 Store 实例:
export default store
这行代码将store
实例作为模块的默认导出。这意味着其他模块可以通过import
语句直接导入这个 Store 实例,而不需要使用大括号{}
来解构。
通过这样的方式,你可以在应用的主入口文件(如 main.js
)中创建 Store 实例,并将其导出,然后在应用启动时将其注入到 Vue 应用中。
在main.js
文件中引用该store
import { createApp } from 'vue'
import App from './App3.vue'
import store from './store'
createApp(App)
.use(store)
.mount('#app')
定义一个具体的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'
}
}
}
})
这段代码使用 Pinia 的 defineStore
函数来定义一个具体的 Store,具体解析如下:
-
导入
defineStore
:import { defineStore } from 'pinia'
这行代码从pinia
包中导入了defineStore
函数。defineStore
是 Pinia 提供的用于定义 Store 的主要函数,它允许你以模块化的方式定义和管理应用的状态。
-
定义 Store:
export const useUserStore = defineStore({ ... })
这里定义了一个名为useUserStore
的 Store。defineStore
函数接收一个配置对象作为参数,这个对象包含了 Store 的各种配置和定义。
-
配置 Store:
id: 'user'
:这是 Store 的唯一标识符,用于在应用中识别和引用这个 Store。id
字段是必需的,它应该是一个唯一的字符串。state: () => {...}
:这是 Store 的状态定义,它返回一个对象,该对象包含了 Store 的初始状态。这里使用了一个箭头函数,返回一个包含userInfo
对象的响应式状态。userInfo
包含了用户的姓名、年龄和性别等信息。
-
使用 Store:
- 一旦定义了 Store,你就可以在组件中通过
useUserStore
函数来访问这个 Store 的实例。例如,在一个 Vue 组件中,你可以这样使用:
- 一旦定义了 Store,你就可以在组件中通过
使用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
userStore.userInfo.name = '李四' // 不要这种代码
在获取到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
的确类似于 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 的 userStore
实例,动态显示了用户十年后的年龄。
数据持久化
众所周知,在前端中数据是无法保存的,一刷新页面,数据就会重新回到初始状态,为了解决这个问题我们可以把数据存储在浏览器的本地存储当中,这就叫数据持久化。
通过安装插件pinia-plugin-persist 可以实现数据持久化功能。
安装
npm i pinia-plugin-persist
使用方法
数据持久化配置
在 defineStore
的配置对象中,persist
属性被设置为一个对象,用于配置数据持久化的细节:
-
enabled: true
:- 这个属性指定了是否开启数据持久化。当设置为
true
时,意味着 Store 中指定的数据将被保存在浏览器的本地存储中。
- 这个属性指定了是否开启数据持久化。当设置为
-
strategies
数组:-
这是一个策略数组,定义了哪些状态应该被持久化以及如何存储它们。每个策略都是一个对象,可以包含以下属性:
paths
:一个字符串数组,指定了 Store 中哪些状态路径应该被持久化。在这个例子中,['userInfo']
表示userInfo
对象将被持久化。storage
:指定了用于存储数据的 Web Storage 对象,默认是localStorage
。你也可以选择使用sessionStorage
,这取决于你希望数据在何时失效。
-
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
}
]
}
})
开启数据持久化
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
对象。
当然我们还可以持久化部分的state,如下:
state: () => {
id: 'user',
state: () => { // 数据源
return {
userInfo: {
name: '张三',
age: 18,
sex: 'girl'
}
}
},
persist: {
enabled: true,
strategies: [
{
storage: localStorage,
paths: ['userInfo.name', 'UserInfo.age']
}
]
}
上面代码中我们就只持久化了name与age属性。
总结
以上内容是pinia的一些基本的用法,如需要深入学习还请参考官方文档( pinia官方文档)
本篇文章就到此结束了,希望对你了解pinia的使用有所帮助,谢谢大家。
转载自:https://juejin.cn/post/7389101647916810291