状态管理库
Pinia是Vue的专属状态管理库,它允许你跨组件或页面共享状态
1:安装与使用pinia
1.1 安装语法:npm install pinia
1.2 创建一个pinia(根存储)并将其传递给应用程序
import {
createApp } from 'vue'
import App from './App.vue'
// 引入 createPinia 函数
import {
createPinia } from 'pinia'
const app = createApp(App)
// 使用 createPinia() 来创建 Pinia(根存储),并应用到整个应用中
app.use(createPinia())
app.mount('#app')
2:Store
- store是一个保存状态和业务逻辑的实体,它并不与你的组件树绑定;换句话说,它承载着全局状态;它有点像一个永远存在的组件,每个组件都可以读取和写入它
- store它有三个概念,state、getters和actions,我们可以l理解成组件中的data、computed和methods
- 在项目中的src\store文件夹下不同的store.js文件
- store是用defineStore(name, function | options)定义的,建议其函数返回的值命名为use…Store方便理解
a. 参数name:名字,必填值且唯一
b. 参数function|options:可以是对象或函数形式
■ 对象形式【选项模式】,其中配置state、getters和actions选项
■ 函数形式【组合模式,类似组件组合式API的书写方式】,定义响应式变量和方法,并且return对应的变量和方法;ref()相当于state,computed()相当于getters,function()相当于actions
定义 store 【选项式】
import {
defineStore } from 'pinia'
// 创建 store,并暴露出去
// 参数一:名字,必填值且唯一
// 参数二:选项式书写方式采用对象形式
export const useStore = defineStore('main', {
state: () => ({
// ……
}),
getters: {
// ……
},
actions: {
// ……
}
})
定义 store 【组合式】
import {
defineStore } from 'pinia'
import {
computed, ref } from 'vue'
// 创建 store,并暴露出去
// 参数一:名字,必填值且唯一
// 参数二:组合式书写方式采用函数形式
export const useStore = defineStore('main', () => {
// ref 变量 ---> state
// computed() 计算属性 ---> getters
// functions 函数 ---> actions
return {
// 暴露出去 变量,函数,计算属性即可
}
})
3:State
state是store的核心部分,主要存储的是共享的数据
3.1:定义state
- store采用的是选项式模式时,state选项为函数返回的对象,在其定义共享的数据
- store采用的是组合式模式时,在其函数内定义的ref变量,最终return出去来提供共享的数据
选项式
import {
defineStore } from 'pinia'
export const useUserStore = defineStore('user', {
// 共享的数据,为函数返回的对象形式
state: () => ({
age: 27,
level: 5,
account: 'SD77842',
nickname: '自古风流'
})
})
组合式
import {
defineStore} from "pinia";
import {
ref} from "vue";
export const useUserStore = defineStore('user', () => {
const age = ref(27)
const level = ref(5)
const account = ref('SD77842')
const nickname = ref('自古风流')
return {
age, level, account, nickname } // 将数据暴露出去,共享给需要的组件
})
3.2:组件中访问state
- 在选项式 API 组件中,可以使用mapState(storeObj, array | object)帮助器将状态属性映射为只读计算属性
a. storeObj引入的store对象
b. array | object:字符串数组形式或者对象形式
■ 【字符串数组形式】直接将store中state的数据映射为当前组件的计算属性,但是不能自定义名称
■ 【对象形式时】key为自定义当前组件的计算属性名,value字符串形式,是store中state的共享数据
提示:mapState()函数映射到组件中的计算属性是只读的,如果想在组件中响应式修改state的数据,则应该选择mapWritableState()函数来映射计算属性 - 在组合式 API 组件中,直接引入对应的store,通过store对象直接获取和修改state
提示:
如果想在组件中自定义变量来接收store中的state中共享的数据,我们可以这样做:
● 使用computed(() => store.dataName),具有响应式,但是只读形式
● 使用storeToRefs(store)从store解构想要的state,具有响应式,可直接修改,可自定义名称
组件中获取 state【选项式】
<script>
import {
mapState, mapWritableState } from 'pinia'
import {
useUserStore } from '@/store/useUserStore'
import UserVue from '@/components/User.vue'
export default {
components: {
UserVue },
computed: {
// mapState:将 store 的 state 映射成当前组件的计算属性
// 具有响应式,但是是只读
// 字符串数组形式:不能自定义计算属性名
// 对象形式:可以自定义计算属性名
...mapState(useUserStore, ['age', 'level']),
...mapState(useUserStore, {
user_account: 'account',
user_nickname: 'nickname'
}),
// mapWritableState 与 mapState 用法类似,区别:它可以响应式的读写映射的计算属性
...mapWritableState(useUserStore, ['account', 'nickname']),
...mapWritableState(useUserStore, {
user_age: 'age',
user_level: 'level'
}),
}
}
</script>
<template>
<UserVue></