(一)为什么要使用vuex
Vuex的定义: Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
(简单说就是,一个公共的数据共享中心,在任何地方都能调用数据共享中心的数据,并且在一处修改,其他位置也会跟着修改)
Vuex主要解决了: 复杂组件之间的数据共享问题
(二)使用vuex的步骤
1 . 安装 vuex
npm install vuex --save
2 . 在 src
目录下创建 store
文件夹 并创建一个 index.js
文件
在 index.js
文件中 引入 vuex
import Vue from 'vue'
import Vuex from "vuex"
Vue.use(Vuex)
export default new Vuex.Store({
// 存放公用的数据,相当于 data中的数据
state: {},
// 组件通过this.$store.dispatch('event', params),的形式,调用actions中的函数
// 然后actions根据上下文,获取mutations,并调用mutations中定义的函数
actions: {},
// 组件通过this.$store.commit('event', params),的形式,调用mutations中的函数
mutations: {},
// 相当于计算属性,对state中的数据进行二次计算,需要return回数据,所以一般用ES6中的箭头函数
getters: {}
})
再在 main.js
文件中引入 store
文件夹
这样一个完整健全的 store
就被创建完成了
可以在组件中通过 {{ this.$store.state.name }}
的形式,调用 store
中定义的变量
在这里插入图片描述
(三)vuex的state、actions、mutations、getters简介
import Vue from 'vue'
import Vuex from "vuex"
Vue.use(Vuex)
export default new Vuex.Store({
// 存放公用的数据,相当于 data中的数据
state: {
name: '张三'
},
// 组件通过this.$store.dispatch('event', params),的形式,调用actions中的函数
// 然后actions根据上下文,获取mutations,并调用mutations中定义的函数
actions: {
handleChangeName({commit}, newName) {
commit('handleChangeNewName', newName)
}
},
// 组件通过this.$store.commit('event', params),的形式,调用mutations中的函数
mutations: {
handleChangeNewName(state, newName) {
state.name = newName
}
},
// 相当于计算属性,对state中的数据进行二次计算,需要return回数据,所以一般用ES6中的箭头函数
getters: {
doubleName(state) {
return state.name + ' ' + state.name
},
otherName: state => state.name + '123'
}
})
1 . state 单一状态树
用一个对象包含了全部的应用层级状态(简单说就是类似组件中的data
)变量都定义在state
中
组件调用 store
中的数据:
(一)通过模板字符串的形式,插入
{{ this.$store.state.name }}
(二)在 computed
中返回该数据
<template>
<div>
{{ name }}
</div>
</template>
<script>
export default {
computed: {
name() {
return this.$store.state.name
}
},
}
</script>
(三)最常用的是,使用vue
提供的 mapState
辅助函数
<template>
<div>
{{ name }}
</div>
</template>
<script>
import {mapState, mapGetters} from "vuex";
export default {
computed: {
// 映射 this.name 为 this.$store.state.name
// 如果有多个属性,在数组中继续添加即可
...mapState(['name']),
},
}
</script>
2 . mutations(mutations 只能处理同步任务)
更改 Vuex
的 store
中的状态的唯一方法是提交 mutation
(简单说就是:修改 Vuex
中的变量,只能通过 mutation
定义的方法进行修改,这也就是前面vuex
定义中状态以一种可预测的方式发生变化
)
一般是组件中通过 this.$store.dispatch('event', 'param')
的形式,调用action
中的事件,再通过action
调用mutations
中的事件,达到修改 state
中数据
举个例子:
<template>
<div>
{{ this.$store.state.name }}
{{ name }}
<div>{{ doubleName }}</div>
<div>{{ otherName }}</div>
<button @click="handleClick">改变名称</button>
</div>
</template>
<script>
import {mapState, mapGetters} from "vuex";
export default {
computed:{
...mapState(['name']),
...mapGetters(['doubleName','otherName'])
},
methods: {
handleClick() {
// 通过 this.$store.dispatch 调用 actions 中的 handleChangeName 并传入 ‘李四’ 为参数
this.$store.dispatch('handleChangeName', '李四')
}
}
}
</script>
注意 mutations
需要传入 state
的形参
actions
需要传入上下文,以便获取到mutations
中的事件
{commit}
是一种简写,常规应该是
handleChangeName(ctx, newName) {
// 调用 mutations 中的 handleChangeNewName
ctx.commit('handleChangeNewName', newName)
}
import Vue from 'vue'
import Vuex from "vuex"
Vue.use(Vuex)
export default new Vuex.Store({
state: {
name: '张三'
},
actions: {
handleChangeName({commit}, newName) {
// 调用 mutations 中的 handleChangeNewName
commit('handleChangeNewName', newName)
}
},
mutations: {
handleChangeNewName(state, newName) {
// 修改 state 中的值
state.name = newName
}
},
})
也可以在组件中通过this.$store.commit('event', 'params')
跳过actions
直接调用mutations
中的事件,修改state
中的值,但无论如何,都无法跳过mutations
直接修改state
中的值
<template>
<div>
{{ this.$store.state.name }}
{{ name }}
<div>{{ doubleName }}</div>
<div>{{ otherName }}</div>
<button @click="handleClick">改变名称</button>
</div>
</template>
<script>
import {mapState, mapGetters} from "vuex";
export default {
computed:{
...mapState(['name']),
...mapGetters(['doubleName','otherName'])
},
methods: {
handleClick() {
// 通过 this.$store.commit 调用 mutations 中的 handleChangeNewName 并传入 ‘李四’ 为参数
this.$store.commit('handleChangeNewName', '李四')
}
}
}
</script>
注意:同样的 mutations
也可以通过 mapMutations
辅助函数解构映射到 methods
中
methods: {
// 将 `this.increment()` 映射为 `this.$store.commit('increment')`
...mapMutations(['increment']),
// 将 `this.add()` 映射为 `this.$store.commit('increment')`
// 重新命名
...mapMutations({
add: 'increment'
})
}
3 . actions(actions 可以处理异步操作,也可以处理同步任务)
Action
类似于 mutation
,不同在于:
Action
提交的是 mutation
,而不是直接变更状态。
Action
可以包含任意异步操作。
4 . getters(getters 可以从store 中的 state 中派生出一些状态,类似计算属性computed)
getters 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。
组件调用 getters
中的数据:
(一)通过模板字符串的形式,插入
<div>{{this.$store.getters.doubleName}}</div>
(二)在 computed
中返回该数据
computed: {
doubleName() {
return this.$store.getters.doubleName
}
}
(三)使用vue
提供的 mapGetters
辅助函数
<template>
<div>
{{ this.$store.state.name }}
<div>{{this.$store.getters.doubleName}}</div>
{{ name }}
<div>{{ doubleName }}</div>
<div>{{ otherName }}</div>
</div>
</template>
<script>
import {mapState, mapGetters} from "vuex";
export default {
computed:{
...mapState(['name']),
...mapGetters(['doubleName','otherName'])
},
}
</script>
getters
的参数:可以将其他的getters
计算后的值作为参数使用
getters: {
doubleName(state , getters) {
return state.name + ' ' + getters.otherName
},
otherName: state => state.name + '123'
}