Pinia
Vuex4 匹配 Vue3;Vuex3 匹配 Vue2。
Vuex3 推荐搭配 Vue2 使用;Vuex4 推荐搭配 Vue2 和 Vue3 的 Options API 使用;Pinia 推荐搭配 Vue3 的 Composition API 使用。
Pinia: 也是 Vue 官方维护的一个状态管理库,用于跨组件、页面进行状态共享。
Pinia 和 Vuex 的区别:
Pinia 原本是 Vue 官方对 Vuex5 的一个实验性版本,不过完善之后官方就将其直接推出了,而不再去发布 Vuex5。
- 在 Pinia 中,mutations 不再存在。
- 在 Pinia 中,不再有 modules 的模块嵌套。
- 相比于 Vuex,Pinia 对 Composition API 有更友好的适配。
- 相比于 Vuex,Pinia 对 TypeScript 有更友好的支持。
安装:
npm install pinia
。
创建并注册 Pinia 对象:
// src/stores/index.js
// 1. 创建 Pinia 对象
import { createPinia } from "pinia"
const pinia = createPinia()
console.log(pinia.state)
export default pinia
// src/main.js
import { createApp } from 'vue'
import App from './App.vue'
import pinia from './store'
const app = createApp(App)
// 2. 注册 pinia 对象,此时 Piani 就生效了
app.use(pinia)
app.mount('#app')
定义并获取 Store:
通过 defineStore()
定义 store。defineStore()
接收两个参数,第一个参数是当前 store 的唯一标识 id;第二个参数是当前 store 的配置对象。defineStore()
返回一个函数,调用返回的函数就会创建并返回 store。
import { defineStore } from "pinia"
// 1. 定义 store。通过 defineStore() 定义 store。在 Pinia 中可以定义任意数量的 store。定义好 store 之后,不需要手动将其加入到 pinia 中,pinia 会自动对其进行管理
const useHome = defineStore('home', {...})
// 2. 获取 store。通过调用 defineStore() 返回的函数创建 store
const homeStore = useHome()
使用:
Store 有三个核心概念:state、getters、actions,等同于 Vue 组件中的 data、computed、methods。一旦 store 被实例化,就可以直接在 store 上访问 state、getters、actions 中定义的任何属性和方法。
state:
state:相当于组件中的 data。用来管理状态。
// src/store/home.js
import { defineStore } from "pinia"
const useHome = defineStore('home', {
// 1. 定义 state 状态
state: () => ({
count: 1,
})
})
export default useHome
// src/components/Home.vue
<template>
<div>{{ homeStore.count }}</div>
</template>
<script setup>
// 2. 获取 state 状态。
import useHome from './store/home'
const homeStore = useHome()
console.log(homeStore.count)
</script>
<style scoped>
</style>
对 store 中的数据进行赋值或者解构,赋值或者解构出来的数据不具有响应式。可以使用 Vue 提供的 toRefs()
方法或者 Pinia 提供的 storeToRefs()
方法使其具有响应式。
// src/components/Home.vue
<template>
<div>{{ count }}</div>
<button @click="hadnleAdd">+1</button>
</template>
<script setup>
import useHome from './store/home'
const homeStore = useHome()
// 赋值或者解构出来的数据不具有响应式
let {count} = homeStore
const hadnleAdd = () => {
count++
}
</script>
<style scoped>
</style>
<template>
<div>{{ count }}</div>
<button @click="hadnleAdd">+1</button>
</template>
<script setup>
// import { toRefs } from 'vue'
import { storeToRefs } from 'pinia'
import useHome from './store/home'
const homeStore = useHome()
// 通过使用 toRefs() 或者 storeToRefs() 使得赋值或者解构出来的数据仍然具有响应性
// let {count} = toRefs(homeStore)
let {count} = storeToRefs(homeStore)
const hadnleAdd = () => {
homeStore.count++ // 但此处修改数据还需要使用 homeStore.count++,不能直接使用 count++
}
</script>
<style scoped>
</style>
修改 state:
在 Pinia 中,可以直接修改 state,而不需要像在 Vuex 中一样必须通过提交 mutation 来修改 state。
可以通过 store 实例直接修改 state。
<template>
<div>{{ homeStore.count }}</div>
<button @click="hadnleAdd">+1</button>
</template>
<script setup>
import useHome from './store/home'
const homeStore = useHome()
const hadnleAdd = () => {
// 通过 store 实例直接修改 state
homeStore.count++
}
</script>
<style scoped>
</style>
也可以通过 store 实例的 $patch()
方法一次性修改多个状态。
homeStore.$patch({
name: 'Lee',
age: 18,
height: 1.88,
})
也可以通过调用 store 实例的 $reset()
方法将状态重置回初始值。
homeStore.$reset()
getters:
getters:相当于组件中的 computed。如果需要对数据进行处理后再使用,就可以使用 getters。
// src/store/home.js
import { defineStore } from "pinia"
const useHome = defineStore('home', {
state: () => ({
count: 1,
}),
// 1. 定义 getters
getters: {
doubleCount(state) {
// 默认会接收 state 作为参数,因此可以使用 state 访问 state 中的数据
return state.count * 2
// 在 getters 中可以使用 this,this 指向 store 实例,因此也可以使用 this 访问 state 中的数据
return this.count * 2
}
}
})
export default useHome
// src/components/Home.vue
<template>
<div>{{ homeStore.doubleCount }}</div>
</template>
<script setup>
// 2. 获取 getters 中的数据
import useHome from './store/home'
const homeStore = useHome()
console.log(homeStore.doubleCount)
</script>
<style scoped>
</style>
actions:
actions:相当于组件中的 methods。用来定义业务逻辑,经常会将组件中的网络请求抽取到 actions 中。
// src/store/home.js
import { defineStore } from "pinia"
const useHome = defineStore('home', {
state: () => ({
count: 1,
}),
// 1. 定义 actions
actions: {
// 可以接收调用时传递过来的参数
increment() {
// 在 actions 中可以使用 this,this 指向 store 实例
this.count++
}
}
})
export default useHome
// src/components/Home.vue
<template>
<div>{{ homeStore.count }}</div>
<button @click="handleAdd">+1</button>
</template>
<script setup>
// 2. 使用 actions
import useHome from './store/home'
const homeStore = useHome()
const handleAdd = () => {
homeStore.increment()
}
</script>
<style scoped>
</style>
原文地址:https://blog.csdn.net/wsln_123456/article/details/145135766
免责声明:本站文章内容转载自网络资源,如侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!