Vuex是实现各个组件之间的互相通讯的状态管理模式 Vuex五个核心概念 state:存储vue的基本数据 mutations:唯一能改变state中数据并触发视图更新 actions:异步操作,并提交到mutations中 getters:Vuex中的计算属性 modules: 模块,可以把Vuex按照功能拆分成不同的模块
state
存在vuex的数据,全局都能调用,避免了组件之间频繁导入,注意:刷新页面时,state中的数据会回复到初始值,需要做好相关默认数据逻辑。 在页面中可以使用 $store.state.xxx来获取state中对应的值,也可以使用computed,相对于第一中写法来说页面看起来比较简洁点,当然还可以使用辅助函数mapState。
<div>
{{$store.state.count}}
<br/>
{{total}}
</div>
computed: {
total() {
return this.$store.state.count
}
}
mapState
当同一个组件获取多个状态时,可使用mapState辅助函数帮助我们生成计算属性,mapState是在computed中使用的,当有多个计算属性时要用三点运算符,没有多余的计算属性时,可以直接写,使用方法如下:
<div>
{{total}}
</div>
import { mapState } from 'vuex'
computed:mapState(['count'])
computed:{
...mapState(['count'])
}
computed:{
...mapState({
count: state => state.count
count: 'count'
})
}
mutations
修改state中的数据,通过commit来触发该属性中对应的方法,commit函数接收两个参数,第一个参数是mutations中的方法名字符串形式,第二个参数是需要传递的值(可传可不传)或者使用 mapMutations 辅助函数将组件中的 methods 映射为 store.commit 调用(需要在根节点注入 store)。 mutations中的每个方法都可以接收两个参数,第一个参数是state,第二个参数是传递的值。 必须是同步函数,如果有异步要在actions调用
<div @click="setCount(2)">加加--{{count}}</div>
import { mapState, mapMutations } from 'vuex'
export default{
computed: {
...mapState(['count'])
},
methods: {
setCount(total) {
this.$store.commit('setCount',total)
},
...mapMutations([
'setCount'
]),
...mapMutations({
setCount: 'setCount'
})
}
}
state: {
count: 0
},
mutations: {
setCount(state, data) {
state.count = data
}
}
actions
actions是提交到mutations中,而不是直接变更状态,可以包含任何异步操作,该函数接受一个与 store 实例具有相同方法和属性的 context 对象,可以通过通过dispatch来触发或者使用 mapActions 辅助函数将组件的 methods 映射为 store.dispatch 调用(需要先在根节点注入 store)
<div @click="increment">increment--{{count}}</div>
import { mapState, mapActions } from 'vuex'
export default{
computed: {
...mapState(['count'])
},
methods: {
increment(total) {
this.$store.dispatch('increment',total)
},
...mapActions([
'increment'
]),
...mapActions({
increment: 'increment'
})
}
}
state: {
count: 0
},
mutations: {
setCount(state, data) {
state.count = data
}
},
actions: {
increment(context,data) {
context.commit('setCount', data)
}
}
getters
getters就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。mapGetters 辅助函数使用方法类似mapState
<div>getters--{{getUserList}}</div>
<div>userList--{{userList}}</div>
import { mapGetters } from 'vuex'
export default{
computed: {
...mapGetters(['getUserList']),
...mapGetters({
userList: 'getUserList'
})
},
}
state: {
userList: [
{ id: 1, name: '张三', isShow: true },
{ id: 2, name: '李四', isShow: false }
]
},
getters: {
getUserList(state) {
return state.userList.filter( item => item.isShow )
}
}
module
当项目中功能比较复杂时,可以将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割。 可以给每个模块添加 namespaced: true 属性其成为带命名空间的模块,当模块被注册后,它的所有 getter、action 及 mutation 都会自动根据模块注册的路径调整命名。 模块中各各属性使用方法跟上面一样,只不过要在调用的时候加上模块的名字。 在store文件夹下面新建一个modules文件夹
const state = {
name: 'modulesA'
}
const mutations = {
changeModulesName(state, name) {
state.name = name
}
}
const actions = {
delayChangeModulesName(context, name) {
context.commit('changeModulesName', name)
}
}
const getters = {
getModules( state ) {
return `${state.name}`
}
}
export default {
namespaced: true,
state,
actions,
mutations,
getters
}
import moduleA from './modules/modulesA'
modules: {
a: moduleA
}
在组件中是用store模块的中的数据时,有两种写法
computed: {
...mapState('a',['name']),
...mapState({
modulesName: state => state.a.name
})
...mapGetters({
name: 'a/getModules'
})
}
在组件中是用store模块的中的方法与数据时,只需要在方法名前面加上模块名称即可
methods: {
...mapMutations({
changeModulesName: 'a/changeModulesName'
}),
...mapActions({
delayChangeModulesName: 'a/delayChangeModulesName'
})
}
|