vuex 主要服务于中大型的单页应用(比较小的就没必要了),是一个类似于 Flux 的一个数据管理框架,让我们的应用内的的状态保持在可维护、可理解的状态;
开始主题:
一 安装:
直接下载:https://unpkg.com/vuex (不推荐)
npm: npm install vuex
注意:由于vuex其内部用了很多ES6的语法,建议使用wabpack等工具自动转ES5,搭建项目。
考虑到很多同学多ES6还是不是很熟悉,本教程基本都是用ES5来说明
二 认识store
store是整个应用的状态的中心,但是区别于其他全部对象的是:1、store是响应式,就是会随着专题改变,而实时改变,而vue组件读取其中的状态也就可以被实时更新。2、store的状态并不能直接改变,必须通过提交更改(一个特定的函数),而改变。这也是保证了数据单项流动;
例子:
var store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment:function (state) { //改变store状态的方法
state.count++
}
}
})
store.commit('increment') //通过commit调用改变状态的increment方法
console.log(store.state.count) //1
三 state、getters、Mutations、actions简介
state: 类似是vue中的date,用户储存数据;
getters: 类似vue中的computed,计算属性;
mutations: 类似于vue中的methods,逻辑方法。注意:这里面的方法必须是同步的,因为这里的方法将直接修改state的状态,从而改变store的状态,如果是异步的话将无法控制state状态改变的先后顺序,使得整个store状态变的不可控。还有一点是 vue-devtools 这个工具是根据这个来记录改变的状态;
actions:实际分发 mutations 里面的方法。
整个逻辑可以看一下官方的一个经典图:
通过这张图我们可以看到这几点:
1.数据是单项,
2.actions是通过组件来调用的
3.devtools记录mutaions的状态
4.store的状态只有被muations改变
5.当store的状态被改变,组件也会变实时刷新
四 实战案例 (购物车)
首先是搭建项目:
我用的是vue的脚手架工具 vue-cli (npm安装:npm install --global vue-cli )
npm:vue init webpack vuex-demo
npm: npm install
npm: npm install vuex --save
最后经过修改的项目结构
主要增加store文件夹。
项目结构目录解释:
api:获取服务器的获取数据方法
store 下面的 index.js: store的根目录,保存项目所以状态(对模块和模块之间公共状态 组件)
store 下面的 modules: vuex由于状态都是基于stroe,但是顺着项目内容的增加,stroe就会变的非常臃肿,所以vuex允许我们把store分成几个modules,每个modules都是自己的state、getter、mutation、actions。
store 下面的 getter.js 和 actions.js :这两个主要是管理模块之间状态
注意:这我就详细讲一下:对于产品获取、展示的这个一个过程
首先获取产品:
首先要在product中保存产品,就需要在product中创建:
var state = {
all:[] //获取的商品
}
要改变state中的状态,只有通过mutations:
var mutations = {
receive_product:function(state,products){
state.all = products;
},
}
而调用muations中的方法,需要actions:
//调用获取产品的
import api_product from '../api/products.js'
//调用获取商品列表方法的action
var getAllProducts = function(context){
var commit = context.commit;
api_product.getProducts(function(products){
//console.info(products)
commit("receive_product",products)
})
}
而这里获取产品就需要通过API来,这个我模拟获取数据
/**
* 模拟服务器获取数据
*/
var _products = [
{"id": 1, "title": "iPad 4 Mini", "price": 500.01, "inventory": 2},
{"id": 2, "title": "H&M T-Shirt White", "price": 10.99, "inventory": 10},
{"id": 3, "title": "Charli XCX - Sucker CD", "price": 19.99, "inventory": 5}
]
export default {
//模拟获取
getProducts:function(callback){
setTimeout(callback(_products), 300)
},
}
最后通过在vux组件(product)中调用actions:
created () {
this.$store.dispatch('getAllProducts')
}
展现刷新产品:
从store中获产品,由于动态所以必须在computed获取:
computed: mapGetters({
products: 'allProducts',
}),
这里要解释:mapGetters,是vuex为我们提供的一个工具函数,方便我们调用getter的方法
由于这个商品,会和购物车模块有联系所以我们单独写在 getter.js 中的方法:
//商品列表
var allProducts = function(state){
return state.products.all;
}
通过获取protuct模块下的state中的all,这样我们就动态的创建产品