- Pinia 在语法上兼容了Composition API,代码的风格更加简易,便捷使用,而且兼容vue2。
- Pinia 丢弃了 Mutations,直接通过 actions 可以修改 state ,同时兼容同步操作、异步操作。
- Pinia 添加了 Plugins 插件,方便开发者扩展。
一、Vuex
二、Pinia
Pinia 是 Vue 的存储库,它允许您跨组件/页面共享状态。有vue2写法也有vue3写法,这里只介绍vue3写法。
2.1 Pinia核心概念
2.1.1 State
state 是存储在 store 中的数据。它是一个普通的 JavaScript 对象,可以包含任意数量的属性。
2.1.2 Getters
getters 是 store 中的计算属性。它们可以像计算属性一样返回值,并且可以访问 store 中的 state。
2.1.3 Actions
actions 是 store 中的方法。它们可以包含同步操作和异步操作,并且可以访问 store 中的 state 和 getters。
2.1.4 Plugins
plugins 是 store 中的插件。它们可以用于扩展 store 的功能,例如添加全局状态或修改 store 的行为。
2.2 安装
npm install pinia
2.3 pinia使用
main.js 中引入 pinia,通过 createPinia 创建一个 store ,注入 app 即可。
import { createPinia } from 'pinia'
app.use(createPinia())
2.4 创建store
在 src/stores 目录下创建一个 index.js 文件,用于模块管理 store。
export * from "./work/index"
export * from "./user/index"
定义了两个 store,分别是 work 和 user。
// stores/user/index.ts
import { ref, computed } from 'vue'
import { defineStore } from 'pinia'
export const userStore = defineStore('user', () => {
// state
const name = ref('Liu');
// actions
const setName = (nickname: string) => {
name.value = nickname
}
// 异步actions
const asyncSetName = async (nickname: string) => {
setTimeout(() => {
name.value = nickname
}, 2000)
}
// getters
const evaluateUser = computed(() => {
return `${name.value} is a beauty.`
})
return { name, evaluateUser, setName, asyncSetName }
})
// stores/work/index.ts
import { ref } from 'vue'
import { defineStore } from 'pinia'
export const workStore = defineStore('work', () => {
const workName = ref('前端开发工程师');
const setWorkName = (newName: string) => {
workName.value = newName
}
return { workName, setWorkName }
})
2.5 组件中使用store
<template>
<div class="wrap">
<div>Pinia 使用方式</div>
<div>userStore中的name: {{user.name}}</div>
<div>userStore中的evaluateUser: {{user.evaluateUser}}</div>
<div>workStore中的workName: {{work.workName}}</div>
<div>userStore中通过插件加入的env: {{user.env}}</div>
<div>workStore中通过插件加入的env: {{work.env}}</div>
<button type="button" @click="user.setName('张三')">修改name</button>
<button type="button" @click="user.asyncSetName('李四')">异步修改name</button>
<button type="button" @click="work.setWorkName('无业游民')">修改工作</button>
</div>
</template>
<script setup>
import { userStore, workStore } from "@/stores/index";
const user = userStore();
const work = workStore();
</script>
<style scoped>
.wrap {
width: 100%;
height: 100%;
background-color: #fff;
color: black;
padding: 20px;
font-size: 16px;
}
.wrap button {
margin: 0 10px;
border-radius: 1px;
padding: 5px 10px;
border: 1px solid #ccc;
cursor: pointer;
}
</style>
2.6 使用plugins
创建一个 stores/plugin.ts
export function commonPiniaPlugin() {
return { env: "项目环境,每一个store都会被注入这个插件" };
}
首先需要在 main.js 里面引入 `stores/plugin.ts ,改写 pinia 的注入。
import { createPinia } from 'pinia'
import { commonPiniaPlugin } from './stores/plugin'
const pinia = createPinia()
pinia.use(commonPiniaPlugin)
app.use(pinia)
这样的话,所有的store中的state都会存在env这个属性。
最后感谢博主「kboyMeng」,戳我查看原文链接