Vuex状态机的快速了解与实例应用
一. 速识概念:
1. 组件之间共享数据的方式:
通常有以下几种方式:
- 父向子传值:v-bind 属性绑定;
- 子向父传值:v-on 事件绑定;
- 兄弟组件之间共享数据:EventBus;
- 按照官方的话来说,Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。Vuex 也集成到 Vue 的官方调试工具 devtools extension (opens new window),提供了诸如零配置的 time-travel 调试、状态快照导入导出等高级调试功能。
- 简单来说,Vuex就是实现组件全局状态(数据)管理的一种机制,可以方便的实现组件之间数据的共享。
- 能够在vuex中集中管理共享的数据,易于开发和后期维护。
- 能够高效地实现组件之间的数据共享, 提高开发效率。
- 存储在vuex中的数据都是响应式的,能够实时保持数据与页面的同步。
- 解决了非父子组件的消息传递(将数据存放在state中)。
- 减少了AJAX请求次数,有些情景可以直接从内存中的state获取。
二. 基本使用: 1.安装依赖包:
npm install vuex --save
2.导入依赖包:
import Vue from 'vue'import Vuex from 'vuex'Vue.use(Vuex)
3.创建store对象:
import Vue from 'vue'import Vuex from 'vuex'Vue.use(Vuex)const store = new Vuex.Store({//state中存放的就是全局共享的数据state: {count: 0}})
4. 将store对象挂载到vue实例中:
new Vue({el: '#app',store})
此时所有组件就可以从store中获取数据了。
三.创建项目: 下面为创建一个vue项目流程,后面会有案例:
(1)打开cmd窗口输入 vue ui 打开vue的可视化面板:
文章图片
(2)选择新建项目路径:
文章图片
(3)命名:
文章图片
(4)手动选择配置,注意用的是vue2版本:
文章图片
文章图片
(5)创建:
文章图片
(6)下一步:
文章图片
(7)创建成功,到对应目录打开vscode开始编程:
文章图片
(8)运行项目:
文章图片
四. 讲解前提: 前提(注意):
? ?写一个计数器小案例,从案例中配合概念能更快上手vuex。所以下面核心概念中的代码部分是基于这个小案例来演示的。目标:写两个子组件,有一个公共count值,在父组件中,其中一个组件实现点击后count值减1,一个组件实现点击后count值增1。
父组件 App.vue 初始代码:
--------------------
子组件Add.vue初始代码:
count值为:
子组件Reduce.vue初始代码:
count值为:
store对象初始代码为:
import Vue from 'vue'import Vuex from 'vuex'Vue.use(Vuex)export default new Vuex.Store({state: {count: 0}})
初始效果:
文章图片
五.核心概念: 1.state:
? ?按照官方的话来说,如下:Vuex 使用单一状态树——是的,用一个对象就包含了全部的应用层级状态。至此它便作为一个“唯一数据源 (SSOT)”而存在。这也意味着,每个应用将仅仅包含一个 store 实例。
? ?简单来说,就是State提供唯一的公共数据源, 所有共享的数据都要统一放到Store的State中进行存储。1.1 组件中访问state的第一种方式: 组件中直接输入以下命令:
this.$store.state.引用的数据名字如在Add.vue子组件中引用:
count值为:{{this.$store.state.count}}
//下面部分代码跟前面一样无改变,所以省略了
看效果,显示了count的值为0:
文章图片
1.2 组件中访问state的第二种方式: (1)从 vuex 中按需导入 mapState 函数
import { mapState } from 'vuex'
(2)通过刚才导入的mapState函数,将当前组件需要的全局数据,映射为当前组件的computed计算属性:
computed: {...mapState([count])}
小知识:computed用来监控自己定义的变量,该变量不在data里面声明,直接在computed里面定义,然后就可以在页面上进行双向数据绑定展示出结果或者用作其他处理;如在Reduce.vue子组件中引用:
count值为:{{count}}
看效果,同样显示了count的值为0:
文章图片
2. mutation:
? ?按照官方的话来说,更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数。
? ?简单来说就是Mutation用于变更Store中的数据。? ?比如,要实现count值自增加1的操作,那就在先motations里定义一个自增加1的函数。然后对应子组件想用,该组件就直接引入mutation并调用对应的函数就好。
①只能通过mutation变更Store数据,不可以直接操作Store中的数据。
②通过这种方式虽然操作起来稍微繁琐一些,但是可以集中监控所有数据的变化。
如下,Add.vue子组件要实现自增加1功能:
先在状态机里的mutations里定义一个能实现自增的函数add:
export default new Vuex.Store({state: {count: 0},mutations: {//自增加1函数add(state){state.count++}}})
2.1 触发mutation的第一种方式: Add.vue子组件里给按钮绑定点击事件,并触发mutation:
count值为:{{this.$store.state.count}}
看效果实现了点击自增:
文章图片
2.2 触发mutation并传参数: 当然,当组件里调用mutation里函数时,也是可以传参数的。
比如,有一个自增函数,但增多少看调用时传入的参数:
export default new Vuex.Store({state: {count: 0},mutations: {// 传入参数,第一个一定是state,第二个为传入的参数//自增加 n 的函数addN(state,n){state.count+= n}}})
对应组件调用时要传入参数:
methods: {btnAdd2() {// 引入mutation的方式,触发addN函数// 并传参,自增加6吧this.$store.commit('addN',6)}}
2.1 触发mutation的第二种方式: (1)从 vuex 中按需导入 mapMutations 函数
import { mapMutations } from 'vuex'
(2)通过刚才导入的mapMutations函数,将需要的mutations函数,映射为当前组件的methods方法:
methods: {...mapMutations(['add','addN'])}
实战,实现Reduce.vue组件的点击自减1的功能要求:
状态机添加自减函数:
export default new Vuex.Store({state: {count: 0},mutations: {//自增加1函数add(state){state.count++},// 自减1的函数sub(state){state.count--}}})
Reduce.vue组件点击按钮实现自减1:
count值为:{{count}}
看效果:
文章图片
3.Action:
? ?至此,第四大点里的案例已经完成,已经实现了自增和自减,现在对案例做改进,要我们点击按钮一秒后再自增和自减,该怎么实现?可以在状态机里的mutation里的函数是加一个1秒定时器吗,这肯定是不行的,因为mutation里不支持异步操作,那咋办,当当当,Action闪亮登场。
? ? Action 可以包含任意异步操作,所以它用来处理异步任务。先在状态机里定义Action:
? ?Action 提交的是 mutation,而不是直接变更状态。记住它并不能直接修改state里的数据,只有mutation能修改。就是说,如果通过异步操作变更数据,必须通过Action,而不能使用Mutation,但是在Action中还是要通过触发Mutation的方式间接变更数据。
export default new Vuex.Store({state: {count: 0},mutations: {//自增加1函数add(state){state.count++},// 自减1的函数sub(state){state.count--}},// 定义action,里面的addAsync函数实现1秒后执行mutation里的add函数actions: {addAsync(context) {setTimeout(()=>{// 必须通过context.commit()触发mutation才行context.commit('add')},1000)} }})
Action 函数接受一个与 store 实例具有相同方法和属性的 context 对象,因此你可以调用 context.commit 提交一个 mutation。
3.1 触发Action的第一种方式: 更改组件Add.vue代码,引入Action,实现异步自增操作。
count值为:{{this.$store.state.count}}
看效果,实现1秒后自增:
文章图片
3.2 触发Action异步任务并传参数: 当然,当组件里调用action里函数时,也是可以传参数的。
比如,有一个点击1秒后才执行的自增函数,但增多少看调用时传入的参数:
定义:
export default new Vuex.Store({state: {count: 0},mutations: {// 传入参数,第一个一定是state,第二个为传入的参数//自增加 n 的函数addN(state,n){state.count+= n}},actions: {// 有参数 n,这个n又传给了mutation里的addN函数addNAsync(context,n) {setTimeout(()=>{context.commit('addN',n)},1000)} }})
对应组件调用时要传入参数:
methods: {btnAdd2() {// 调用dispatch函数// 触发action时传参数,为 6 吧,表示自增6this.$store.dispatch('addNAsync',6)}}
3.3 触发Action的第二种方式: (1)从 vuex 中按需导入 mapActions 函数
import { mapActions } from 'vuex'
(2)通过刚才导入的mapActions函数,将需要的actions函数,映射为当前组件的methods方法:
methods: {...mapActions(['add','addN'])}
实战,实现Reduce.vue组件的点击一秒后自减1的功能要求:
定义actions里的subAsync为一秒后自减函数:
export default new Vuex.Store({state: {count: 0},mutations: {//自增加1函数add(state){state.count++},// 自减1的函数sub(state){state.count--}},actions: {addAsync(context) {setTimeout(()=>{context.commit('add')},1000)},subAsync(context) {setTimeout(()=>{context.commit('sub')},1000)} }})
更改Reduce.vue代码,实现功能:
count值为:{{count}}
看效果:
文章图片
4. Getter:
? ? Getter用于对Store中的数据进行加工处理形成新的数据。且要注意的是它并不会修改state中的数据。如,有一个返回当前count+1的getter函数:
①Getter 可以对Store中已有的数据加工处理之后形成新的数据,类似Vue的计算属性。
②Store 中数据发生变化,Getter 的数据也会跟着变化。
export default new Vuex.Store({state: {count: 0}, getters: {showNum(state){return`当前count值加1为:${state.count+1}`}}})
4.1 触发getters的第一种方式:
this.$store.getters.名称
在App.vue组件中显示:
--------------------
--------------------
{{this.$store.getters.showNum}}
效果:
文章图片
4.2触发getters的第二种方式: (1)从 vuex 中按需导入 mapGetters 函数
import { mapGetters } from 'vuex'
(2)通过刚才导入的mapGetters函数,将当前组件需要的全局数据,映射为当前组件的computed计算属性:
computed: {...mapGetters(['showNum'])}
还是在App.vue中使用把:
--------------------
--------------------
{{showNum}}
看,一样的效果:
文章图片
六.总结: 【Vuex状态机的快速了解与实例应用】到此这篇关于Vuex状态机的快速了解与实例应用的文章就介绍到这了,更多相关Vuex状态机应用内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
推荐阅读
- 热闹中的孤独
- JAVA(抽象类与接口的区别&重载与重写&内存泄漏)
- 放屁有这三个特征的,请注意啦!这说明你的身体毒素太多
- 一个人的旅行,三亚
- 布丽吉特,人生绝对的赢家
- 慢慢的美丽
- 尽力
- 一个小故事,我的思考。
- 家乡的那条小河
- 《真与假的困惑》???|《真与假的困惑》??? ——致良知是一种伟大的力量