1.Vuex介绍:
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。简单地说,Vuex 就是管理组件之间数据通信的容器,此处的组件通信是 Vue 里面所有组件,而不仅仅包括父子组件之间的通信。
2.使用案例:
1).安装:
cnpm install --save vuex |
2).在
src 目录下新建
store
目录,然后再在
store 目录里面新建
index.js
,内容如下:
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
}
})
|
3).在
main.js
文件里面引入:
import store from './store' |
注:如果没写具体文件,引入的就是该目录下 index.js 或者 index.vue 文件。
4). 在
main.js
实例化 vue 时注入 vuex:
new Vue({
el: '#app',
store,
//所有子组件都将具有store的实例,子组件不再需要单独引入
components: { App },
template: '<App/>'
})
|
5).在需要使用状态管理的组件里面直接使用:
<template>
<div>
{{
msg
}} --
{{
mycount
}}
<button @click="
clickMe" >点击我</button>
</div>
</template>
<script>
export default {
name:"Hello",
data(){
return {
msg:'hello'
}
},
methods:{
clickMe
: function(){
this.$store.commit('
increment
');
//触发状态改变
this.msg =
this.$store.state.
count
;
//在方法里面获取改变之后的值
}
},
computed: {
//也可以在计算属性中返回状态,更简单
mycount
() {
return this.$store.state.
count
}
}
}
</script>
|
3.Vuex 和单纯的全局对象有以下两点不同:
1). Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。
2). 你不能直接改变 store 中的状态。改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。这样使得我们可以方便地跟踪每一个状态的变化,从而让我们能够实现一些工具帮助我们更好地了解我们的应用。
4.Vuex详解:
1).State:
Vuex 使用单一状态树,而 State 作为一个状态容器的唯一数据源而存在。请确保每个要使用的状态都在 state 里面得到初始化。
2).Getter:
getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。
案例:
①. 在
store/index.js
里面:
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
count: 0,
todos: [
{ id: 1, text: '...', done: true },
{ id: 2, text: '...', done: false }
]
},
mutations: {
increment (state) {
state.count++
}
},
getters: {
doneTodos
: state => {
return state.todos.filter(todo => todo.done)
}
}
})
|
②. 调用(Getter 会暴露为 this.$store.getters 对象):
<template>
<div>
{{ msg }} --{{ mycount }}
<span v-for="todo in todos">{{ todo }}</span>
<button @click="clickMe" >点击我</button>
</div>
</template>
<script>
export default {
name:"Hello",
data(){
return {
msg:'hello',
todos:[]
}
},
methods:{
clickMe : function(){
this.$store.commit('increment'); //触发状态改变
this.msg = this.$store.state.count; //在方法里面获取改变之后的值
this.todos
= this.$store.getters.
doneTodos
;
//在方法里面获取getters的值
}
},
computed: {
//也可以在计算属性中返回状态,更简单
mycount () {
return this.$store.state.count
}
}
}
</script>
<style scoped>
</style>
|
3).Mutation:
①. 更改 Vuex 中状态的唯一方法是提交 mutation。
你不能直接调用 mutation 里面的方法,必须使用this.$store.commit('mutation里的方法名');
②. mutation中可以传参数,一般是对象:
a.
在
store/index.js
里面:
mutations: {
increment
(state,
payload
) {
state.count += payload.amount
}
}
|
b.调用的时候:
this.$store.commit('
increment
',
{
amount: 10
}
)
|
mutation中只能包含同步操作,如果有异步操作必须放在Action 中。
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
count: 0,
},
mutations: {
increment (state) {
state.count++
}
},
actions: {
increment (
context
) {
context.commit('
increment
');
//转向调用mutation里面的increment方法
}
}
})
|
Action 通过 store.dispatch 方法触发:
this.$store.dispatch('increment'); //此处调用的是action里面的increment方法 |
注:Action 提交的是 mutation,而不是直接变更状态。Action 可以包含任意异步操作。
5). 总结:我们通过提交 mutation 的方式,而非直接改变 store.state.count,是因为我们想要更明确地追踪到状态的变化。这个简单的约定能够让你的意图更加明显,这样你在阅读代码的时候能更容易地解读应用内部的状态改变。
由于store中的状态是响应式的,在组件中调用 store 中的状态简单到仅需要在计算属性中返回即可。触发变化也仅仅是
在组件的 methods 中提交 mutation。流程为:
view ->(dispatch) Action ->(Commit) Mutations ->(Mutate) State -> View
注意:Action不是必需品,如果有异步操作才可能用到Action,否则可以不使用。
5.Vuex使用场景:
虽然 Vuex 可以帮助我们管理共享状态,但也附带了更多的概念和框架。这需要对短期和长期效益进行权衡。
如果您不打算开发大型单页应用,使用 Vuex 可能是繁琐冗余的。确实是如此——如果您的应用够简单,您最好不要使用 Vuex。一个简单的 global event bus 就足够您所需了。但是,如果您需要构建是一个中大型单页应用,您很可能会考虑如何更好地在组件外部管理状态,Vuex 将会成为自然而然的选择。