重点看懂这张图:
重点记住:
1.Mutation 必须是同步函数,即mutations里只能处理同步操作。
2.如果处理的是同步操作可直接commit提交mutations更改state,如果是异步操作则需要通过actions提交mutations。
3.Action 提交的是 mutation,而不是直接变更状态。
4.Action 可以包含任意异步操作。
理解为什么要使用Vuex?
当我们的应用遇到多个组件共享状态时,单向数据流的简洁性很容易被破坏:
- 多个视图依赖于同一状态。
- 来自不同视图的行为需要变更同一状态。
- 对于问题一,传参的方法对于多层嵌套的组件将会非常繁琐,并且对于兄弟组件间的状态传递无能为力。
- 对于问题二,我们经常会采用父子组件直接引用或者通过事件来变更和同步状态的多份拷贝。以上的这些模式非常脆弱,通常会导致无法维护的代码。因此,我们为什么不把组件的共享状态抽取出来,以一个全局单例模式管理呢?在这种模式下,我们的组件树构成了一个巨大的“视图”,不管在树的哪个位置,任何组件都能获取状态或者触发行为!通过定义和隔离状态管理中的各种概念并通过强制规则维持视图和状态间的独立性,我们的代码将会变得更结构化且易维护。
使用案例:
建立如下目录结构,方便维护
state.js
export default {
count: 0,
firstName: 'Keyan',
lastName: 'Liu'
}
actions.js
export default {
increment(context, n) {
// setTimeout(() => {
// context.commit('increment', n)
// }, 1000)
context.commit('increment', n)
}
}
mutations.js
export default {
increment(state, payload) {
state.count += payload.amount
}
}
getters.js
export default {
fullName(state) {
return `${state.firstName} ${state.lastName}`
}
}
store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
import state from './state/state'
import mutations from './mutations/mutations'
import getters from './getters/getters'
import actions from './actions/actions'
Vue.use(Vuex)
export default new Vuex.Store({
state,
mutations,
getters,
actions
})
about.vue
<template>
<div class="about">
<h1>This is an about page</h1>
<span>{{ count }}</span>
<br>
<button @click="fun({amount: 11})">增加</button>
<br>
<span>{{ fullName }}</span>
<!-- <span>{{ countAlias }}</span> -->
</div>
</template>
<script>
import { mapState, mapMutations, mapActions, mapGetters } from 'vuex'
export default {
name: 'About',
beforeRouteEnter(to, from, next) {
console.log('----------before enter--------', this)
next(vm => {
console.log('after enter vm.id is:', vm.id)
})
},
beforeRouteUpdate(to, from, next) {
console.log('-----------upadte enter--------')
next()
},
beforeRouteLeave(to, from, next) {
console.log('------------leave enter----------')
if(global.confirm('are you sure?')) {
next()
}
},
props: ['id'],
mounted() {
console.log(this.id)
console.log(this.$route)
},
computed: {
...mapState([
'count',
]),
...mapGetters([
'fullName'
])
},
methods: {
...mapMutations({
fun: 'increment'
}),
...mapActions({
fun: 'increment'
})
}
}
</script>