![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/743c039baf069bf9d7d81ac2c063b307.png)
基本使用
- src下新建store文件夹 – >> index.js
- main.js中import引入store,挂载到vue实例
一、State -->store中的状态(数据)
vuex 中存在 单一数据源的概念,每个app应用都只存在一个store实 例。Vuex中的store实例注册到vue实例中以后,app下任意组件可通过
this.$store.state
进行访问到store的状态,this.$store.getters
获取store的计算属性。
在.vue组件中如何拿到state中的数据(getters和state)呢?
主要有两种方式:
-
组件中直接取:代码不美观
-
通过computed去取:简化代码
-
通过官方提供的mapState和mapGetters进一步简化
这里值得注意的是计算属性中map函数中的变量名要和index.js中mutation保持一致,…扩展运算符的应用使得在computed中也可以书写本地的计算属性。
二、Getters
Getters相当于store的计算属性,只有当依赖的状态发生变化,其值才会被重新计算,否则值会被缓存起来。
- Getters中默认接受state,也可以接受其他的Getters(暴露)进行合并计算。
三、Mutation–>(变更状态)
提交mutation是变更状态的唯一方式(直接)
而提交mutation又含有2种方式:
1.组件内部通过事件直接commit提交,
2.组件内通过(事件)dispatch触发action,提交mutation,间接变更状态
这里我看仍以计数器counter为例,click点击增加,减少按钮,counter++/–;
试想一下:如果希望每次点击增加/减少2?或许可以这样
increase:state => state.counter += 2,
进一步想这样并不够灵活,我们可以根据传入的值进行有规律的增加或减少!
注意:这里的payload(载荷:附带的参数):根据需要决定传不传,可以是一个数字,一个字符串,对象(多个参数).
补充:
-
Mutation必须是同步函数
如果进行异步操作,带来的问题是进行状态无法追踪,调试困难。 -
Vuex中的state也遵循响应式系统的规定
Store中state的所需的property必须事先初始化好
Vue.set(obj, ‘newProp’, 123)或者新对象替换老对象将state加入响应式系统。
四、Actions
说明:**mutations必须是同步函数,直接变更状态,当我们需要进行异步操作时就不适用了,所以actions相当于一个附加的函数,可以在执行异步操作完成后
,再提交Mutaions,里面可以进行任意异步操作,比如调接口,异步拉取数据.
Actions主要用来提交mutations,它允许执行异步操作,再提交mutations,如果需要传递参数,可以提交载荷payload,它可以是一个字符串,数字这种单个参数;或者是对象这样可以传递多个参数,另外有异步操作,推荐都在actions里提交mutations,利用mapActions辅助函数即可,这里我们仍以计数器为例。
index.js
这里context与store基本相同,但有细微的差别
,这在modules会看到.
五、Modules模块
说明: 如果你的你的项目非常大,如果需要的对象都集中在在一个index.js里面,代码会变得不易管理。 Vuex允许我们将store分成模块module,这样便于管理,每个模块都有自己的state,getters,actions…,例如下面的例子。
什么时候需要分模块呢?比如博客项目中用户部分和博客部分,use.js,blog.js等等。这里以counter.js为例
在index.js入口文件利用modules选项进行配置(必须先引入)
import counter from './module/counter
值得注意的是这里state被限制在了counter这个模块下,组件若想访问到,必须使用(在计算属性中):this.$store.state.counter.counter
(这里模块名counter和state名重复)
但是只有state(局部模块限制)特殊,在组件中使用的时候,getters不论module中的getters,还是主文件中的module都是被store进行全局注入,可以通过this.$store.getters进行访问到,并且commit 和dispatch可以触发不论是index.js的mutation还是action,还是module中的都可以触发,mutaions和actions相当于注入到全局命名空间,但值得注意的是传入的参数都是局部的。
局部模块中getters默认传入state,getters(自身模块上的state和getters),其次可以接受第三个参数rootstate,可以访问根节点(index.js)中state.
局部模块中的action可以利用context.state,拿到局部状态,context.rootState拿到根文件(index.js)中的状态。
分割store
如果根文件index.js过大,可以进行拆分,根文件下创建actions.js,getters.js,mutations.js,这都是属于根文件,当然module局部模块也可以这样进行创建。
命名空间
**原因:**说明:getters,mutations,actions这些东西最终会共享同一个命名空间,必须保证变量名不能重复,为此出现了命名空间的问题.
**解决办法:**可以建立在store的根级别新建mutation-types.js,创建全局的命名空间的变量 ,保证变量名唯一。
在相应的js文件下引入,将getters,mutations,actions进行相应的替换即可。具体观看下面的截图
总结:这样操作起来,对于mutations,actions,getters进行变量名的替换,固然有些麻烦,但是对于大型应用,这样是非常有必要的,保障变量名的唯一。
六、目录结构
- 应用层级的状态应该集中到单个 store 对象中。
- 提交 mutation 是更改状态的唯一方法,并且这个过程是同步的。
- 异步逻辑都应该封装到 action 里面。
只要你遵守以上规则,如何组织代码随你便。如果你的 store 文件太大,只需将 action、mutation 和 getter 分割到单独的文件。对于大型应用,我们会希望把 Vuex 相关代码分割到模块中。下面这个是官方推荐。
七、Vuex总结
**说明:**vuex 的使用不是必须的,基于项目的大小来决定,Store是一个中央仓库,仓库的内容会被mutations改变,mutations必须是同步的,我们常常用actions进行来提交mutations,actions是由组件dispatch来触发的,始终用actions是很好的写法,即使mutations或任务不是异步的,但并不强制;我们可以在组件中直接提交Mutaions,中间不用actions也可以;当出现异步任务的时候,必须使用actions的,
actions自动会有一个上下文context,基本等同于这个中央仓库,但会有细微的差别。
store--》中央仓库
state--》状态
getters--》访问状态,对状态进一步修饰
mutations--》直接变更状态,可在组件中触发更改状态,或者由action间接触发。
actions--》可以先进行异步操作,在提交mutation
modules--》当项目过大,需要分模块管理时,可将store按模块进行拆分。