什么是状态管理
- 将需要共享的状态,放在一个全局单例中来管理,这样在任何地方都可以直接访问这个单例获取状态或改变状态,操作简单且更容易维护。
为什么需要状态管理?
- 当多个组件需要使用同一状态时,如果使用Props传递的方式,传递层次过深可能会导致代码冗长问题;
- 通过模版引用获取父/子实例或通过事件触发去改变和同步多个状态的副本,会导致这些模式的健壮性不理想,代码难以维护;
实现方式
- reactive、ref、computed,只适合SPA,如果是SSR项目则不合适,需要使用Pinia,后面介绍
代码示例
//store.js
import { reactive } from 'vue'
export const storeDemo = reactive({
count: 0,
increase(){
this.count++
}
})
// A.vue
import { storeDemo } from './store.js'
......
<template>
<h1>{{storeDemo.count}}</h1>
<button @click="storeDemo.increase()">+1</button>
</template>
// B.vue
import { storeDemo } from './store.js'
......
<template>
<h1>{{storeDemo.count}}</h1>
<button @click="storeDemo.increase()">+1</button>
</template>
- Pinia 满足以下需求
- 更强的团队协作约定
- 与 Vue DevTools 集成,包括时间轴、组件内部审查和时间旅行调试
- 模块热更新 (HMR)
- 服务端渲染支持
pinia使用:
1.安装
npm install pinia
//or
yarn install pinia
2.在vue中使用
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');
3.定义一个pinia仓库(目录例如:stores)用来管理不同状态
代码示例
import { defineStore } from 'pinia';
const useUserStore = defineStore('user', {
//state 存储数据的地方
state: () => ({
username: 'John',
userRole: 'customer'
}),
//Getters 和computed类似,属于计算属性,依赖state的值进行计算
getters: {
isAdmin() {
return this.userRole === 'admin';
}
},
//Actions 主要用于修改state或者执行一些异步操作
actions: {
updateUsername(newUsername) {
this.username = newUsername;
}
}
});
//----------------------------------------------------------------------
// 异步操作示例:
import { defineStore } from 'pinia';
const useProductStore = defineStore('product', {
state: () => ({
products: []
}),
actions: {
async fetchProducts() {
const response = await fetch('https://example.com/products');
this.products = await response.json();
}
}
});
//-----------------------------------------------------------------------
//组件使用:
<script setup>
import { useUserStore } from './stores/userStore';
const userStore = useUserStore();
</script>