提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
- 前言
- 一、状态管理之vuex
- 1.1 State
- 调用:
- 1.2 Mutation
- 在vuex中定义:
- 在组件中使用:
- 1.3 Action
- 在vuex中定义:
- 将上面的减法操作改为异步操作
- 在组件中使用:
- 1.4 Getter
- 1.4 Modules
- 二、状态管理之pinia
- pinia文件
- pinia->index.vue
- pinia->child.vue / pinia->child1.vue组件
- child.vue
- child1.vue
- modules文件
- info.ts
- todo.ts
- 总结
前言
组件之间的传值一般有哪些?有父子组件通讯,兄弟组件通讯…但是传参对于多层嵌套就显得非常繁琐,代码维护也会非常麻烦。因此就把组件共享状态抽取出来以一个全局单例模式管理,把共享的数据函数放进状态管理中,任何组件都可以进行使用。
提示:以下是本篇文章正文内容,下面案例可供参考
一、状态管理之vuex
Vue2通常使用的状态管理工具是vuex,它有五个核心概念 State、Getter、Mutation 、Action、 Module
1.1 State
提供唯一的公共数据源,所有共享的数据统一放到store的state进行储存,与data有点类似
在vuex中state中定义数据,可以在任何组件中进行调用
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
//数据,相当于data
state: {
name:"张三",
age:12,
count:0
},
})
调用:
调用的方法有好几种,这里只列举比较常用的方法
this.$store.state.全局数据名称
1.2 Mutation
更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的事件类型 (type)和一个回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数:
在vuex中定义:
其中参数state参数是必须的,也可以自己传递一个参数,如下代码,进行计数器的加减操作,加法操作时可以根据所传递参数大小进行相加,减法操作没有传参每次减一
在组件中使用:
定义两个按钮进行加减操作,并且使用commit触发Mutation操作
<template>
<div>
<button @click="btn">点我增加store仓库中的数据</button>
<button @click="btn1">点我减少store仓库中的数据</button>
</div>
</template>
methods:{
//加法
btn(){
this.$store.commit("addcount",10) //每次加十
}
//减法
btn1(){
this.$store.commit("reduce")
}
}
1.3 Action
Action和Mutation相似,一般不用Mutation 异步操作,若要进行异步操作,使用Action
在vuex中定义:
将上面的减法操作改为异步操作
在组件中使用:
直接使用 dispatch触发Action函数
this.$store.dispatch("asynAdd")
1.4 Getter
类似于vue中的computed,进行缓存,对于Store中的数据进行加工处理形成新的数据
1.4 Modules
当遇见大型项目时,数据量大,store就会显得很臃肿为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割:
二、状态管理之pinia
通常情况下在一个vue3项目中会创建一个store文件夹,项目比较大的时候数据量比较大,需要对状态管理数据进行分块管理。如下:
pinia文件
pinia->index.vue
<template>
<div class="box">
<h1>pinia</h1>
<div class="container">
<Child></Child>
<Child1></Child1>
</div>
</div>
</template>
<script setup lang="ts">
import Child from "./Child.vue";
import Child1 from "./Child1.vue";
//vuex:集中式管理状态容器,可以实现任意组件之间通信!!!
//核心概念:state、mutations、actions、getters、modules
//pinia:集中式管理状态容器,可以实现任意组件之间通信!!!
//核心概念:state、actions、getters
//pinia写法:选择器API、组合式API
</script>
<style scoped>
.box {
width: 600px;
height: 400px;
background: skyblue;
}
.container{
display: flex;
}
</style>```
## 2.1 State
>提供唯一的公共数据源,所有共享的数据统一放到store的state进行储存,与data有点类似
在vuex中state中定义数据,可以在任何组件中进行调用
```javascript
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
//数据,相当于data
state: {
name:"张三",
age:12,
count:0
},
})
pinia->child.vue / pinia->child1.vue组件
child.vue
<template>
<div class="child">
<h1>{{ infoStore.count }}---{{infoStore.total}}</h1>
<button @click="updateCount">点击我修改仓库数据</button>
</div>
</template>
<script setup lang="ts">
import useInfoStore from "../../store/modules/info";
//获取小仓库对象
let infoStore = useInfoStore();
console.log(infoStore);
//修改数据方法
const updateCount = () => {
//仓库调用自身的方法去修改仓库的数据
infoStore.updateNum(66,77);
};
</script>
<style scoped>
.child {
width: 200px;
height: 200px;
background: yellowgreen;
}
</style>
child1.vue
<template>
<div class="child1">
{{ infoStore.count }}
<p @click="updateTodo">{{ todoStore.arr }}{{todoStore.total}}</p>
</div>
</template>
<script setup lang="ts">
import useInfoStore from "../../store/modules/info";
//获取小仓库对象
let infoStore = useInfoStore();
//引入组合式API函数仓库
import useTodoStore from "../../store/modules/todo";
let todoStore = useTodoStore();
//点击p段落去修改仓库的数据
const updateTodo = () => {
todoStore.updateTodo();
};
</script>
<style scoped>
.child1 {
width: 200px;
height: 200px;
background: hotpink;
}
</style>
modules文件
info.ts
//定义info小仓库
import { defineStore } from "pinia";
//第一个仓库:小仓库名字 第二个参数:小仓库配置对象
//defineStore方法执行会返回一个函数,函数作用就是让组件可以获取到仓库数据
let useInfoStore = defineStore("info", {
//存储数据:state
state: () => {
return {
count: 99,
arr: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
}
},
actions: {
//注意:函数没有context上下文对象
//没有commit、没有mutations去修改数据
updateNum(a: number, b: number) {
this.count += a;
}
},
getters: {
total() {
let result:any = this.arr.reduce((prev: number, next: number) => {
return prev + next;
}, 0);
return result;
}
}
});
//对外暴露方法
export default useInfoStore;
todo.ts
//定义组合式API仓库
import { defineStore } from "pinia";
import { ref, computed,watch} from 'vue';
//创建小仓库
let useTodoStore = defineStore('todo', () => {
let todos = ref([{ id: 1, title: '吃饭' }, { id: 2, title: '睡觉' }, { id: 3, title: '打豆豆' }]);
let arr = ref([1,2,3,4,5]);
const total = computed(() => {
return arr.value.reduce((prev, next) => {
return prev + next;
}, 0)
})
//务必要返回一个对象:属性与方法可以提供给组件使用
return {
todos,
arr,
total,
updateTodo() {
todos.value.push({ id: 4, title: '组合式API方法' });
}
}
});
export default useTodoStore;
总结
提示:这里对文章进行总结: