vue-cli中使用vuex
一、vuex的作用
官网的解释:每一个 Vuex 应用的核心就是 store(仓库)。“store”基本上就是一个容器,它包含着你的应用中大部分的状态 (state)。
我的理解:vuex就是用来存储数据的,的当你通过api向后台获得数据后,你可以把这些数据存在vuex的store里,之后使用的时候就可以直接在store中获取,当然你也可以把网页运行时产生的数据存在store里面。
二、vuex与全局对象的区别
区别1:Vuex 的状态存储是响应式的
既然是要存数据,那么为什么不简单的使用一个全局对象,而要用vuex呢,因为vuex的转台存储是响应式的,可以看下面的例子,这是组件中的一段js代码
export default {
name: 'sample',
computed: {
a () {
// 这里a从store中读取了状态b,所以当b变化后
// a的值就会跟着发生变化
return this.$store.state.b
}
}
}
如果单单是全局对象的话是做不到这一点的。
区别2:你不能直接改变 store 中的状态
改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation,
也就是说你不能直接this.$store.state.b += 1
,这样会报错。
正确的做法是commit mutation
// store.js
const mutations = {
increaseB (state) {
state.b += 1
}
}
// 组件中使用commit
this.$store.commit('increaseB')
三、简单的使用方法
下面举一个获取商品价格例子
这是vue-cli的src目录下的结构
src
|-- main.js
|-- api // 与后台交互的api
| |-- goodsAPI.js
|
|-- components // 组件目录
| |-- goods.vue
|
|-- store
|-- modules
| |-- goods.js
|
|-- index.js
// src/api/goodsAPI.js
// 使用axios向后台发送get请求
import axios from 'axios'
const myAxios = axios.create({
// 这里换成你服务器的url
baseURL: 'http://1.2.3.4:8080',
timeout: 1000,
headers: {
'Content-Type': 'application/json;charset=UTF-8'
}
})
export default {
getGoodsInfoFromServer (resolve, reject) {
myAxios.get('getGoodsInfo').then(resolve, reject)
// 这里就是向'http://1.2.3.4:8080/getGoodsInfo'发送了get请求
// 拿到response后再resolve中处理,出错了就在reject中处理
}
}
// src/store/modules/goods.js
import goodsAPI from '../../api/goodsAPI'
const state = {
goodsInfo: []
}
const getters = {}
// 这个例子里先不管getters,因为没什么必要
const mutations = {
getGoodsInfoMMM (state, data) {
state.goodsInfo.push(data)
// 注意mutation里面的操作只能是同步的,
// 所以goodsAPI只能在actions中调用
}
}
const actions = {
getGoodsInfoAAA ({ commit }) {
goodsAPI.getGoodsInfoFromServer(resposne => {
// 这就是传入getGoodsInfoFromServer的resolve
if (response.status === 200) {
// 成功的处理
commit('getGoodsInfoMMM', response.data)
// axios中response的body叫做data
} else {
// 其他返回状态的处理
}
}, err => {
// 这就是传入getGoodsInfoFromServer的reject
// 如果服务器返回的状态码是4xx,那么都会在这里被处理
console.error(err)
})
}
}
export default {
// namespaced: true是为了区分不同module下的同名方法
namespaced: true,
state,
getters,
actions,
mutations
}
// src/store/index.js
// 把不同模块合起来(目前只有一个模块)
import Vue from 'vue'
import Vuex from 'vuex'
import goods from './modules/goods'
Vue.use(Vuex)
const debug = process.env.NODE_ENV !== 'production'
export default new Vuex.Store({
modules: {
goods
},
strict: debug
})
// src/components/goods.vue
<template>
<div v-for="good in goodsInfo">
{{ good.someProperty }}
</div>
</template>
<script>
export default {
name: 'goods',
computed: {
goodsInfo () {
// 在this.$store.state.goods.goodsInfo更新后
// computed中的goodsInfo也会跟着改变
return this.$store.state.goods.goodsInfo
// 但是注意如果goodsInfo的类型是Map或Set那么vue是
// 检测不到它的变化的
}
},
mounted {
this.$store.dispatch('goods/getGoodsInfoAAA')
// 这条指令就调用了actions中的getGoodsInfoAAA
}
}
</script>
// src/main.js
// store需要在main中全局注入
import Vue from 'vue'
import App from './App'
import store from './store/index'
new Vue({
el: '#app',
store,
components: { App },
template: '<App/>'
})