zoukankan      html  css  js  c++  java
  • vuex实例详解

    • vuex是一个专门为vue.js设计的集中式状态管理架构。状态?把它理解为在data中的属性需要共享给其他vue组件使用的部分。
    • 简单的说就是data需要共用的属性

    一、小demo

    • 已经用Vue脚手架工具构建好项目

    1、引入vuex

    1.安装vuex

    npm n install vuex --save

    • 注意:一定要加上--save,因为这个包我们在生产环境中要使用

    2.新建store文件夹(不是必须),并在文件夹下新建store.js,文件中引入我们的vue和vuex

    import Vue from 'vue';
    import Vuex from 'vuex'
    

    3.使用我们vuex,引入之后用Vue.use进行引用

    Vue.use(Vuex)

    2、demo

    • 我们这个小demo先声明一个state的count状态,在页面中使用显示这个count,然后可以利用按钮进行加减

    1.在store.js文件里增加一个常量对象。

    const state = {
        count:3
    }
    

    2.用export default封装代码,让外部可以引用

    export default new Vuex.Store({
    	state
    })
    

    3.在src/components下新建count.vue

    • 在模板中我们引入我们刚建的store.js文件,并在模板中用{{$store.state.count}}输出count 的值。

       <template>
           <div>
               <h2>{{msg}}</h2>
               <h4>{{$store.state.count}}</h4><hr>
           </div>
       </template>
       <script>
       import store from '@/store/store.js'
       export default {
           data(){
               return {
                   msg: 'Hello Vuex!'
               }
           },
           store
       }
       </script>
      

    4.在store.js文件中加入两个改变state的方法

    • src/store/store.js

        const mutations = {
            add(state){
                state.count++;
            },
            reduce(state){
                state.count--;
            }
        }
      
    • 这里的mutations是固定的写法,意思是改变的,我们要改变state的数值的方法,必须写在mutations里就可以了。

    5.在count.vue模板中加入两个按钮,并调用mutations中的方法

    <div>
        <button @click="$store.commit('add')">+</button>
        <button @click="$store.commit('reduce')">-</button>
    </div>
    
    • 这样进行预览就可以实现对vuex中的count进行加减了。

    二、state访问状态对象

    • const state,这个就是我们说的访问状态对象,它是我们SPA(单页应用程序)中的共享值。

    • count.vue页面中,这种写法看着就麻烦

        <h4>{{$store.state.count}}</h4><hr>
      
    • 简便写法

        <h4>{{count}}</h4>
      
    • 这样就好多了可是怎么实现呢???

    • 想要实现有三种方法

    1.通过computed的计算属性直接赋值

    • computed属性可以在输出前,对data中的值进行改变,利用这种特性把store.js中的state值赋值给我们模板中的data值

        computed:{
        	count(){
        		return this.$store.state.count;
        	}
        }
      

    2.通过mapState的对象来赋值

    • 1.用import引入mapState

        import { mapState } from 'vuex;
      
    • 2.在computed计算属性写

        computed:mapState{
        	count:state=>state.count
        }
      
    • 使用ES6的箭头函数来给count赋值

    • 3.通过mapState的数组来赋值

        computed:mapState(['count'])
      
    • 最简单的写法,在实际项目开发中经常这样使用

    三、Mutations修改状态

    1、$store.commit()

    • Vuex提供了commit方法来修改状态

        <button @click="$store.commit('add')">+</button>
        <button @click="$store.commit('reduce')">-</button>
      
    • store/store.js

        const mutations={
            add(state){
                state.count++;
            },
            reduce(state){
                state.count--;
            }
        }
      

    2、传值

    • add方法加上一个参数n

        const mutations={
            add(state,n){
                state.count+=n;
            },
            reduce(state){
                state.count--;
            }
        }
      
    • 在Count.vue里修改按钮的commit( )方法传递的参数,我们传递10,意思就是每次加10

        <div>
        	<button @click="$store.commit('add',10)">+</button>
        	<button @click="$store.commit('reduce')">-</button>
        </div>
      

    3、模板获取Mutations方法

    • $store.commit()这样的方法写起来麻烦
      例如:@click=”reduce” 就和没引用vuex插件一样。
    • 要达到这种写法,只需要简单的两部就可以了:
    1.在模板count.vue里用import引入我们的mapMutations
    import { mapState,mapMutations } from 'vuex';
    
    2.在模板的script标签里添加methods属性,并加入mapMutations
     methods:mapMutations([
            'add','reduce'
    ])
    
    • 通过上边两部,我们已经可以在模板中直接使用我们的reduce或者add方法

        <div>
            <button @click="add(5)">+</button>
            <button @click="reduce">-</button>
        </div>
      

    四、getters计算过滤操作

    • getters从表面是获取的意思,可以把他看作在获取数据之前进行的一种在编辑,相当于对数据的一个过滤和加工。你可以把它看作store.js的计算属性

    1、getters基本用法

    • 比如我们现在要对store.js文件中的count进行一个计算属性的操作,就是在它输出前,给它加上10

    • 我们首先要在store.js里用const声明我们的getters属性。

        const getters = {
            count(state) {
                return state.count+=10;
            }
        }
      
    • 写好了gettters之后,我们还需要在Vuex.Store()里引入

        export default new Vuex.Store({
            state,
            mutations,
            getters
        })
      
    • count.vue

        computed:{
            ...mapState(["count"]),
            count(){
                return this.$store.getters.count;
            }
        }
      

    2 用mapGetters简化模板写法

    • 首先用import引入我们的mapGetters

        import { mapState,mapMutations,mapGetters } from 'vuex'
      
    • 在computed属性中加入mapGetters

         computed:{
                ...mapState(['count']),
                ...mapGetters(['count'])
        }
      

    五、actions异步修改状态

    • actions和之前讲的Mutations功能基本一样,不同点是,actions是异步的改变state状态,而Mutations是同步改变状态。

    1、在store.js中声明actions

    • actions是可以调用Mutations里的方法,在actions里调用add和reduce两个方法

        const actions = {
            addAction(context){
                context.commit('add',10)
            },
            reduceAction({commit}){
                commit('reduce')
            }
        }
      
    • 在actions里写了两个方法addAction和reduceAction,两个方法传递的参数不一样

    • context:上下文对象,这里你可以理解称store本身。

    • {commit}:直接把commit对象传递过来,可以让方法体逻辑和代码更清晰明了

    2、模板中的使用

    <div>
         <button @click="addAction">addAction+</button>
         <button @click="reduceAction">reduceAction-</button>
    </div>
    
    • import引入mapActions

        import { mapState,mapMutations,mapGetters,mapActions } from 'vuex'
      
    • methods方法

           methods:{
                ...mapMutations(['add','reduce']),
                ...mapActions(['addAction','reduceAction'])
            }
      

    3、增加异步体验

    • 我们现在看的效果和我们用Mutations作的一模一样,肯定有的小伙伴会好奇,那actions有什么用,我们为了演示actions的异步功能,我们增加一个计时器(setTimeOut)延迟执行。在addAction里使用setTimeOut进行延迟执行。

        const actions = {
            addAction(context){
                context.commit('add',10)
                setTimeout(()=>{
                    context.commit('reduce')
                },3000)
                console.log('我比reduce提前执行')
            },
            reduceAction({commit}){
                commit('reduce')
            }
        }
      

    count.vue

    <template>
        <div>
            <h2>{{msg}}</h2>
            <h4>{{count}}</h4><hr>
            <div>
                <button @click="add(10)">+</button>
                <button @click="reduce">-</button>
            </div>
            <hr>
             <div>
                <button @click="addAction">addAction+</button>
                <button @click="reduceAction">reduceAction-</button>
            </div>
        </div>
    </template>
    <script>
    import store from '@/store/store.js'
    import { mapState,mapMutations,mapGetters,mapActions } from 'vuex'
    export default {
        data(){
            return {
                msg: 'Hello Vuex!'
            }
        },
        // computed:{//方法1
        //     count(){
        //         return this.$store.state.count;
        //     }
        // },
        // computed:mapState({//方法2
        //     count:state => state.count
        // })
        computed:{
            ...mapState(['count']),//方法3
        //     count(){
        //         return this.$store.getters.count;
        //     }
            // ...mapGetters(['count']) //简写
    
        }
        ,
        methods:{
            ...mapMutations(['add','reduce']),
            ...mapActions(['addAction','reduceAction'])
        }
        ,store
    }
    </script>
    

    store.js

    import Vue from 'vue';
    import Vuex from 'vuex'
    Vue.use(Vuex);
    
    const state = {
        count:3
    }
    const mutations = {
        add(state,n){
            state.count+=n;
        },
        reduce(state){
            state.count--;
        }
    }
    const getters = {
        count(state) {
            return state.count+=10;
        }
    }
    
    const actions = {
        addAction(context){
            context.commit('add',10)
            setTimeout(()=>{
                context.commit('reduce')
            },3000)
            console.log('我比reduce提前执行')
        },
        reduceAction({commit}){
            commit('reduce')
        }
    }
    export default new Vuex.Store({
        state,
        mutations,
        getters,
        actions
    })
    

    六、module模块组

    • 随着项目的复杂性增加,我们共享的状态越来越多,这时候我们就需要把我们状态的各种操作进行一个分组,分组后再进行按组编写。
    • module:状态管理器的模块组操作
    • 项目不是很大,一般不用

    1、声明模块组

    • store.js

        const moduleA={
            state,mutations,getters,actions
        }
      
    • 修改原来 Vuex.Stroe里的值:

        export default new Vuex.Store({
            modules:{a:moduleA}
        })
      

    2、在模板中使用

    	<h3>{{$store.state.a.count}}</h3>
    
    • 简写

        <h3>{{count}}</h3>
      

    ``

    	computed:{
    	    count(){
    	        return this.$store.state.a.count;
    	    }
    	},
  • 相关阅读:
    建立自己的影响力
    在病房垒代码
    知乎确实不错
    不在乎你用到了什么技术,而在于你提供了哪些有价值的东西
    oschina上有不少好的项目
    我为何坚守Java?
    掌握了学习方法才能学到更多知识
    Jrebel实现Jetty 热部署
    互联网到底能干什么?我们还能干些什么?
    centos 阿里云 安装VNC Viewer
  • 原文地址:https://www.cnblogs.com/DCL1314/p/9530271.html
Copyright © 2011-2022 走看看