vuex浅析

官方说明:Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
如果您不打算开发大型单页应用,使用 Vuex 可能是繁琐冗余的。确实是如此——如果您的应用够简单,您最好不要使用 Vuex。一个简单的 global event bus 就足够您所需了。但是,如果您需要构建是一个中大型单页应用,您很可能会考虑如何更好地在组件外部管理状态,Vuex 将会成为自然而然的选择。

显然现在不是讨论用不用vuex的时候,直接进入主题。

在vue.js组件传值中介绍了父子组件之间的传值,使用vuex可以解决一般性的组件之间数据共享,即没有关联的两个组件之间也可以共享组件。

1.全局注册vuex
这里写图片描述
在新建src/store/index.js(个人文件结构习惯,仅供从参考),代码:

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  //...
})

现在有vuex实例,那么如何去使用它呢?
在vue的入口main.js中全局注册我们刚刚新建的vuex,main.js中添加代码:

import store from './store'
new Vue({
  // ...  
  store
})

这样在所有的组件中都可以通过this.$store访问vuex实例。

2.state
vuex中所有的状态都在state中,有点想vue中的data。修改上面的示例,在修改src/store/index.js:

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    count:0,
    todoList:[
      {id: 1,text: 'homework',finish:true},
      {id: 1,text: 'run',finish:false}
    ]
  }
})

那么各个组件可以通过this.$store.state.count访问vuex实例中的count,如在组件vueA.vue中:

<p>init count  =  {{count}}p>
computed: {
      count () {
          return this.$store.state.count
      }
  }

这样只要vuex中的count有修改,vueA中的count也会修改。

3.getter
有时候我们需要从 store 中的 state 中派生出一些状态,如

  • 未支付/未发货:待付款
  • 未支付/已发货:货到付款
  • 已支付/未发货:代发货
  • 已支付/已发货:待收货

在实际应用中可以会有一些组合状态,但是在各个组件中,不能在各个组件中通过运算获取这些组件状态,因为这样可能导致各个组件之间状态不一致,并且维护起来不方便,对于这种组合状态,可以在vuex中统一运算,通过getter暴露给各个组件,保持组件的状态一致,也方便维护。

举一个简单的栗子:
对于上例中的todoList,vuex提供一个获取已经完成list的方法,即总是给出finish == true的todolist:

getters: {
    doneList (state){
      return state.todoList.filter(item => item.finish)
    }
  }

各个组件获取doneList :

computed: {    
    doneList () {
      return this.$store.getters.doneList
    }    
  }

这样组件只负责获取vuex中的状态,而状态的逻辑由vuex控制。

4.mutations
更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。
这句话的意思是组件可以通过this.$store.state.count访问vuex中的状态,但是这是只读的,不能通过简单的赋值改变vuex中的状态,这样做的好处在于无法简单改变vuex的状态,必须要显示的提交修改,便于掌握数据的流向。
假设我们现在需要使上例中的count加1,通过上面的说明,this.$store.state.count++是不会起作用的。

那么如何实现count加1?添加src/store/index.js代码:

mutations: {
    addCount (state) {
      state.count++
    },
    minCount (state) {
      state.count--
    }
  }

在mutations中定义了addCount 和minCount ,通过代码看到分别实现了count加一和减一,在组件中调用方法如下:

<button @click="add()">+1button>
methods: {
      add () {
          this.$store.commit('addCount')
      }
  }

通过this.$store.commit(‘addCount’)调用vuex的mutations中的addCount。
如果希望传递其他的参数:

mutations: {
    addCount (state,para) {
      state.count++
    }    
  }
this.$store.commit('addCount',para)

mutations中的方法第一个参数为state,传递过去的参数依次往后。

5.action
官方说明:action 类似于 mutation,不同在于:

  • Action 提交的是 mutation,而不是直接变更状态。
  • Action 可以包含任意异步操作。

    示例:

  actions: {
    addCount (context) {
      setTimeout(() => {
        context.commit('addCount')
      },1000)
    }
  }

组件中访问:

this.$store.dispatch('addCount')

可以看到通过dispatch关键字访问action中的方法,而在action中需要改变vuex中的状态,仍然需要显示调用commit。

6.modules
为了解决臃肿问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter。

详情见官网https://vuex.vuejs.org/zh-cn/modules.html

7.map…
关键字state、getters、mutations、actions都有对应的map关键字,分别为mapState 、mapGetters 、mapMutations、mapActions
他们的主要作用是映射。
对于mapState、mapGetters 主要用于组件的computed中:

computed: {
  localComputed () { /* ... */ },
  // 使用对象展开运算符将此对象混入到外部对象中
  ...mapState({
    // ...
  })
}

主要作用是使代码更加简洁,对比两种写法:

count () {
          return this.$store.state.count
      }
 ...mapState ({ 
      count:'count'
    })

这样假如有大量的状态,使用mapState只需要做映射,而第一种写法每次都要return this.$store.state.count

其他的map系列都是同样的作用,不一一细讲。
代码地址:https://github.com/Demon-han/vuex-demo/

你可能感兴趣的:(前端,vue-js,vuex)