初始化vue项目
安装Vuex
npm install vuex --save
初始化Vuex
在项目根目录下的
src
目录下创建vuex
文件夹,用于存放vuex
相关文件,并新建index.js
用于编写相关代码
创建
Vuex
实例,并向外暴露
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
// 用于存放状态(数据)
state: {
},
// 用于处理state中的状态(相当于vue中的计算属性)
getter: {
},
// 用于存放同步方法
mutations: {
},
// 用于存放异步方法
actions: {
}
})
export default store
在main.js中引入Vuex实例,并挂载在Vue实例上
import Vue from 'vue'
import App from './App'
import router from './router'
import store from './vuex/index.js'
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
store,
components: { App },
template: '<App/>'
})
这样就可以在全局使用
vuex
中的状态了
在组件中使用Vuex
同步
因为已经在
mian.js
中引入了vuex
的实例,所以可以在全局使用,通过this.$store
使用vuex
实例中的state、getter、mutations、actions
vuex/index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
// 用于存放状态(数据)
state: {
num: 0
},
// 用于处理state中的状态(相当于vue中的计算属性)
getter: {
},
// 用于存放同步方法
mutations: {
addFun: function (state) {
state.num++
},
reduceFun: function (state) {
state.num--
}
},
// 用于存放异步方法
actions: {
}
})
export default store
HelloWorld.vue
中触发事件来提交mutations
中的同步方法,提交mutations
中的方法使用commit
<template>
<div class="hello">
<div class="box">{{num}}</div>
<button @click='add'>+</button>
<button @click='reduce'>-</button>
</div>
</template>
<script>
export default {
data: function () {
return {
// 错误写法
// num: this.$store.state.num
}
},
computed: {
// 正确写法
num: function () {
return this.$store.state.num
}
},
methods: {
add: function () {
this.$store.commit('addFun')
},
reduce: function () {
this.$store.commit('reduceFun')
}
}
}
</script>
由于 Vuex 的状态存储是响应式的,从 store 实例中读取状态最简单的方法就是在
计算属性
中返回某个状态
----(vue官网)
你不能直接改变 store 中的状态。改变 store 中的状态的
唯一途径
就是显式地提交(commit) mutation
。这样使得我们可以方便地跟踪每一个状态的变化 ----(vue官网)
为什么要在
computed
中获取?data
是有缓存的,一旦Vuex
中值改变了,没法做到响应。而放在computed
中,虽然也有缓存,但会自动监视依赖
,此外,不能直接改变state
中的值,只能通过commit
或者dispatch
异步
action
函数接受一个与store
实例具有相同方法和属性的context
对象,因此你可以调用context.commit
提交一个mutation
,或者通过context.state
和context.getters
来获取state
和getters
,提交actions
中的异步方法使用dispatch
<template>
<div class="hello">
<div class="box">{{num}}</div>
<button @click='add'>+</button>
<button @click='reduce'>-</button>
<button @click='asyncAdd'>异步+</button>
</div>
</template>
<script>
export default {
data: function () {
return {
// 错误写法
// num: this.$store.state.num
}
},
computed: {
// 正切写法
num: function () {
return this.$store.state.num
}
},
methods: {
add: function () {
this.$store.commit('addFun')
},
reduce: function () {
this.$store.commit('reduceFun')
},
// 异步方法
asyncAdd: function () {
this.$store.dispatch('asyncAddFun')
}
}
}
</script>
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
// 用于存放状态(数据)
state: {
num: 0
},
// 用于处理state中的状态(相当于vue中的计算属性)
getter: {
},
// 用于存放同步方法
mutations: {
addFun: function (state) {
state.num++
},
reduceFun: function (state) {
state.num--
}
},
// 用于存放异步方法
actions: {
// 异步方法
asyncAddFun: function (context) {
setTimeout(function () {
// 错误写法,Action 提交的是 mutation,而不是直接变更状态。
// state.num++
context.commit('addFun')
}, 2000)
}
}
})
export default store
注意官网中的这句话—
改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation
,在actions
中的方法中,也是通过再次提交mutations
中的同步方法来改变state
的
辅助函数
this.$store.sate.XXX
、this.$store.getter.XXX
、this.$stpre.commit('XXX')
、this.dispatch('XXX')
这样的写法太繁琐,因此Vuex
提供了辅助函数
mapState
-------帮助我们生成计算属性
mapGetters
-------将 store 中的 getter 映射到局部计算属性
mapMutations
-------将组件中的 methods 映射为 store.commit 调用(需要在根节点注入 store)
mapActions
--------将组件的 methods 映射为 store.dispatch 调用(需要先在根节点注入 store)
<template>
<div class="hello">
<div class="box">{{num}}</div>
<button @click='addFun'>+</button>
<button @click='reduceFun'>-</button>
<button @click='asyncAddFun'>异步+</button>
</div>
</template>
<script>
import {mapState, mapMutations, mapActions} from 'vuex'
export default {
data: function () {
return {
// 错误写法
// num: this.$store.state.num
}
},
computed: {
...mapState(['num'])
// 等价于
// num:this.$store.state.num
},
methods: {
...mapMutations(['addFun', 'reduceFun']),
// 等价于
// addFun: function () {
// this.$store.commit('addFun')
// },
// reduceFun: function () {
// this.$store.commit('reduceFun')
// },
...mapActions(['asyncAddFun'])
// 等价于
// asyncAddFun: function () {
// this.$store.dispatch('asyncAddFun')
// }
}
}
</script>
参考文章