浅谈|浅谈 VueX 状态管理模式
前言
我们知道什么是VueXVue
组件通讯基本的方式有子传父
,父传子
,平行兄弟组件通信
,那么在简单的应用当中,Vue Store
这种单一状态管理基本的方式就可以满足我们的日常需求,但是若要遇到大型复杂系统,你比如说,我有个数据,需要在多个实例,多层实例之间来回传递共享,那么一层一层的接收与发送就显得非常繁琐,并且组件之间的状态管理会显得十分麻烦,那么这个时候我们就应该考虑应用VueX
了。
VueX
是vue
的状态管理
开发模式,以可预测
的方式发生变化,那么首先先解释下相关基本组成成分1.事件组成
2.基本对象组成
dispatch
: 触发事件,是唯一能执行action的方法commit
:状态改变提交操作方法。对mutation进行提交,是唯一能执行mutation的方法。mutate
:状态改变过程render
:编译过程
3.基本流程
state
: 存储状态(变量)getters
: 可以理解为store 的计算属性,说的通俗一点就是我可以通过getters将state重新赋值,重新定义mutations
: 修改状态并且是同步的方法(唯一改变state
的途径)actions
: 提交的是mutation
,而不是直接变更状态。负责处理Vue Components
接收到的所有交互行为。包含同步/异步操作,支持多个同名方法,按照注册的顺序依次触发,该模块提供了Promise
的封装,以支持action
的链式触发modules
:store
的子模块,为了开发大型项目,方便模块化状态管理而使用的*注:VueX不能直接更改状态,必须通过提交(commit) mutations
1.Vue
组件接收状态并且交互,调用dispatch()
方法
2.dispatch()
方法触发actions
里的相关对应方法
3.actions
里的相关对应方法如果需要改变state
状态,则调用commit()
方法
4.commit()
方法提交mutation
修改state
5.render
的过程通过getters
对应的计算属性获取到新的state
状态
6.重新渲染Components
,更新视图
*注:VueX一旦更改了state状态,与之相关的所有组件都会收到相应变化
文章图片
4.接下来我将写一个基于模块化的
Vuex
状态管理的使用(这里就是使用Module
将Store
分割),因为基于单一的状态管理,所有的状态操作都存放在一个对象里,会变得十分繁琐,同样对象会堆得越来越大,那么首先我们先看下基本的结构是什么样子const store = new Vuex.Store({
state: { ... },
mutations: { ... },
actions: { ... },
getters: { ... },
modules: {
a: moduleA,
b: moduleB
}
})
5.首先,我通过一个
Demo
实例来解释VueX
如何使用,结构如下文章图片
image.png 【浅谈|浅谈 VueX 状态管理模式】
6.这里我做了全局和局部模块拆分的处理,全局
store
存放在global.js
,模块化的以文件为单位,存放在modules
文件夹下,最后通过index.js
合并导出.同样我用两个子组件ChildA
、ChildB
,一个父组件Parents
来说明组件之间如何实现全局控制。代码示例如下global.js
/**
* Created by Echonessy on 2019.09.29
* 全局store 配置
*///components 执行dispatch('addAction')
// 触发actions的addAction方法
//addAction通过commit('add')触发mutations的add方法改变state
//getter计算后重新渲染到页面上//golbal state
export const state = {
golbalNumber:0
}
//golbal getters
export const getters = {
golbalNumber: state => state.golbalNumber+'_golbalGetters',
}
//golbal mutations
export const mutations = {
addGolbalMutation:state => {state.golbalNumber++;
},
subGolbalMutation:state => {state.golbalNumber--;
},
}
//golbal actions
export const actions = {
addGolbalAction ({ commit }) {
commit('addGolbalMutation')
},
subGolbalAction ({ commit }) {
commit('subGolbalMutation')
},
}export default {
state,
getters,
mutations,
actions
}
childa.js
/**
* Created by Echonessy on 2019.09.29
* childa 模块 配置
*/
export const state = {
number:1
}export const getters = {
childNumber: state => state.number+'_fromChildA',
}export const mutations = {
addMutation:state => {
state.number++;
},
subMutation:state =>{
state.number--;
}
}export const actions= {
addAction ({ commit }) {
commit('addMutation')
},
subAction({ commit }){
commit('subMutation')
}
}export default {
namespaced: true, //在使用模块化的时候,dispatch('childb/addAction')
state,
getters,
mutations,
actions
}
childb.js
/**
* Created by Echonessy on 2019.09.29
* childb 模块 配置
*/
export const state = {
number:1
}export const getters = {
childNumber: state => state.number+'_fromChildB',
}export const mutations = {
addMutation:state => {
state.number++;
},
subMutation:state =>{
state.number--;
}
}export const actions= {
addAction ({ commit }) {
commit('addMutation')
},
subAction({ commit }){
commit('subMutation')
}
}export default {
namespaced: true, //在使用模块化的时候,dispatch('childb/addAction')
state,
getters,
mutations,
actions
}
-
index.js
主入口
import Vue from 'vue'
import Vuex from 'vuex'
import global from './global'Vue.use(Vuex)const modulesFiles = require.context('./modules', true, /\.js$/);
// module 合并
const modules = modulesFiles.keys().reduce((modules, modulePath) => {
// set './app.js' => 'app'
const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1');
const value = https://www.it610.com/article/modulesFiles(modulePath);
modules[moduleName] = value.default
return modules
}, {})const obj = {}
obj.modules = modules;
const options = Object.assign(global,obj)
const store = new Vuex.Store(options)export default store
7.
main.js
主入口文件引入import Vue from 'vue'
import App from './App'
import router from './router'
import store from "./store";
Vue.config.productionTip = false/* eslint-disable no-new */
new Vue({
el: '#app',
router,
store,
components: { App },
template: ''
})
8.我们打印
index.js
里的options
,结构如下,我们可以看到整个store
的基本结构文章图片
image.png
9.上面已经讲了
VueX
的运行流程,那么我们在组件内如何去修改
state
? 我用一个
Parents
组件就能够完全说明
parents.vue
我是父组件
全局state {{$store.state}}
全局getters {{$store.getters}}
模块A => {{$store.getters['childa/childNumber']}}
.child{border: 1px solid #ccc;
box-sizing: border-box;
padding: 30px;
}
.single{line-height: 40px;
}
10.基本效果
文章图片
11.最后代码地址:demo
推荐阅读
- 停下“忙乱”的状态
- Java基础-高级特性-枚举实现状态机
- VueX--VUE核心插件
- 老年状态
- Android超简单实现沉浸式状态栏
- 生活最好的状态
- 2019-09-08
- 性能测试中QPS和TPS的区别
- vuex|vuex 基础结构
- VueX(Vuex|VueX(Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式)