WEB前端

vue状态管理之vuex

2019-03-28  本文已影响0人  马建文

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

  1. vuex的状态存储是响应式的:store中的状态发生变化响应的组件也会发生变化。
  2. 不能直接改变store中的状态:只能通过commit mutation 改变。
vuex的使用
  1. 安装
    npm install vuex --save
  2. 使用:确保全局下载过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,
  render: 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来分割成模块,方便管理与维护
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 的状态
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的使用区别
上一篇 下一篇

猜你喜欢

热点阅读