vuex浅析

来源:互联网 发布:新闻联播动画制作软件 编辑:程序博客网 时间:2024/05/20 00:17

官方说明: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()">+1</button>
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/

原创粉丝点击