一、Pinia是什么?
Pinia 是 Vue 的存储库,它允许跨组件/页面共享状态。实际上,pinia就是vuex的升级版,官网也说过,为了尊重原作者,所以取名pinia,而没有取名Vuex,所以大家可以直接将pinia比作为Vue3的Vuex。
二、为什么要使用pinia?
- 状态管理:Pinia 允许你在应用级别管理和存储状态。你可以创建多个 store,每个 store 都有自己的状态和行为,都是独立的,互相不影响。这有助于将你的状态管理逻辑组织得更清晰。
- 简洁的 API:Pinia 的 API 非常简洁且易于理解。只有state、getter、action。pinia中action支持同步和异步,Vuex不支持。你可以使用
defineStore
函数创建一个新的 store,然后在你的组件中使用useStore
函数来获取 store 的实例。 - DevTools 支持:Pinia 提供了强大的 DevTools 支持,包括时间旅行、状态查看和修改等。
- Server-Side Rendering (SSR) 支持:Pinia 支持在服务器端渲染 (SSR) 的应用中使用,允许你在服务器上预填充状态,然后在客户端接管。
- TypeScript 支持:Pinia 提供了出色的 TypeScript 支持,让你可以利用 TypeScript 的类型检查功能编写更稳健的代码。
- 灵活的插件系统:Pinia 提供了一个插件系统,你可以用来扩展 Pinia 的功能或改变其行为。pinia支持插件来扩展自身功能。
- 体积非常小,只有1KB左右。
理解 Pinia 的核心概念如状态、动作、和获取器
Pinia 的核心概念包括状态(State)、动作(Actions)和获取器(Getters)。这些概念为你提供了一种组织和管理应用状态的方式。
状态(State):状态是你在 store 中存储的数据。每个 Pinia store 都有自己的状态,这个状态是一个 JavaScript 对象。你可以在定义 store 时初始化状态:
import { defineStore } from 'pinia';
const useStore = defineStore({
id: 'myStore',
state: () => ({
count: 0,
user: null,
}),
});
在这个例子中,count
和 user
就是这个 store 的状态。
动作(Actions):动作是一种修改 store 状态的方法。在 Pinia 中,你可以在 actions
属性中定义动作:
import { defineStore } from 'pinia';
const useStore = defineStore({
id: 'myStore',
state: () => ({
count: 0,
}),
actions: {
increment() {
this.count++;
},
},
});
在这个例子中,increment
就是一个动作,它将 count
的值增加 1。
获取器(Getters):获取器是一种依赖于 store 状态并产生计算值的函数。这些值将被缓存,直到依赖的状态改变。在 Pinia 中,你可以在 getters
属性中定义获取器:
import { defineStore } from 'pinia';
const useStore = defineStore({
id: 'myStore',
state: () => ({
count: 0,
}),
getters: {
doubleCount() {
return this.count * 2;
},
},
});
在这个例子中,doubleCount
就是一个获取器,它返回 count
的两倍。
通过这些核心概念,Pinia 提供了一种简单而强大的方式来管理和操作你的应用状态。
项目中引用
安装pinia
npm install pinia@next
mian.js
import { createApp } from 'vue'
import { createPinia } from 'pinia';
import App from './App.vue'
// 创建 Pinia 实例
const pinia = createPinia();
// 创建 Vue 应用
const app = createApp(App);
app.use(pinia).mount('#app')
// createApp(App).mount('#app')
stores/userStore.js
import { defineStore } from 'pinia';
export const useUserStore = defineStore('user', {
state: () => ({
users: [
{ id: 1, name: 'Alice', age: 28, profession: 'Engineer' },
{ id: 2, name: 'Bob', age: 24, profession: 'Designer' },
{ id: 3, name: 'Lili', age: 31, profession: 'Sunny' }
],
selectedUser: null
}),
actions: {
selectUser(user) {
this.selectedUser = user;
}
}
});
components/userList.vue
<template>
<ul>
<li v-for="user in users" :key="user.id" @click="selectUser(user)">
{{ user.name }}
</li>
</ul>
</template>
<script setup>
import { ref } from "vue";
import { useUserStore } from "../stores/userStore";
const userStore = useUserStore();
const users = ref(userStore.users);
// 当用户被点击时,更新 Pinia store 中的 selectedUser 状态
const selectUser = (user) => {
userStore.selectUser(user);
};
</script>
components/UserProfile.vue
<template>
<div v-if="user">
<h2>{{ user.name }}</h2>
<p>Age: {{ user.age }}</p>
<p>Profession: {{ user.profession }}</p>
</div>
</template>
<script setup>
import { defineProps } from "vue";
defineProps({
user: {
type: Object,
required: false,
default: null,
},
});
</script>
App.vue
<template>
<div id="app">
<UserList />
<UserProfile :user="selectedUser" />
</div>
</template>
<script setup>
import { computed } from "vue";
import { useUserStore } from "./stores/userStore";
import UserList from "./components/UserList.vue";
import UserProfile from "./components/UserProfile.vue";
const userStore = useUserStore();
// 使用 computed 保证响应性
const selectedUser = computed(() => userStore.selectedUser);
</script>
暂时理解就这样