什么是Vuex,这里就不介绍了,请移步到官网 vuex.vuejs.org/zh/guide/ 学习,这里咱们只须要知道Vuex能够用来作应用的状态管理。 首先来看一下使用vue create my-project命令生成项目的时候,自动生成的Vuex的代码,store.js:vue
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
},
mutations: {
},
actions: {
}
})
复制代码
下面咱们来搞懂模版代码中的state,mutations,actions是干吗的,既然Vuex能够用来作状态管理,那么管理的是什么?咱们知道vue是mvvm架构,想到mvvm 咱们就是想到数据驱动ui,因此,状态管理,说白了管理的就是数据,那么咱们就能够把咱们须要操控的数据放在state里面vuex
状态,也就是存放咱们须要操控的数据数组
改变,若是咱们须要改变state中的数据的时候能够在这里面操做,怎么操做?下面说bash
行为,和mutations相似,咱们想要改变state中的数据的时候能够在这里面进行操做,一样,怎么操做,下面说架构
既然是状态管理,若是咱们直接操做state去改变他的值的话,固然就称不上管理,Vuex采用集中式存储管理应用的全部组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化 ,固然不会直接让咱们去修改state里面的值。若是想要改变状态的值怎么办,mutations登场:异步
store.js:
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
userInfo: {}
},
mutations: {
setUserInfo(state) {
let info = {
name: 'wfq',
age: 26
}
state.userInfo = info
}
},
actions: {}
})
复制代码
而后在咱们的页面上,咱们能够这样使用:mvvm
<template>
<div>
<div>name:{{$store.state.userInfo.name}}</div>
<el-button type="primary" size="small" @click="$store.commit('setUserInfo')">获取用户信息</el-button>
</div>
</template>
<script>
export default {
name: "vuex1",
data() {
return {}
},
methods: {},
mounted() {
}
}
</script>
<style scoped>
</style>
复制代码
使用$store.commit('setUserInfo')来触发mutations中的getUserInfo方法,对于mutations,这里有几点须要注意:ide
多个 state 的操做 , 使用 mutations 会来触发会比较好维护 , 那么须要执行多个 mutations怎么办?actions登场,前面说过 官方建议咱们在actions里面写异步的代码,那么咱们模拟一下:函数
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
userInfo: {}
},
mutations: {
setUserInfo(state,userInfo) {
state.userInfo = userInfo
}
},
actions: {
// commit来自Vuex中上下文context,这里直接使用对象解构,至关于context.commit('setUserInfoAsync',info)
setUserInfoAsync({commit}){
setTimeout(()=>{
let info = {
name: 'wfq',
age: 26
}
commit('setUserInfo',info)
},2000)
}
}
})
复制代码
在store.js中咱们在actions中使用commit来触发mutations里面的方法,这个和上面说的一致,那么咱们怎么触发actions里面的方法:学习
<template>
<div>
<div>name:{{$store.state.userInfo.name}}</div>
<el-button type="primary" size="small" @click="$store.dispatch('setUserInfoAsync')">获取用户信息</el-button>
</div>
</template>
复制代码
咱们使用dispatch来触发actions里面的方法。
若是咱们调用方法,页面上过分使用this.$store.***的话,会显得很累赘,上面三个函数即是Vuex给咱们提供的函数,方便咱们调用store里面的方法 首先记住一点,mapstate和mapGetters放在computed中,mapActions放在methods,记得导入mapState,mapGetters,mapActions,那么咱们以前页面的代码能够改写以下:
store.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
userInfo: {}
},
getters:{
getUserInfo(state){
return state.userInfo
}
},
mutations: {
setUserInfo(state,userInfo) {
state.userInfo = userInfo
}
},
actions: {
// commit来自Vuex中上下文context,这里直接使用对象解构,至关于context.commit('setUserInfoAsync',info)
setUserInfoAsync({commit}){
setTimeout(()=>{
let info = {
name: 'wfq',
age: 26
}
commit('setUserInfo',info)
},2000)
}
}
})
复制代码
页面
<template>
<div>
<div>name:{{userInfo.name}}</div>
<el-button type="primary" size="small" @click="getInfo">获取用户信息</el-button>
</div>
</template>
<script>
import {mapState,mapGetters,mapActions} from 'vuex'
export default {
name: "vuex1",
data() {
return {}
},
computed:{
// 这里的mapState对应store.js里面的state,参数是个数组,里面的元素其实就是store.js里面的state里面的数据
...mapState([
'userInfo'
]),
// 这里的mapGetters对应store.js里面的getters,参数是个数组,里面的元素其实就是store.js里面的getters里面的方法
// mapGetters其实和mapState相似,都是获取state里面的数据,大多数状况,咱们使用mapState便可,这也是为何state.js的
// 模版代码中没有getters
...mapGetters([
'getUserInfo'
])
},
methods: {
// 这里的mapActions对应的是store.js里面的actions,参数是个数组,里面的元素其实就是store.js里面的actions里面的方法
...mapActions([
'setUserInfoAsync'
]),
getInfo(){
// 调用的方法是mapActions里面的setUserInfoAsync
this.setUserInfoAsync()
},
},
mounted() {
}
}
</script>
<style scoped>
</style>
复制代码
这里咱们使用了Vuex的modules,以及namespaced属性,modules容许咱们以modules的形式导出多个store,namespaced:true的话表明 咱们访问store里面的方法时要在对应的命名空间下
下面咱们改写代码,新建store文件夹,在下面新建index.js和modules文件夹,在modules文件夹下面新建一个咱们本身须要的文件夹wfq, 而后在wfq下面新建modules文件夹和index.js,而后在main.js里修改store的路径,目录结构以下图
代码以下:
store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
import wfq from './modules/wfq'
Vue.use(Vuex)
export default new Vuex.Store({
modules: {
wfq
}
})
复制代码
store/modules/wfq/index.js
// 找出以.js开头的文件
const files = require.context('./modules', false, /\.js$/)
const modules = {}
files.keys().forEach(key => {
modules[key.replace(/(\.\/|\.js)/g, '')] = files(key).default
})
export default {
namespaced: true,
modules
}
复制代码
store/modules/wfq/modules/user.js
export default {
namespaced: true,
state: {
userInfo: {name:'WFQ'}
},
getters:{
getUserInfo(state){
return state.userInfo
}
},
mutations:{
setUserInfo(state,info){
state.userInfo = info
}
},
actions: {
setUserInfoAsync({commit}){
setTimeout(()=>{
let info = {
name: 'wfq',
age: 26
}
commit('setUserInfo',info)
},2000)
}
}
}
复制代码
接下来看咱们怎么使用:
<template>
<div>
<div>name:{{userInfo.name}}</div>
<el-button type="primary" size="small" @click="setInfo">设置用户信息</el-button>
</div>
</template>
<script>
import {mapState,mapActions} from 'vuex'
export default {
name: "demo1",
data() {
return {}
},
computed:{
...mapState('wfq/user',[
'userInfo',
]),
},
methods: {
...mapActions('wfq/user',[
'setUserInfoAsync',
]),
setInfo(){
this.setUserInfoAsync();
},
},
mounted() {
}
}
</script>
复制代码
使用modules修改后,mapState和mapActions要在第一个参数加上路径,'wfq/user',这也就证实了namespaced的做用
接下来再思考一个问题,若是我在一个store文件(例如user.js)里面想调用另外一个store的方法怎么办,好比,在获得用户的信息后, 我想直接调用该用户的订单信息,而后存储在vuex中怎么办?咱们知道,获取订单信息是一个异步操做,咱们要放在actions里面,而actions里面的 方法怎么触发呢?使用dispatch 咱们新建一个store文件,order.js,此时目录结构以下图
代码以下:
export default {
namespaced: true,
state: {
orderList:[]
},
getters:{
},
mutations:{
},
actions: {
setOrderListByUser({state},userInfo){
if(userInfo.name === 'wfq'){
let orderlist = ['order1','order2']
state.orderList = orderlist
}
}
}
}
复制代码
下面咱们修改user.js的代码以下:
actions: {
setUserInfoAsync({commit,dispatch}){
setTimeout(()=>{
let info = {
name: 'wfq',
age: 26
}
commit('setUserInfo',info)
dispatch('wfq/order/setOrderListByUser',info,{ root: true })
},2000)
}
}
复制代码
咱们使用dispatch来触发order下面的setOrderListByUser的方法,并传入用户信息,注意:这里要设置{ root: true }, 这样咱们就能在别的页面获取到order.js里面的state下面的orderList的数据了,注意:别忘了去main.js里面修改store的路径