Vuex是一个专为vue.js应用程序开发的状态管理模式。他采用集中式存储来管理应用程序中所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。Vuex也集成到了vue的官网调试工具vue-devtools中,提供了诸如零配置的time-travel调试、状态快照导入导出等高级调试功能
getter
vuex允许我们在store中定义gettrs(可以认为是store计算属性)与计算属性一样,getter的返回值根据他的依赖项被缓存起来,且只有在他的依赖项发生改变时才会重新计算
getter接收state作为第一参数,代码如下:
const store = new Vuex.Store({ state: { books: [ { id: 1, title: 'vue.js', isSold: false }, { id: 2, title: 'vue.js2', isSold: true }, { id: 3, title: 'vue.js3', isSold: true } ] }, getters: { sellingBooks: state => state.books.forEach(book => book.isSold === true) } })
getter也可以接收其他getter作为第二参数,代码如下:
getters: { sellingBooks: state => state.books.forEach(book => book.isSold === true), sellingBooksCount:(state,getters)=>{ return getters.sellingBooks.length } }
在组件内要注意作为属性访问的getter作为Vue的响应式系统的统一部分被缓存。
如果想简化上述getter在计算属性中的访问形式,可以使用mapGetters辅助函数,这个辅助函数的用法和mapMutations、mapState类型,使用对象展开运算符将getter混入computed中,传递数组作为参数,代码如下:
computed:{ ...mapGetters([ 'sellingBooss', 'sellingBoossCount' ]) }
getter还有更灵活的用法,通过让getter返回一个函数,来实现给getter传参,代码如下:
getters:{ getBookById:function(state){ return function(id){ return state.books.find(book=>book.id===id) } } }
action
在定义mutaion时,有一条重用的原则就是mutation必须是同步函数,。。在mutation处理器函数中,不能存在异步调用。例如下面代码:
const store = new Vuex.Store({ state: { count:0 }, mutations:{ increment(state){ setTimeout(()=>{ state.count++ },2000) } }
在increment函数中调用setTimeout()方法在2s后更新count,这就是一个异步调用,不要这么做,因为这会让调试变得困难
确实需要执行异步操作的话那么应该使用action。action类似于mutasion,不同之处在于:
- action提交的是mutation,而不是直接变更状态
- action可以包含任意异步操作
一个简单的action如下所示:
const store = new Vuex.Store({ state: { count:0 }, mutations:{ increment(state){ state.count++ } }, actions:{ increment(context){ context.commit('increment') } } })
action处理函数接收一个与store实例具有相同方法和属性的context对象,因此可以利用该对象调用commit方法来提交mutation,或者通过context.state和context.getters来访问state和getter,甚至可以用context.dispatch调用其他的action,要注意的是,context对象并不是store实例本身