Vuex 是什么?
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。Vuex 也集成到 Vue 的官方调试工具 devtools extension,提供了诸如零配置的 time-travel 调试、状态快照导入导出等高级调试功能。
Vuex的核心
vuex由以下几部分组成:
- state
- mutations
- getters
- actions
- modules
state里面就是存放项目中需要多组件共享的状态
mutations就是存放更改state里状态的方法
getters就是从state中派生出状态,比如将state中的某个状态进行过滤然后获取新的状态。
actions就是mutation的加强版,它可以通过commit mutations中的方法来改变状态,最重要的是它可以进行异步操作。
modules顾名思义,就是当用这个容器来装这些状态还是显得混乱的时候,我们就可以把容器分成几块,把状态和管理规则分类来装。这和我们创建js模块是一个目的,让代码结构更清晰。
实例理解vuex
main.js
import Vue from 'vue'
import App from './App'
import router from './router'
import store from './store.js'
var vm = new Vue({
el: '#app',
router,
store,
template: '<App/>',
components: { App }
})
store.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex);
const state = { //数据存储
count:10,
};
const mutations = { //数据处理
increment(state) {
state.count++;
},
decrement(state) {
state.count--;
}
};
const actions = { //=处理你要怎么做,比如异步请求,判断,流程控制等commit讲请求提交到mutation里面
increment:({commit})=>{
commit('increment');
},
decrement:({commit})=>{
commit('decrement');
},
increDouble:({commit,state})=>{
if(state.count%2==0){
commit('increment');
}
},
decreOnly:({commit,state})=>{
if (state.count%2!=0) {
commit('decrement');
}
},
clickAnsy:({commit})=>{//可以通过promise异步获取数据
new Promise(function(resolve, reject) {
setTimeout(()=>{
commit('increment');
resolve();
},1000)
});
}
}
const getters={
nowNum(state){
return state.count;
},
getOdd(state) {
return state.count%2==0?'偶数':'奇数';
}
}
export default new Vuex.Store({
state,
mutations,
actions,
getters
});
App.Vue
<template>
<div id="app">
<h2>vue全局组件use使用</h2>
<h2>vuex的使用</h2>
<input type="button" value="增加" @click="increment"/>
<input type="button" value="减少" @click="decrement"/>
<input type="button" value="偶数时可点击+" @click="increDouble"/>
<input type="button" value="奇数时可点击-" @click="decreOnly"/>
<input type="button" value="异步处理" @click="clickAnsy"/>
<div>现在的数字为:{{nowNum}} 它现在是{{getOdd}}</div>
<button @click="test"> 1 </button>
</div>
</template>
<script>
import {mapActions,mapGetters} from 'vuex'
export default {
name: 'app',
computed:{
...mapGetters([
'nowNum',
'getOdd'
])
},
methods:{
...mapActions([
'increment',
'decrement',
'increDouble',
'decreOnly',
'clickAnsy'
]),
test(){
this.$store.dispatch('increment')
}
},
mounted:function () {
console.log(this.$store)
}
}
</script>
现在vuex内的定义已经完成,可以再组件内调用,获取了
获取state内值方法一:
computed: {
count () {
return this.$store.state.count
}
}
方法二 利用mapState 辅助函数
import { mapState } from 'vuex'
export default {
// ...
computed: mapState({
// 箭头函数可使代码更简练
count: state => state.count,
// 传字符串参数 'count' 等同于 `state => state.count`
countAlias: 'count',
// 为了能够使用 `this` 获取局部状态,必须使用常规函数
countPlusLocalState (state) {
return state.count + this.localCount
}
})
}
对象展开运算符
mapState函数返回的是一个对象。我们如何将它与局部计算属性混合使用呢?通常,我们需要使用一个工具函数将多个对象合并为一个,以使我们可以将最终对象传给 computed
属性。但是自从有了对象展开运算符(现处于 ECMASCript 提案 stage-3 阶段),我们可以极大地简化写法:
computed: {
localComputed () { /* ... */ },
// 使用对象展开运算符将此对象混入到外部对象中
...mapState({
// ...
})
}
Mutations
更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。Vuex 中的 mutations 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数:
你不能直接调用一个 mutation handler。这个选项更像是事件注册:“当触发一个类型为 increment 的 mutation 时,调用此函数。”要唤醒一个 mutation handler,你需要以相应的 type 调用 store.commit 方法:
store.commit('increment')
提交载荷(Payload)
你可以向 store.commit 传入额外的参数,即 mutation 的 载荷(payload):
mutations: {
increment (state, n) {
state.count += n
}
}
store.commit('increment', 10)
在组件中提交 Mutations
你可以在组件中使用 this.$store.commit('xxx') 提交 mutation,或者使用 mapMutations 辅助函数将组件中的 methods 映射为 store.commit 调用(需要在根节点注入 store)。
import { mapMutations } from 'vuex'
export default {
methods: {
...mapMutations([
'increment' // 映射 this.increment() 为 this.$store.commit('increment')
]),
...mapMutations({
add: 'increment' // 映射 this.add() 为 this.$store.commit('increment')
})
}
}
Actions
Action 类似于 mutation,不同在于:
- Action 提交的是 mutation,而不是直接变更状态。
- Action 可以包含任意异步操作。
组件内 可以通过Action 通过 store.dispatch 方法触发:
触发
Actions 支持同样的载荷方式和对象方式进行分发:
// 以载荷形式分发
store.dispatch('incrementAsync', {
amount: 10
})
// 以对象形式分发
store.dispatch({
type: 'incrementAsync',
amount: 10
})
vuex内的actions 会通过第二参数获取
const actions = {
increment:({commit} , test)=>{
commit('increment' ,test);
},
}
modules
通过modules 创建的vuex state 是分模块的,其他 mutations 和 actions 都不分模块 如果重复命名会调用两次 getters函数命名重复会报错
使用的时候 获取state值 使用 this.$store.(模块名)+字段名
调用actions mutations 同单store
注意分modules 的vuex 的模块只
export default {
state,
getters,
actions,
mutations
}
不实例化vuex