vuex

Vuex是什么及其核心概念

很简单来说,对vue应用中多个组件的共享状态进行集中式的管理(读/写)

State

  • vuex管理的状态对象
  • 他应该是唯一的
const state = {
    xxx: intValue,
}

Mutations

  • 包含多个直接更新state的方法(回调函数)的对象
  • 谁来触发?action中的 commit("mutations名称")来触发
  • 只能包含同步的代码,不能写异步代码(例如发送ajax请求就是异步的代码,不能在Mutations中写)
const mutations = {
    yyy(state, data) {
        // 更新state的某个属性
    },
}    

Action

  • 包含多个事件回调函数的对象
  • 通过执行:commit()来触发mutations的调用,间接更新state
  • 谁来触发?在组件中使用 $store.dispatch("Action的名称")来触发
  • 可能包含异步代码(如:定时器,ajax)
const action = {
    zzz({commit, state}, data1) {
        commit('yyy', data1);
    },
}

store对象

  1. 所有的vuex管理的组件中都会多出一个$store属性,它就是一个store对象
  2. store相关属性
    1. state:就是上面讲到的注册的state对象
    2. getters:注册的getters对象
  3. store相关方法
    1. dispatch(actionName, data):风阀调用action

映射store

去App.vue中映射

import Vue from "vue";
import store from "./store";   // 这里填写我们自定义的store.js文件

new Vue({
    store,     // 映射结果,所有的组件对象中都多了一个对象:$store
});

使用Vuex

安装

通过npm安装

npm install vuex --save

使用

暴露一个store

store.js:

/*
vuex的核心管理对象模块
 */
import Vue from "vue"
import Vuex from "vuex"

Vue.use(Vuex)

// 状态对象
const state = {
  count: 0,
};
// 包含多个更新state函数的对象
const mutations = {
  // 增加count
  inccount(state) {
    state.count++;
  },
  // 减少count
  deccount(state) {
    state.count--;
  },
};
// 包含多个对应事件回调函数的对象
const actions = {
  // 增加的action
  increment({commit}) {
    // 提交增加的mutation
    commit("inccount");
  },
  // 减少的action
  decrement({commit}) {
    commit("deccount");
  },
  // 奇数+1
  incrementIfOdd({commit, state}) {
    if(state.count % 2 === 1){
      commit("inccount");
    }
  },
  // 过一秒加1
  incrementAsync({commit}) {
    setTimeout(()=>{
      commit("inccount");
    }, 1000);
  },
};
// 包含多个getter计算属性的对象
const getters ={
  evenOrOdd(state) {
    return state.count % 2 === 0 ? '偶数' : '奇数';
  }
}

export default new Vuex.Store({
  state,       // 状态对象
  mutations,   // 包含多个更新state函数的对象
  actions,    // 包含多个对应事件回调函数的对象
  getters,    // 包含多个getter计算属性的对象
});

在main.js中映射store

映射之后每一个组件都会有一个$store对象

import Vue from "vue"
import App from "./App"
import store from "./store"

new Vue({
  el: '#app',
  components:{
    App,
  },
  template: "<App />",
  store,    // 映射store,映射的结果,所有的组件对象都多了一个对象:$store
});

在组件中使用vuex

<template>
  <div>
    <p>click {{ $store.state.count }} times,the count is {{ evenOrOdd }}</p>
    <button @click="increment">increment</button>
    <button @click="decrement">decrement</button>
    <button @click="incrementIfOdd">increment if Odd</button>
    <button @click="incrementAsync">increment asyn</button>
  </div>
</template>

<script>
  export default {
    computed: {
      evenOrOdd (){
        return this.$store.getters.evenOrOdd;
      }
    },
    methods: {
      // 加一
      increment (){
        // 通知vuex增加count
        this.$store.dispatch("increment");    // 触发对应的action调用
      },
      // 减一
      decrement (){
        this.$store.dispatch("decrement");
      },
      // 当前数字是奇数就加一
      incrementIfOdd (){
        this.$store.dispatch("incrementIfOdd");
      },
      // 过一秒加一
      incrementAsync (){
        this.$store.dispatch("incrementAsync");
      },
    },
  }
</script>

<style scoped>

</style>

简化

<template>
  <div>
    <p>click {{ count }} times,the count is {{ evenOrOdd }}</p>
    <button @click="increment">increment</button>
    <button @click="decrement">decrement</button>
    <button @click="incrementIfOdd">increment if Odd</button>
    <button @click="incrementAsync">increment asyn</button>
  </div>
</template>

<script>
  import {mapActions, mapState, mapGetters} from "vuex";

  export default {
    computed: {
      ...mapGetters(['evenOrOdd']),   // 返回一个对象{}: {evenOrOdd(){return this.$store.gettters['evenOrOdd']}}
      ...mapState(['count']),
    },
    methods: {
      ...mapActions(["increment", "decrement", "incrementIfOdd", "incrementAsync"]),
    },
  }
</script>

<style scoped>

</style>

 

posted @ 2018-11-19 20:37  Jin同学  阅读(125)  评论(0)    收藏  举报