vue状态管理之vuex

vuex和单纯的全局对象有两点不同:

  1. vuex的状态存储是响应式的:store中的状态发生变化响应的组件也会发生变化。
  2. 不能直接改变store中的状态:只能通过commit mutation 改变。
vuex的使用
  1. 安装

npm install vuex --save

  1. 使用:确保全局下载过Vue,并且引用,
    import vuex from 'vuex'
    Vue.use(vuex)
  1. 创建第一个store
   let store = new store({
       state:{
           count:0
       },
       mutation:{
           increment(state){
               state.count++
           }
       }
   })

4.在页面上显示数据,state(辅助函数mapState),mutation(辅助函数mapMutation),getters(辅助函数mapGetters)
第一步,创建store.js

    import Vue from 'vue'
   import vuex from 'vuex'
   Vue.use(vuex);

   let store  = new vuex.Store({
   state:{
   	count:0,
   	todos:[
   		{id:1,text:'第一条todo',done:true},
   		{id:2,text:'第二条todo',done:false},
   	]
   },
   getters:{
       todoDone(state){
           return state.todo.filter(todo =>todo.done)
       }
   },
   mutations:{
   	increment (state,payload) {
   		state.count += payload.amount
   	},
   	decrement(state,payload){
   	    state.count -= payload.amount
   	}
   },
   actions:{
   	increment(context,payload){
   		debugger
   		console.log(context,payload);
   		context.commit('increment',payload)
   	},
   	//还可以以解构赋值的方式来显示参数,直接拿到commit方法,不用context.commit
   	decrement({commit},payload){
   		commit('decrement',payload)
   	}
   }
   });


   export default store;

第二步,将store挂载到vue中,这样vue根实例及其每个子组件都可以直接使用store

    import store from './store.js'

    new Vue({
      el: '#app',
      store,
     ender: h => h(App)
    })

第三步,在App.vue文件中显示,并且加减数据。

    <template>
      <div id="app">
          {{$store.state.count}}-{{count1}}
          <!--这里两种方法都可以显示出来-->
            <button @click="submit">增加</button>
        <button @click="reduce">减少</button>
        <hr/>
        <ul>
            <li v-for='item in todo' :key="item.id">
              <span>{{item.id}}</span>
              <span>{{item.text}}</span>
              <span>{{item.done}}</span>
            </li>
       </ul>
      </div>
    </template>

    <script>
    import {mapState,mapGetters} from 'vuex'
    export default {
      name: 'app',
      data () {
        return {
         msg: 'Welcome to Your Vue.js App',     
        }
     },
      computed:{
        ...mapState({
          count1:'count'
        }),
        ...mapGetters({
            todo:'doneTodos'
       })
      },
      methods:{
        submit(){
          //写法1:可以直接数字10,然后store.js中直接加数字10就可以
         //写法2:可以传一个对象{amount:10},然后调用对象的amount就行。
          this.$store.commit('increment',{amount:10});
       },
        reduce(){
            this.$store.commit('decrement',{amount:10})
       },
       //actions第一种:不用辅助函数mapActions
        /*actionAdd(){
          //以载荷形式分发
          this.$store.dispatch('increment',{amount:10});
        },
        actionReduce(){
           //以对象形式分发
          this.$store.dispatch({
            type:'decrement',
            amount:20
          })
        },*/
        //actions第二种,使用辅助函数mapActions,重命名,调用的时候在template中的@click传参数
        ...mapActions({
          actionAdd : 'increment',
         actionReduce : 'decrement'
       }),
     }
    }
    </script>
  1. module使用方法:当store对象变得非常大,非常臃肿的时候,这时候可以使用modules来分割成模块,方便管理与维护
  • 第一种:直接在一个store.js文件中写入好几个对象,然后在modules中注册。
    const moduleA = {
      state: { ... },
      mutations: { ... },
      actions: { ... },
      getters: { ... }
    }

    const moduleB = {
      state: { ... },
      mutations: { ... },
      actions: { ... }
    }

    const store = new Vuex.Store({
      modules: {
       a: moduleA,
       b: moduleB
      }
    })

    store.state.a // -> moduleA 的状态
    store.state.b // -> moduleB 的状态
  • 第二种方法:没个模块可以写在一个js文件中,然后倒入到store.js中
    首先moduleA.js文件:
    export let moduleA = {
	state:{
		numA:10
	},
	mutations:{},
	actions:{},
	getters:{}
    }

其次moduleB.js文件中:

    let moduleB = {
	state:{
		numB:10
	},
	mutations:{},
	actions:{},
	getters:{}
    }

    export default moduleB;

然后在store.js中统一导入就可以使用了:

    import {moduleA as a}from './moduleA.js'
    import moduleB from './moduleB.js'
    console.log(a)

    let store  = new vuex.Store({
    ...
    modules:{
		a:a,
		b:moduleB
	}
    })
这里稍微简单总结一下:export和export default的使用区别
  • export 可以倒出一赋值语句,如:export let moduleA = {},但是在导入的时候变量名得用{}包起来,如:import {moduleA as a}from './moduleA.js',也可以重命名.
  • export default 一个对象的时候可以先定义对象let moduleB = {},然后export default moduleB;;或者 export default {}就行,然后导入的时候命名import moduleB from './moduleB.js'

posted on 2019-03-29 18:36  稀里糊涂学前端  阅读(310)  评论(0)    收藏  举报

导航