9.Vue组件之状态管理Vuex(2018.01.17)

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
} )

4).Action:
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 将会成为自然而然的选择。








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值