官方文档
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
bus
和js的事件中心类似
main.js
const bus = new Vue()
Vue.prototype.$bus = bus
home.vue
<div class="home">
<p>content: {{content}}</p>
<button @click="click">传递数据给content组件</button>
<g-content></g-content>
</div>
export default {
name: 'Home',
data () {
return {
content: '修改之前'
}
},
components: {
},
methods: {
click () {
this.$bus.$emit('change', this.content)
}
}
}
G-content.vue
<template>
<div class="page">
这是content页面---{{content}}
</div>
</template>
<script>
export default {
name: 'GContent',
data () {
return {
content: ''
}
},
mounted () {
this.$bus.$on('change', res => {
this.content = res
})
}
}
</script>
vuex-state&getter
state
官方文档
存储在 Vuex 中的数据和 Vue 实例中的 data
遵循相同的规则,例如状态对象必须是纯粹 (plain) 的。参考:Vue#data。
在 Vue 组件中获得 Vuex 状态
什么是getters
在Store仓库里,state就是用来存放数据,若是对数据进行处理输出,比如数据要过滤,一般我们可以写到computed中。但是如果很多组件都使用这个过滤后的数据,比如饼状图组件和曲线图组件,我们是否可以把这个数据抽提出来共享?这就是getters存在的意义。我们可以认为 getters 是store的计算属性。
那么我们如何在 Vue 组件中展示状态呢?由于 Vuex 的状态存储是响应式的,从 store 实例中读取状态最简单的方法就是在计算属性中返回某个状态:
在state中定义一个变量
store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
userName: 'nick'
},
getters: {
firstLetter: (state) => {
console.log(typeof state.userName)
return state.userName.slice(-1)
}
},
mutations: {
},
actions: {
},
modules: {
}
})
通过计算属性拿到变量
home.vue
<p>用户名:{{userName}}</p>
<p>最后一个字母是--{{firstLetter}}</p>
computed: {
userName () {
return this.$store.state.userName
},
firstLetter () {
return this.$store.getters.firstLetter
}
}
mapState 辅助函数
<p>用户名:{{userName}}</p>
<p>最后一个字母是--{{firstLetter}}</p>
import { mapState, mapGetters } from 'vuex'
computed: {
// 获取state内变量的第一种方法
...mapState([
'userName'
]),
// 获取state内变量的第二种方法
...mapState({
userName: 'userName'
}),
// 获取state内变量的第三种方法
userName () {
return this.$store.state.userName
},
// 调用getters内函数的第一种方法
...mapGetters([
'firstLetter'
]),
// 调用getters内函数的第二种方法
...mapGetters({
firstLetter: 'firstLetter'
}),
// 调用getters内函数的第三种方法
firstLetter () {
return this.$store.getters.firstLetter
}
}
vuex-mutation&action/module
Mutation
mutation 必须是同步函数
更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数
home.vue
methods: {
changeUserName () {
// 第一种方法
this.$store.commit('CHANGE_USER_NAME')
// 第二种方法, 两个参数
this.$store.commit('CHANGE_USER_NAME', {
newUserName: 'Richard'
})
// 第三种方法, 对象的写法
this.$store.commit({
type: 'CHANGE_USER_NAME',
newUserName: 'Richard'
})
},
state/index.js
mutations: {
// 第一种方法
CHANGE_USER_NAME (state) {
state.userName = 'Richard'
}
// 第二种方法
CHANGE_USER_NAME (state, params) {
state.userName = params.newUserName
}
// 第三种方法
CHANGE_USER_NAME (state, params) {
state.userName = params.newUserName
}
},
如果要添加一个state内本来没有的属性, 也只能在 mutations 里操作
使用 Vue.set(obj, 'newProp', 123)
home.vue
<p>新增的值--{{newValue}}</p>
<button @click="setNewValue">点击新增</button>
computed: {
...mapState([
'newValue'
]),
},
methods: {
setNewValue () {
this.$store.commit('SET_NEW_VALUE')
}
}
state/index.js
SET_NEW_VALUE (state) {
Vue.set(state, 'newValue', 'newValue')
}
action
Action 类似于 mutation,不同在于:
Action 提交的是 mutation,而不是直接变更状态。
Action 可以包含任意异步操作。
home.vue
<p>用户名:{{userName}}</p>
<p>最后一个字母是--{{firstLetter}}</p>
<button @click="actions">使用actions改变username</button>
import { mapState, mapGetters, mapActions } from 'vuex'
computed: {
...mapActions([
'actionChangeUserneme'
])
},
methods: {
actions () {
this.$store.dispatch('actionChangeUserneme', {
newUserName: 'david'
})
},
changeUserName () {
this.$store.commit({
type: 'CHANGE_USER_NAME',
newUserName: 'Richard'
})
},
state/index.js
export default new Vuex.Store({
state: {
userName: 'nick'
}
mutations: {
CHANGE_USER_NAME (state, params) {
state.userName = params.newUserName
}
},
// actions支持异步操作
actions: {
actionChangeUserneme (state, params) {
setTimeout(() => {
state.commit('CHANGE_USER_NAME', params)
}, 1000)
}
}
})