前端学习12 pinia 和 vuex 状态管理
在现代前端开发中,状态管理是一个至关重要的方面。尤其是在大型应用中,如何高效、清晰地管理状态不仅影响着代码的可读性和可维护性,还对应用的性能有直接的影响。在 Vue3 中,Vuex 和 Pinia 是两种主要的状态管理库,这两者各有不同的设计理念和使用方式。
1.vuex
Vuex 是 Vue.js 官方的状态管理库。它采用了 Flux 的思想,提供了一个集中式存储,允许组件以不同的方式共享状态。Vuex 的核心概念包括 State、Getters、Mutations 和 Actions。
其中:
1.State: 应用的状态存储。
2.Getters: 类似于计算属性,用于计算基于状态的派生状态。
3.Mutations: 处理状态的唯一方式,直接修改状态。
4.Actions: 进行异步操作,并提交 Mutations。
5.modules:进行划分模块。
vuex示例代码:
// store.js
import { createStore } from 'vuex';
const store = createStore({
state: {
//状态的存储
count: 0,
},
getters: {
//计算其中的派生元素
doubleCount(state) {
return state.count * 2;
},
},
mutations: {
//定义其中的操作
increment(state) {
state.count++;
},
},
actions: {
//进行异步操作,并提交 Mutations。
incrementAsync({ commit }) {
setTimeout(() => {
commit('increment');
}, 1000);
},
},
});
export default store;
使用vuex:
<template>
<div>
<p>Count: {{ count }}</p>
<p>Double Count: {{ doubleCount }}</p>
<button @click="increment">Increment</button>
<button @click="incrementAsync">Increment Async</button>
</div>
</template>
<script>
import { mapState, mapGetters, mapActions } from 'vuex';
export default {
computed: {
...mapState(['count']),
...mapGetters(['doubleCount']),
},
methods: {
...mapActions(['increment', 'incrementAsync']),
},
};
</script>
2.pinia
Pinia 是一个新兴的状态管理库,也是 Vue.js 的官方推荐替代方案。它为 Vue 3 提供了一种更简单、更具灵活性的状态管理方式,与 Vuex 相比,Pinia 在设计上更现代化,支持 Composition API,使得开发者在使用时更加方便。
其中:
Store: 状态存储的基本单位,通过建立一个或多个 Store 来管理状态。这是与vuex最主要的区别。
State: 用于保存应用的响应式状态。
Getters: 计算属性的延伸,基于状态计算派生值。
Actions: 包含了执行异步操作的行为和直接修改状态的方法。
3.pinia的使用
3.1 piniad的创建
import { createApp,h } from 'vue'
import App from './App.vue'
import { createPinia } from 'pinia'
const app = createApp(App)
app.use(createPinia())
3.2 pinia 定义store
在深入研究核心概念之前,我们需要知道 Pinia 是使用 defineStore() 定义的,并且它需要一个唯一的 name 作为第一个参数传递: name(也称为id)是必需的,Pinia使用 name 参数将 Store 连接到 devtools。
将返回的函数命名为 use…
是一种跨组件的约定,使其用法规范化。
defineStore(name,options)
- name: 必传,类型
string
- options:{}
import { defineStore } from 'pinia'
// useStore可以是任何类似useUser、useCart的东西
// 第一个参数是应用程序中 Store 的唯一id
export const useStore = defineStore('main', {
// state: () => ({ count: 0 }),
state:()=>{
return {
// 所有这些属性都将自动推断其数据类型
items: [],
counter: 0,
name: 'Eduardo',
isAdmin: true,
}
},
getters: {
doubleCount: (state) => state.counter * 2,
//doubleCount(state){
// console.log(this,'想要在getter中获取该store的其他内容则不能用箭头函数,')
// return state.counter * 2
//},
},
actions: {
increment(num,test1,test2) {
console.log(num,test1,test2)
this.counter++
},
randomizeCounter() {
this.counter = Math.round(100 * Math.random())
},
}
})
3.3 使用 Store
我们之所以声明store,是因为在setup()
内部调用useStore()
之前不会创建存储。
<template>
<p>Double count is {{ store.doubleCount }}</p>
</template>
<script>
import { mapState } from 'pinia'
import { useStore} from '@/stores/counter'
export default {
setup() {
const store = useStore()
store.counter++
store.$patch({ // 除了直接用store.counter++改变store之外,您还可以调用该$patch方法。state它允许您对部分对象同时应用多个更改:
counter: store.counter + 1,
name: 'Abalam',
})
store.$patch((state) => { // $patch 方法还接受一个函数,用于应对复杂数据的修改过程
state.items.push({ name: 'shoes', quantity: 1 })
state.isAdmin = false
})
store.increment(9,'测试多参数1','测试2') // 调用 actions 并传入参数
store.randomizeCounter() // 调用 actions
return {
// 您可以返回整个store实例以在模板中使用它
store,
}
},
computed: {
storeCounter() {
return this.store.counter * 3
},
// ...mapState(useCounterStore, ['counter']) // 没有 setup 的时候才使用这方式
},
}
</script>
4.Vuex vs Pinia
现在我们来比较 Vuex 和 Pinia 的优缺点。
4.1 API 和易用性
Vuex:
采用认证的 Flux 风格,有一定的学习曲线,需要掌握多个概念(状态、getter、mutation、action)。对于小型应用来说,可能会显得过于复杂。
Pinia:
设计更为简单,结合了 Composition API,让开发者能够更直观地管理状态。尤其是 Vue 3 的 Setup 语法糖,使用更加直观。
4.2 响应式
Vuex: 响应式总是要依赖于 Vue 的响应式系统,并且有多种约定(例如 Mutation),使用中需要更小心。
Pinia:
完全基于 Vue 3 的响应式系统,状态变化后组件自动更新,无需额外的处理。
#前端学习#