vue踩坑笔记06---vuex的state,getter,mustation,action,module
vue踩坑笔记06---vuex的state,getter,mustation,action,module
Vuex是什么?
官方文档说明:
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
说白了,vuex就是一个工厂,里面包含存放数据的仓库。
Vuex核心属性:
vuex中给出了几个核心名词,state,getter,mutation,action,module。
我们画图说明。
属性名 | 描述 |
---|---|
state | 仓库,里面存放数据 |
getter | 搬运工小组,有无数个搬运工,只负责从厂房往外搬东西 |
mutation | 操作工小组,有无数个操作工,负责更新货物,只能同步进行 |
action | 操作工小组,有无数个操作工,负责更新货物,可以异步进行 |
module | 工厂里的厂区,vuex里面可以有无数个厂区 |
vuex的使用:
要使用vuex,首先要下载vuex包。
// 下载vuex包 npm install --save vuex
然后我们在src目录下,创建一个store目录,在该目录下创建一个index.js文件。
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) // 数据仓库 const state = { // 定义一个公共属性,并初始化赋值 name: '厂长' } // 数据的搬运工,我可以在其中定义搬运规则 const getters = { getName: function (state) { // 在这里定义搬运规则,然后返回 return state.name + '是我表哥' } } // mutations操作工,专门用于修改state里的属性的方法集合,只能同步 const mutations = { setName (state, payload) { state.name = payload } } // actions操作工,用于修改state里的属性的方法集合,可以异步 const actions = { setName (context, payload) { // 这里进行异步操作,最后还是调用了mutations中的方法 context.commit('setName', payload) } } // 导出 export default new Vuex.Store({ state: state, mutations: mutations, getters: getters, actions: actions // 如果参数名相同,可以简写 state, getters, mutations, actions })
注意,注意,注意,这里参数,vuex已经规定好了,只能是state,getters,mutations,actions。
最后,别忘了在main.js入口文件中导入该文件。
import Vue from 'vue' import App from './App' import router from './router' // 在这里导入 import store from './store' import Vuex from 'vuex' Vue.use(Vuex) new Vue({ el: '#app', router, // 添加到vue实例 store, components: { App }, template: '<App/>' })
简单的说明了一下vuex,假设厂长是我表哥,我现在可以指挥这个工厂了。
state应用:
上面说过了,state里存放的是数据,要想获取数据,有两种办法。
第一种:厂长亲自来取数据,缺点是不能定义规则。
第二种:厂长叫getter搬运工去取,getter搬运工有定义规则的能力。
既然厂长是我表哥,那么就由我代劳了。
在任何组件中,我们都可以使用以下方式,获取state中的数据。
this.$store.state.name // 一般,我们会放在computed里。 computed: { showName () { return this.$store.state.name } }
以上内容可以发现,厂长可以直接来取数据,但缺点是无法过滤数据。
getter应用:
getter专门用来取数据的,并且我可以在里面定义各种各样的规则。
举例说明。
const state = { // 定义了一个数组,里面包含员工,和他对应的工资 data: [{ name: '牛二', salary: 3000 }, { name: '张三', salary: 3200 }, { name: '李四', salary: 3600 }, { name: '王麻子', salary: 3800 }] }
假设,厂长现在要给工资3500以下的人涨工资,那么我们就可以通过getter知道,有那些人的工资在3500以下。
const getters = { getName: function (state) { var people = [] for (var temp of state.count) { if (temp.salary < 3500) { people.push(temp) } } return people } } export default new Vuex.Store({ state, getters })
在任何组件中,我们都可以使用以下方式,通过getter获取state中的数据。
this.$store.getters.getName
当然,也可以放在computed里封印起来。
computed: { showName () { return this.$store.getters.getName} }
这里要注意的是官方给出的说明,如下。
Vuex 允许我们在 store 中定义“getter”(可以认为是 store 的计算属性)。就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。
mutation应用:
mutation专门用来更新数据的。
最重要的是:mutation是同步的,同步的,同步的。
官方给出的说明如下。
更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数。
举例说明。
const state = { name: '厂长' } const mutations = { // 在这里进行更改 setName (state) { state.name += '是我表哥' } } export default new Vuex.Store({ state, mutations })
既然mutation被当做事件,那么就不能称之为调用了,在vuex中,通过以下方式,触发mutation。
store.commit('setName')
那么,也就是说,在任何组件里,都可以通过如下方式,使用mutation,一般将mutation封印在methods中。
this.$store.commit('xxx')
以上例子中,name的变更方式已经被固定死了,我希望按照我制定的方式变更。
vuex中有如下说明。
你可以向 store.commit 传入额外的参数,即 mutation 的 载荷(payload)
举例说明。
const state = { name: '厂长' } const mutations = { // 接收一个str参数,即mutation的载荷 setName (state, str) { state.name += str } } export default new Vuex.Store({ state, mutations })
触发方式不变,也就是多了个参数。
store.commit('setName', '是我表哥')
一般来说,这个载荷是一个对象,这样就可以把多个要使用的参数,传入其中。
action应用:
action和mutation同样是操作工,但是action还是要牛一些的。
action牛的地方在于,有些活儿他不干,他让mutation去干。
最重要的是,action可以异步,可以异步,可以异步。
官方有如下说明。
Action 类似于 mutation,不同在于:
Action 提交的是 mutation,而不是直接变更状态。
Action 可以包含任意异步操作。
比如,我现在让action去干活,他觉得活儿太简单了,就让action去干,结果就是他睡一觉起来,活儿干完了。
举例说明。
const actions = { setName (context, name) { // action自己去睡了一觉,让mutation去干活 setTimeout(() => { context.commit('setName', name) }, 5000) } }
action的调用,称之为分发,在vuex中,通过以下方式,分发action。
store.dispatch('setName', name)
在任何组件里,都可以通过如下方式,使用action,一般将action封印在methods中。
this.$store.dispatch('xxx')
这里要注意的是:
Action 函数接受一个与 store 实例具有相同方法和属性的 context 对象,我们可以通过这个 context 对象获取当前 store 实例的 state 和 getters,但是这个 context 对象,不是 store 实例本身,不是,不是,不是。
上图说明。
context对象:
store实例:
只是有点像,但是二者不一样。
module应用:
module的作用就是将state,getter,mutation,action拆分,这样就避免了所有代码混在一起的情况。
举例说明。
const moduleA = { state: { name: '模块A' }, mutations: {}, actions: {}, getters: {} } const moduleB = { state: { name: '模块B' }, mutations: {}, actions: {}, getters: {} } export default new Vuex.Store({ state: { name: '根节点' }, mutations: {}, actions: {}, getters: {}, modules: { a: moduleA, b: moduleB } })
这里要注意的是,模块内部的 mutation 和 getter,接收的第一个参数是模块的局部状态对象。
也就是说,模块内部的mutation和getter,用的是自己的仓库。
而action接收的还是一个和store实例相似的对象。
举例说明。
const moduleA = { namespaced: true, state: { name: '模块A' }, mutations: { myMutation: function ( // 如果在模块中定义则为模块的局部状态 state, // 载荷,可选 payload) { } }, actions: { myAction: function ( // context对象 { state, rootState, commit, dispatch, getters, rootGetters }, // 载荷,可选 payload) { } }, getters: { myGetter: function ( // 如果在模块中定义则为模块的局部状态 state, // 等同于 store.getters getters, // 等同于 store.state rootState, // 所有 getters rootGetters) { return state.data } } }
即使是分了模块,state,getter,mustation,action的使用方法还是一样。
// 使用state this.$store.state.name // 使用getter this.$store.getters.myGetter // 使用mutation this.$store.commit('myMutation', '哈哈哈') // 使用action this.$store.dispatch('myAction', '哈哈哈')
那么问题来了,如果模块A和模块B中的属性和方法重名,怎么办?
举例说明。
const moduleA = { state: { name: '模块A' }, mutations: { aaa: function (state) {} }, actions: { bbb: function (context) {} }, getters: { ccc: function (state) {} } } const moduleB = { state: { name: '模块B' }, mutations: { aaa: function (state) {} }, actions: { bbb: function (context) {} }, getters: { ccc: function (state) {} } }
快使用命名空间,哼哼哈嘿。
举例说明。
const moduleA = { namespaced: true, state: { name: '模块A' } } const moduleB = { namespaced: true, state: { name: '模块B' } } export default new Vuex.Store({ modules: { a: moduleA, b: moduleB } })
在上述例子中,我加了一个属性namespaced: true,表示使用命名空间,那么在使用state,getter,mustation,action时,就得加上命名空间。
// 使用state this.$store.state.a.name // 使用getter this.$store.getters['a/myGetter'] // 使用mutation this.$store.commit('a/myMutation', '哈哈哈') // 使用action this.$store.dispatch('a/myAction', '哈哈哈')
还有就是,module还可以嵌套,不过基本上都是大同小异,经常看猪跑,猪肉啥味儿也能猜到。
基本上,vuex的核心就这些,算是填了上次传值的坑了。
个人学习总结,欢迎批评指正
- vuex state mutation action 之间关系,axios 跨域代理请求问题
- IOS开发笔记-01按钮操作-05.IBAction&IBOutlet 06.加法计算器小结 07.关闭键盘
- vuex的 module 除了state其他的都合并
- Vue-高级讲师之笔记06
- vuex--学习笔记(二)在组件中如何获取vuex的state对象中的属性
- vue视频学习笔记06
- SPRING IN ACTION 第4版笔记-第八章Advanced Spring MVC-002-SpringFlow的组件(state\<transition>\<var>\<set>\<evaluate>)
- Struts2 学习笔记 —— 06 —— ActionWildCard 通配符
- Vuex的Action学习
- 【Spring】【笔记】《Spring In Action》第3章 简化XML配置
- MySQL-python模块导入笔记06
- 学习笔记:vue(代码篇)
- Vue学习笔记10——demo地址
- IllegalStateException: Can not perform this action after onSaveInstanceState的解决方法
- Android StateMachine 学习笔记
- Vue.js学习笔记-1-组件
- oracle编程入门笔记2015-01-06--基本概念
- React Native 学习笔记四(关于state的使用)
- opencv2笔记06-主成分分析(PCA)
- 论文笔记之 SST: Single-Stream Temporal Action Proposals