vuex

145 阅读2分钟

vuex是什么

  • Vuex是Vue.js的状态管理模式。
  • 简单来说: 是对 vue 应用中多个组件的共享状态进行集中式的管理(读/写)

状态自管理应用

  • state: 驱动应用的数据源
  • view: 以声明方式将 state 映射到视图
  • actions: 响应在 view 上的用户输入导致的状态变化(包含 n 个更新状态的方法)

多组件共享状态的问题

  • 多个视图依赖于同一状态
  • 来自不同视图的行为需要变更同一状态
  • 以前的解决办法
    • 将数据以及操作数据的行为都定义在父组件
    • 将数据以及操作数据的行为传递给需要的各个子组件(有可能需要多级传递)
  • vuex 就是用来解决这个问题的

使用Vuex

在src目录下新建store文件夹,在此文件夹下新建index.js

App.vue
<template>
  <div id="app">
    <p>click {{count}} times,count is {{evenOrOdd}}</p>
    <button @click="increment">+</button>
    <button @click="decrement">-</button>
    <button @click="incrementIfOdd">increment if odd</button>
    <button @click="incrementAsync">increment async</button>
  </div>
</template>

<script>
//辅助函数
import {mapState,mapGetters,mapActions} from "vuex"

export default {
  methods:{
    ...mapActions(['increment','decrement','incrementIfOdd','incrementAsync'])
  },
  computed:{
    //mapState(["count"])有返回值,相当于:
    //{count(){return this.$store.state['count']}}
    ...mapState(["count"]),
    //mapGetters(["evenOrOdd"])返回值,相当于:
    //{evenOrOdd(){return this.$store.getters['evenOrOdd']}}
    ...mapGetters(["evenOrOdd"])
  }
}
</script>
<style></style>
index.js
import Vue from "vue"
import Vuex from "vuex"

Vue.use(Vuex);

const state={
    count:0
}
const getters={
    evenOrOdd(state){//不需要调用,只需要读取属性值
        return state.count%2===0 ? "偶数" : "奇数";
    }
}
const mutations={
    //增加的mutation
    INCREMENT(state){
        state.count++
    },
    //减少的mutation
    DECREMENT(state){
        state.count--
    }
}
const actions={
    //增加的action
    increment({commit}){
        //提交增加的mutation
        commit("INCREMENT");
    },
    //减少的action
    decrement({commit}){
        //提交减少的mutation
        commit("DECREMENT");
    },
    //带条件的action
    incrementIfOdd({commit,state}){
        if(state.count%2===1 || state.count%2===-1){
            //提交增加的mutation
            commit("INCREMENT");
        }
    },
    //异步的action
    incrementAsync({commit}){
        //在action中直接可以执行异步代码
        setTimeout(() => {
            //提交增加的mutation
            commit("INCREMENT");
        }, 1000);
    }
}

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

在main.js中引入

main.js
import Vue from 'vue'
import App from './App'
import router from './router'
//导入store
import store from './store'
Vue.config.productionTip = false

//把store的实例注入给所有的组件对象,使其都有一个属性:$store
new Vue({
  el: '#app',
  router,
  store,
  components: { App },
  template: '<App/>'
})

state

  • vuex 管理的状态对象
  • 它应该是唯一的

mutations

  • 包含多个直接更新 state 的方法(回调函数)的对象
  • 谁来触发: action 中的 commit('mutation 名称')
  • 只能包含同步的代码, 不能写异步代码

actions

  • 包含多个事件回调函数的对象
  • 通过执行: commit()来触发 mutation 的调用, 间接更新 state
  • 谁来触发: 组件中: $store.dispatch('action 名称', data1)
  • 可以包含异步代码(定时器, ajax)

getters

modules

  • 包含多个 module
  • 一个 module 是一个 store 的配置对象
  • 与一个组件(包含有共享数据)对应

向外暴露 store 对象

export default new Vuex.Store({
state, mutations, actions, getters
})

组件中

映射 store

store 对象

  • 所有用 vuex 管理的组件中都多了一个属性$store,它就是一个 store 对象
  • 属性:
    • state: 注册的 state 对象
    • getters: 注册的 getters 对象
  • 方法:
    • dispatch(actionName, data): 分发调用 action