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
- 包含多个计算属性(get)的对象
- 谁来读取: 组件中: $store.getters.xxx
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