Vuex ~ 专门为vue.js设计的集中式状态管理架构

Posted £AP︶ㄣOL◢◤LO

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vuex ~ 专门为vue.js设计的集中式状态管理架构相关的知识,希望对你有一定的参考价值。

状态:data中的属性需要共享给其他vue组件使用的部分(即data中需要共用的属性)
 
1、初识vuex直接来个小demo
  下面操作都是基于vue-cli,如果不了解先学习下vue-cli
  利用npm包管理工具,进行安装 vuex。
    npm install vuex --save
  新建一个vuex文件夹(这个不是必须的),并在文件夹下新建store.js文件,文件中引入我们的vue和vuex。
    import Vue from ‘vue‘;
    import Vuex from ‘vuex‘;
    使用我们vuex,引入之后用Vue.use进行引用。
    Vue.use(Vuex);
  通过以上操作,vuex就算引用成功了
  
  直接来个demo,在vue-cli的src目录下新建一个文件夹vuex,并在此文件夹下新建一个store.js文件;直接上demo
  
现在我们store.js文件里增加一个常量对象
        const state={
            count:1
        }
    
    用export default 封装代码,让外部可以引用。
        export default new Vuex.Store({
            state
        })
    
    新建一个vue的模板,xxx.vue。在模板中我们引入我们刚建的store.js文件,
    并在模板中用{{$store.state.count}}输出count 的值。
        <template>
            <div>
                <h2>{{msg}}</h2>
                <hr/>
                <h3>{{$store.state.count}}</h3>
            </div>
        </template>
        <script>
            import store from ‘@/vuex/store‘
            export default{
                data(){
                    return{
                        msg:‘Hello Vuex‘
                    }
                },
                store   //注意要先引用下
            }
        </script>
    在store.js文件中加入两个改变state的方法。

        const mutations={
            //改变state的数值
            add(state){
                state.count++;
            },
            reduce(state){
                state.count--;
            }
        }
        export default new Vuex.Store({
            state,
            mutations
        })

    
    在xxx.vue模板中加入两个按钮,并调用mutations中的方法
        <div>
            <button @click="$store.commit(‘add‘)">+</button>
            <button @click="$store.commit(‘reduce‘)">-</button>
        </div>
    这样进行预览就可以实现对vuex中的count进行加减了
 
2.state访问状态对象
上面例子中 const state ,就是访问状态对象,也就是兄弟组件间的共享值。
    下面是状态对象赋值给内部对象,也就是把stroe.js中的值,赋值给我们模板里data中的值

    三种赋值方式:
        一、通过computed的计算属性直接赋值
            computed:{
                count(){
                    return this.$store.state.count;
                }
            }
            模板调用:{{count}}

            缺点:当一个组件需要获取多个状态时候,将这些状态都声明为计算属性会有些重复和冗余。
        
        二、通过mapState的《对象》来赋值
            import {mapState} from ‘vuex‘;
            然后还在computed计算属性里写如下代码:
                computed:mapState({
                    count:state=>state.count
                })

        三、通过mapState的《数组》来赋值
            computed:mapState(["count"])

 

3.Mutations修改state状态

1. mutations  相当于一个对象,对象里面放的是事件类型相对应的回调函数,作用就是进行状态更改;简单理解就相当于一个事件注册

    2. $store.commit()  //模板中调用mutations 里面的事件函数

    传值:只需要在Mutations里再加上一个参数,并在commit的时候传递就就可以了
        const mutations={
            add(state,n){
                state.count+=n;
            },
            reduce(state){
                state.count--;
            }
        }

        在XXX.vue里修改按钮的commit( )方法传递的参数,我们传递10,意思就是每次加10.
            <p>
                <button @click="$store.commit(‘add‘,10)">+</button>
                <button @click="$store.commit(‘reduce‘)">-</button>
            </p>
    
    
    模板获取Mutations方法
        实际开发中我们也不喜欢看到$store.commit( )这样的方法出现,我们希望跟调用模板里的方法一样调用。
        例如:@click=”reduce”   就和没引用vuex插件一样。
        要达到这种写法,只需要简单的两部就可以了:

        在模板XXX.vue里用import 引入我们的mapMutations:
            1.在模板XXX.vue里用import 引入我们的mapMutations:
                import { mapState,mapMutations } from ‘vuex‘;

            2.在模板的script标签里添加methods属性,并加入mapMutations
                methods:mapMutations([
                    ‘add‘,‘reduce‘
                ]),

            3.通过上面两步后调用(注意额外参数直接写上)
                <button @click="add(10)">+</button>

 

4.getters计算过滤操作

