一、Pinia
1. Pinia是什么?
基于 Vue.js 的状态管理库,用于管理应用程序的数据。
2.pinia的特点
- 充分利用了Vue3的响应性系统和Composition Api
- 类 Vuex 的 API
- 将应用程序的状态组织为存储库的形式,存储库包含状态(state)、动作(actions)、获取器(getters)等
- 支持在动作(actions)中执行异步操作,如发送网络请求、处理副作用等响应式状态管理
- 提供了插件系统
- 支持 TypeScript,并且提供了类型安全的 API 和开发体验
- 适用于大型应用程序,可以轻松管理复杂的状态逻辑和数据流。
3.使用
基本运用
//main.js文件
import { createPinia } from "pinia";
const pinia = createPinia();
createApp(App).use(pinia).mount('#app')
//src/store/index.js文件
import {defineStore} from 'pinia'
import { defineStore } from 'pinia'
// useStore 一般命名是use开头,useProductStore、useUserStore 等等
// defineStore 是用于定义存储库(store)的方法。它接受两个参数:storeName 和 storeDefinition。
// 1.storeName(必需):表示存储库的名称,是一个字符串。该名称用于在 Pinia 中唯一标识存储库,因此在应用程序中定义不同的存储库时,应确保每个存储库具有唯一的名称。
// 2.storeDefinition(必需):表示存储库的定义,是一个对象。该对象包含了存储库的配置、状态(state)、动作(actions)、获取器(getters)等。
export const useUserStore = defineStore('user', {
// 推荐使用 完整类型推断的箭头函数
state: () => {
return {
// 所有这些属性都将自动推断其类型
name: "zahngzahng",
age: 10
};
},
})
<template>
<!-- 在页面中直接使用就可以了-->
<div>name值:{{ userStore.name }}</div>
<div>age值:{{ userStore.age }}</div>
</template>
<script setup>
// 引入一下创建的store
import {useUserStore} from '../store/index'
// 因为是个方法,所以我们得调用一下
const userStore = useUserStore()
</script>
解构后响应式处理--storeToRefs函数
<template>
<!-- 在页面中直接使用就可以了-->
<div>name值:{{ userStore.name }}</div>
<div>age值:{{age }}</div>
<button @click="addAge">修改年龄</button>
</template>
<script setup>
// 引入一下创建的store
import {useUserStore} from '../store/index'
import {storeToRefs} from 'pinia'
const userStore = useUserStore()
const {age} = storeToRefs(userStore)
function addAge() {
userStore.age = userStore.age + 1
}
</script>
$patch函数修改store方法
<template>
<!-- 在页面中直接使用就可以了-->
<div>name值:{{ userStore.name }}</div>
<div>age值:{{ age }}</div>
<button @click="addAge">修改年龄</button>
</template>
<script setup>
// 引入一下创建的store
import {useUserStore} from '../store/index'
import {storeToRefs} from 'pinia'
const userStore = useUserStore()
const {age} = storeToRefs(userStore)
function addAge() {
// userStore.age = userStore.age + 1
userStore.$patch({
name: "James",
age: 39
})
}
</script>
$reset()函数重置state中数据
<template>
<!-- 在页面中直接使用就可以了-->
<div>name值:{{ userStore.name }}</div>
<div>age值:{{ age }}</div>
<button @click="addAge">修改年龄</button>
<button @click="restart">重置store</button>
</template>
<script setup>
// 引入一下创建的store
import {useUserStore} from '../store/index'
import {storeToRefs} from 'pinia'
const userStore = useUserStore()
const {age} = storeToRefs(userStore)
function addAge() {
userStore.age = userStore.age + 1
}
function restart() {
userStore.$reset()
}
</script>
getters
用于获取存储库中的状态(state)的方法
Getter的主要特点包括:
- 用于获取和计算存储库的状态。
- 可以接受参数进行动态计算。
- 在状态发生变化时,Getter会自动重新计算。
- 不能直接修改状态,只能读取状态。
export const useUserStore = defineStore('user', {
// 推荐使用 完整类型推断的箭头函数
state: () => {
return {
// 所有这些属性都将自动推断其类型
name: "curry",
age: 35,
};
},
getters: {
// 年龄乘以2
doubleAge: (state) => state.age * 2,
},
})
<template>
<div>doubleAge:{{ userStore.doubleAge }}</div>
</template>
<script setup>
import {useUserStore} from '../store/index'
const userStore = useUserStore()
</script>
actions
Action的主要特点包括:
- 用于操作和修改存储库的状态。
- 接受参数进行动态操作。
- 进行异步操作,如发送网络请求。
- 修改状态或触发其他动作。
import {defineStore} from 'pinia'
export const useUserStore = defineStore('user', {
// 推荐使用 完整类型推断的箭头函数
state: () => {
return {
// 所有这些属性都将自动推断其类型
name: "curry",
age: 35,
};
},
getters: {
// 年龄乘2
doubleAge: (state) => state.age * 2,
},
actions:{
incrementAge(num){
this.age += num
}
}
})
import {defineStore} from 'pinia'
// useStore 一般命名是use开头,useProductStore、useUserStore 等等
// defineStore 是用于定义存储库(store)的方法。它接受两个参数:storeName 和 storeDefinition。
// 1.storeName(必需):表示存储库的名称,是一个字符串。该名称用于在 Pinia 中唯一标识存储库,因此在应用程序中定义不同的存储库时,应确保每个存储库具有唯一的名称。
// 2.storeDefinition(必需):表示存储库的定义,是一个对象。该对象包含了存储库的配置、状态(state)、动作(actions)、获取器(getters)等。
export const useUserStore = defineStore('user', {
// 推荐使用 完整类型推断的箭头函数
state: () => {
return {
// 所有这些属性都将自动推断其类型
name: "curry",
age: 35,
};
},
getters: {
// 年龄乘2
doubleAge: (state) => state.age * 2,
},
actions:{
incrementAge(num){
this.age += num
}
}
})
总结 Getter主要用于获取数据,而Action主要用于执行操作和修改数据。
数据持久化
默认pinia数据是没有持久化的,刷新页面就变成默认值了,持久化需要安装插件pinia-plugin-persist
二、Vuex
1.Vuex是什么?
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式 + 库。
2. 使用场景
如果开发简单应用,不建议使用Vuex,store模式足够。 如果构建中大型单页应用,则需要考虑如何更好的在组件外部管理状态,推荐使用vuex.
3. Vuex中五个状态
State
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
//公共数据源,所有的共享数据统一到store里面的state,类似data
state:{
name:"温温",
sex:"女"
},
})
//使用
<div>{{$store.state.name}}</div> --在标签中
this.$store.state.name -- 调用
//映射为当前组件computed属性
import {mapState} from "vuex"
computed:{
...mapState(["name","sex"])
}
<div>{{name + sex}}</div>
Mutation
更改 Vuex 的 store 中的状态
state:{
name:"温温",
count:0
},
//mutation里面定义操作state的方法
mutations:{
addcount(state,num){
state.count=state.count + num
},
reduce(state){
state.count--
}
}
组件
<button @click ="addBtn"></button>
<button @click ="redBtn"></button>
1.使用commit触发Mulation操作
method:{
addBtn(){
this.$store.commit("addcount",8)
},
redBtn(){
this.$store.commit("reduce")
}
}
2.辅助函数映射
import {mapMutations} from "vuex"
methods:{
...mapMutations(["addcount","reduce"]),
addBtn(){
this.addcount(8);
},
redBtn(){
this.reduce();
}
Action
与Mutation类似,用来进行异步操作
actions:{
asyncAdd(context){
//异步
setTimeiout(()=>{
context.commit("reduce")
},1000);
}
}
//使用
1.dispath触发Action
this.$store.dispatch("asynAdd")
2.辅助函数mapActions
...mapActions(["asyncAdd"]),
addbtn(){
this.asyncAdd();
},
Getter
类似于vue中的computed
Modules
切割store成模块---当数据量特别大
modules:{
newinfo:{
//成为带命名空间的模块
namespaced:true,
state:{
newname:"温温",
},
mutations:{},
actions:{},
getter:{}
},
userinfo:{
state:{
username:"温温"
},
...
}
选择Pinia的原因
Pinia 和 Vuex 设计类似,都沿用 Flux 的思想,并针对 Vue 框架单独进行了一些设计上的优化。但 Pinia 在许多方面优于其他解决方案,包括 Vuex。主要优势如下:
1)直观的设计:
Pinia 的 API 设计简单直接,使创建和组织存储变得简单,类似于创建组件。这种方法减少了需要模板代码的需求,不用像 Vuex 一样去关注 commit 还是 dispatch。Pinia 为开发人员提供了一种更容易更好地理解您的 store 的方式。
2)更好的 TS 支持:
无需创建自定义的复杂封装程序来支持 TypeScript,所有内容都是类型化的,API 的设计方式也尽可能利用了 TS 类型推断。
3)舍弃了 Mutations 和 module: Pinia 通过在创建 store 时指定 name 来区分不同的 store,不再需要 module。
4)更好的模块结构:
模块结构不再嵌套。您仍然可以通过导入和使用一个存储空间来隐式嵌套另一个存储空间,但 Pinia 通过设计提供了一种扁平结构,同时仍然支持存储空间之间的交叉组合方式。
5)天生的轻量:
Pinia 只有 1KB,非常容易集成到您的项目中。提高应用程序的性能。