getters从表面是获得的意思,可以把他看作在《 获取数据之前 》进行的一种再编辑(注意模板显示getters操作后的值)
    相当于对数据的一个过滤和加工,可以把它看作store.js的计算属性(类似于computed)
    getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算

    《1》基本用法:
        首先要在store.js里用const声明我们的getters属性。
            const getters = {
                count:function(state,getters){
                    return state.count +=getters.params_getter;
                },
                params_getter:function(){
                    return 1000
                }
            }
            参数:
                state : 
                getters : getters.xxx 来传递其他 getters 中的数据

        写好了gettters之后,我们还需要在Vuex.Store()里引入
            export default new Vuex.Store({
                state,mutations,getters
            })
        
        在store.js里的配置算是完成了,我们需要到模板页对computed进行配置
        在vue 的构造器里边只能有一个computed属性,如果你写多个,只有最后一个computed属性可用,
        所以要对computed属性进行一个改造。
        改造时我们使用ES6中的展开运算符”…”。
            computed:{
                ...mapState(["count"]), //相当于一个扩展
                count(){
                    return this.$store.getters.count;
                }
            }
        
    《2》用mapGetters简化模板写法:
        都知道state和mutations都有map的引用方法把我们模板中的编码进行简化,我们的getters也是有的
        首先用import引入我们的mapGetters
            import { mapState,mapMutations,mapGetters } from ‘vuex‘;
        在computed属性中加入mapGetters
            ...mapGetters(["count"])

 

5.actions异步修改状态

actions和之前讲的Mutations功能基本一样
    不同点是,
        1.actions 提交的是 mutation,而不是直接变更状态。
        2.actions是异步的改变state状态,而Mutations是同步改变状态。

    在store.js中声明actions
        actions是可以调用Mutations里的方法的,在actions里调用add和reduce两个方法
        以下是事件注册的两种方式:
            const actions ={
                addAction(context){
                    context.commit(‘add‘,10)
                },
                reduceAction({commit}){
                    //由于context 与 store 实例具有相同方法和属性,所以可以提交mutation
                    commit(‘reduce‘)
                }
            }
        
        在actions里写了两个方法addAction和reduceAction,在方法体里,我们都用commit调用了Mutations里边的方法。
            context:上下文对象,这里你可以理解称store实例本身。
            {commit}:直接把commit对象传递过来,可以让方法体逻辑和代码更清晰明了。
        
        
        模板中的使用
            <p>
                <button @click="addAction">+</button>
                <button @click="reduceAction">-</button>
            </p>
            改造一下我们的methods方法,首先还是用扩展运算符把mapMutations和mapActions加入
            methods:{
                ...mapMutations([  
                    ‘add‘,‘reduce‘
                ]),
                ...mapActions([‘addAction‘,‘reduceAction‘])
            }
        
            用import把我们的mapActions引入才可以使用
                import { mapState,mapMutations,mapGetters,mapActions } from ‘vuex‘;
        
        增加异步检验
            演示actions的异步功能,我们增加一个计时器(setTimeOut)延迟执行
                setTimeOut(()=>{context.commit(reduce)},3000);
                console.log(‘我比reduce提前执行‘);

 

6.module模块组(状态管理器的模块组操作)

随着项目的复杂性增加,我们共享的状态越来越多,这时候我们就需要把我们状态的各种操作进行一个分组,分组后再进行按组编写。
    声明模块组:
        在vuex/store.js中声明模块组,我们还是用我们的const常量的方法声明模块组。代码如下:
            const moduleA = {
                state: { ... },
                mutations: { ... },
                actions: { ... },
                getters: { ... }
            }
            const moduleB = {
                state: { ... },
                mutations: { ... },
                actions: { ... }
            }
        声明好后,我们需要修改原来 Vuex.Stroe里的值:
            const store = new Vuex.Store({
                modules: {
                    a: moduleA,
                    b: moduleB
                }
            })
        
        store.state.a // -> moduleA 的状态
        store.state.b // -> moduleB 的状态
    
    在模板中使用:
        现在我们要在模板中使用count状态,要用插值的形式写入
            <h3>{{$store.state.a.count}}</h3>
        如果想用简单的方法引入,还是要在我们的计算属性中rutrun我们的状态。写法如下:
            computed:{
                count(){
                    return this.$store.state.a.count;
                }
            }

  

 
    
    
    
 

以上是关于Vuex ~ 专门为vue.js设计的集中式状态管理架构的主要内容,如果未能解决你的问题,请参考以下文章

Vuex教程

初识Vuex

最详细的Vuex教程

vuex的学习笔记

详细的Vuex教程

Vuex入门详细教程