Vuex
下载
- npm install vuex@next --save
思想
- vuex 是一个数据管理的仓库
- vuex 中有5个核心的配置选项 state 、 getters 、 mutations 、 actions 、 modules
- state 选项用于存放数据
- getters 选项用于存放一些对 state 数据加工的数据,并且具有缓存功能
- mutations 选项中存放用于操作 state 数据的函数,所有操作 state 中的数据的函数都应该写在这里, mutations 中的函数应该是同步的
- actions 选项中可以有异步函数, actions 中配置的函数主要用于触发 mutations 中的函数,从而借用 mutations 中的函数修改 state 中的数据
- modules 选项的主要功能是将一个大的 vuex 拆分为多个小的 vuex
使用思路
- 在组件中使用 this.$store.state 可以拿到 vuex 中 state 选项保存的数据
- 在组件中使用 this.$store.getters 可以拿到 vuex 中 getters 选项中保存的数据
- 在组件中使用 this.$store.commit('字符串函数名') 可以触发 mutations 选项中的函数
- 在组件中使用 this.$store.dispatch('字符串函数名') 可以触发 actions 选项中的函数
配置
- src/store/index.js
import {createStore} from 'vuex'
// 创建一个 store 实例
const store = createStore({
state: { // 存放数据地方
num: 1
},
mutations: { // 存放修改数据的地方
INCREMENT(state, payload) {
state.num += payload
}
},
actions: { // 存放触发 mutations 的地方
incrementWait(context, payload) {
setTimeout(() => {
context.commit('INCREMENT', payload)
}, 1000)
}
},
getters: { // 基于 state 数据进行加工的地方
bigSum(state) {
return state.num * 10
}
}
})
// 暴露
export default store
actions 选项中定义的函数,第一个参数是一个上下文对象 context ,可以通过上下文对象里面的 commit 函数调用 mutations 里面的函数,在上下文对象中也可以拿到 state 但不要直接修改里面的值而是要借助 mutations 里面的函数修改 state 的值
actions 选项中定义的函数,第二个参数是 组件使用 dispatch 触发时传递过来的
- src/main
import { createApp } from 'vue'
import App from './App.vue'
import store from "./store"; // 引入
const app = createApp(App)
app
.use(store) // 使用该插件
app.mount('#app')
- 现在所有的组件都可以通过 this.$store 使用 vuex
基本使用
<template>
<div>Demo</div>
<div>vuex中的state数据 {{this.$store.state.num}}</div>
<div>vuex中的getters中加工了的数据 {{this.$store.getters.bigSum}}</div>
<div>
<button @click="increment">调用 commit 触发 mutations 中的函数</button>
<button @click="incrementWait">调用 dispatch 触发 actions 中的函数</button>
</div>
</template>
<script>
export default {
methods: {
increment() {
// 通过 this.$store.commit 触发 mutations 中的 INCREMENT 函数 并传递一个参数 1
this.$store.commit('INCREMENT', 1)
},
incrementWait() {
// 通过 this.$store.dispatch 触发 actions 中的 incrementWait 函数 并传递一个参数 10
this.$store.dispatch('incrementWait', 10)
}
}
}
</script>
- 使用 this.$store.state 可以拿到 vuex 中 state 中的数据
- 使用 this.$store.getters 可以拿到 vuex 中 getters 加工的数据
- 使用 this.$store.dispatch 可以触发 vuex 中 actions 里面的函数,并且在调用 dispatch 函数时可以传递1个参数
- 使用 this.$store.commit 可以触发 vuex 中 mutations 里面的函数,并且在调用 commit 函数时可以传递 1 个参数
优化模板中vuex的使用
<template> <div>Demo</div> <div>vuex中的state数据 {{num}}</div> <div>vuex中的getters中加工了的数据 {{bigSum}}</div> <div> <button @click="increment">调用 commit 触发 mutations 中的函数</button> <button @click="incrementWait">调用 dispatch 触发 actions 中的函数</button> </div> </template> <script> export default { computed: { num() { return this.$store.state.num }, bigSum() { return this.$store.getters.bigSum } }, methods: { increment() { // 通过 this.$store.commit 触发 mutations 中的 INCREMENT 函数 并传递一个参数 1 this.$store.commit('INCREMENT', 1) }, incrementWait() { // 通过 this.$store.dispatch 触发 actions 中的 incrementWait 函数 并传递一个参数 10 this.$store.dispatch('incrementWait', 10) } } } </script>
- 借助计算属性,优化 vuex 的 state 和 getters 在模板中的使用
mapState 和 mapGetters 再次优化Vuex的使用
<template> <div>Demo</div> <div>vuex中的state数据 {{num}}</div> <div>vuex中的getters中加工了的数据 {{bigSum}}</div> <div> <button @click="increment">调用 commit 触发 mutations 中的函数</button> <button @click="incrementWait">调用 dispatch 触发 actions 中的函数</button> </div> </template> <script> import {mapState, mapGetters, } from 'vuex' export default { computed: { ...mapState({num: 'num'}), ...mapGetters({bigSum: 'bigSum'}) }, methods: { increment() { // 通过 this.$store.commit 触发 mutations 中的 INCREMENT 函数 并传递一个参数 1 this.$store.commit('INCREMENT', 1) }, incrementWait() { // 通过 this.$store.dispatch 触发 actions 中的 incrementWait 函数 并传递一个参数 10 this.$store.dispatch('incrementWait', 10) } }, } </script>
- mapState 函数接收一个对象作为参数,对象中的 key 将作为一个 computed 计算属性,对象的 value 将映射到 vuex 中对应的 state。 mapState 函数的返回值是一个对象,需要在计算属性 computed 中解构出来
- mapGetters 函数接收一个对象作为参数,对象中的 key 将作为一个 computed 计算属性,对象的 value 将映射到 vuex 中对应的 getters 。 mapGetters 函数的返回值是一个对象,需要在计算属性 computed 中解构出来
mapState 和 mapGetters 的第二种写法
<template> <div>Demo</div> <div>vuex中的state数据 {{num}}</div> <div>vuex中的getters中加工了的数据 {{bigSum}}</div> <div> <button @click="increment">调用 commit 触发 mutations 中的函数</button> <button @click="incrementWait">调用 dispatch 触发 actions 中的函数</button> </div> </template> <script> import {mapState, mapGetters, } from 'vuex' export default { computed: { ...mapState(['num']), ...mapGetters(['bigSum']) }, methods: { increment() { // 通过 this.$store.commit 触发 mutations 中的 INCREMENT 函数 并传递一个参数 1 this.$store.commit('INCREMENT', 1) }, incrementWait() { // 通过 this.$store.dispatch 触发 actions 中的 incrementWait 函数 并传递一个参数 10 this.$store.dispatch('incrementWait', 10) } }, } </script>
- 调用 mapState 函数可以接收一个数组,数组中的每一个字符串属性与 Vuex 中对应的 state 保持映射关系
- 调用 mapGetters 函数可以接收一个数组,数组中的每一个字符串属性与 Vuex 中对应的 getters 保持映射关系
mapMutations 和 mapActions优化Vuex的使用
<template> <div>Demo</div> <div>vuex中的state数据 {{num}}</div> <div>vuex中的getters中加工了的数据 {{bigSum}}</div> <div> <button @click="increment(1)">调用 commit 触发 mutations 中的函数</button> <button @click="incrementWait(10)">调用 dispatch 触发 actions 中的函数</button> </div> </template> <script> import {mapState, mapGetters, mapMutations, mapActions, } from 'vuex' export default { computed: { ...mapState(['num']), ...mapGetters(['bigSum']) }, methods: { ...mapMutations({increment: 'INCREMENT'}), ...mapActions({incrementWait: 'incrementWait'}) }, } </script>
- mapMutations 函数接收一个对象作为参数,对象中的每个 key 将会转换为一个 methods 函数,对象的 value 与 Vuex 中对应的 mutations 保持映射关系。 mapMutations 返回一个对象,需要解构并且在使用 mutations 生成的函数l时注意传递参数
- mapActions 函数接收一个对象作为参数,对象中的每个 key 将会转换为一个 methods 函数,对象的 value 与 vuex 中对应的 actions 保持映射关系。 mapActions 返回一个对象,需要解构并且在使用 actions 生成的函数时注意传递参数
mapMutations 和 mapActions 的第二种写法
<template> <div>Demo</div> <div>vuex中的state数据 {{num}}</div> <div>vuex中的getters中加工了的数据 {{bigSum}}</div> <div> <button @click="INCREMENT(1)">调用 commit 触发 mutations 中的函数</button> <button @click="incrementWait(10)">调用 dispatch 触发 actions 中的函数</button> </div> </template> <script> import {mapState, mapGetters, mapMutations, mapActions, } from 'vuex' export default { computed: { ...mapState(['num']), ...mapGetters(['bigSum']) }, methods: { ...mapMutations(['INCREMENT']), ...mapActions(['incrementWait']) }, } </script>
- mapMutations 函数接收一个数组作为参数时,数组中的每一个字符串与 Vuex 中对应的 mutations 保持映射关系
- mapActions 函数接收一个数组作为参数时,数组中的每一个字符串与 Vuex 中对应的 actions 保持映射关系
Vuex模块化
import {createStore} from 'vuex'
// 计算相关的vuex模块
const calculate = {
namespaced: true, // 开启命名空间
state: { // 存放数据地方
num: 1
},
mutations: { // 存放修改数据的地方
INCREMENT(state, payload) {
state.num += payload
}
},
actions: { // 存放触发 mutations 的地方
incrementWait(context, payload) {
setTimeout(() => {
context.commit('INCREMENT', payload)
}, 1000)
}
},
getters: { // 基于 state 数据进行加工的地方
bigSum(state) {
return state.num * 10
}
}
}
// 员工相关的 vuex 模块
const staff = {
namespaced: true, // 开启命名空间
state: {
person: ['zhangsan']
},
mutations: {
ADDPERSON(state, payload) {
state.person[0] = payload
}
},
actions: {
addPersonWait(context, payload) {
setTimeout(() => {
context.commit('ADDPERSON', payload)
}, 1000)
}
},
getters: {
changePerson(state) {
return state.person[0] + '666'
}
}
}
// 创建一个 store 实例
const store = createStore({
modules: { // 配置模块
calculate, // 计算模块
staff, // 员工模块
}
})
// 暴露
export default store
- namespaced: true 用于开启命名空间
- modules 选项中配置模块
<template>
<div>Demo</div>
<div>计算模块中的state 和 getters {{num}} ---- {{bigSum}}</div>
<div>
<button @click="INCREMENT(1)">修改计算模块中的 state </button>
<button @click="incrementWait(66)">异步修改计算模块中的 state </button>
</div>
<div>员工模块中的state 和 getters {{person}} --- {{changePerson}}</div>
<div>
<button @click="ADDPERSON('王五')">修改员工模块中的 state</button>
<button @click="addPersonWait('张三')">异步修改员工模块中的 state</button>
</div>
</template>
<script>
import {mapState, mapGetters, mapMutations, mapActions, } from 'vuex'
export default {
computed: {
// 使用指定模块中暴露的 state 数据
...mapState('calculate', ['num']),
...mapState('staff', ['person']),
// 使用指定模块中暴露的 getters 数据
...mapGetters('calculate', ['bigSum']),
...mapGetters('staff', ['changePerson']),
},
methods: {
// 使用指定模块中暴露的 mutations 方法
...mapMutations('calculate', ['INCREMENT']),
...mapMutations('staff', ['ADDPERSON']),
// 使用指定的模块中暴露的 actions 方法
...mapActions('calculate', ['incrementWait']),
...mapActions('staff', ['addPersonWait'])
},
}
</script>
- mapState 、 mapGetters 、 mapMutations 、 mapActions 的第一个参数用于指定 vuex 的模块空间,第二个数组中用于指定映射哪些内容
- 如果不使用这四个辅助函数则写法上有点麻烦
- 取计算模块中的 state this.$store.state.calculate.num
- 取计算模块中的 getters this.$store.getters['calculate/bigSum']
- 使用计算模块中的 mutations this.$store.commit('calculate/INCREMENT', 1)
- 使用计算模块中的 actions this.$store.dispatch('calculate/incrementWait', 50)
Component API 中使用 Vuex
<template>
<div>Demo</div>
<div>计算模块中的state 和 getters {{num}} ---- {{bigSum}}</div>
<div>
<button @click="increment(1)">修改计算模块中的 state </button>
<button @click="incrementWait(66)">异步修改计算模块中的 state </button>
</div>
<div>员工模块中的state 和 getters {{person}} --- {{changePerson}}</div>
<div>
<button @click="ADDPERSON('王五')">修改员工模块中的 state</button>
<button @click="addPersonWait('张三')">异步修改员工模块中的 state</button>
</div>
</template>
<script>
import {mapState, mapGetters, mapMutations, mapActions, useStore, } from 'vuex'
import {computed} from "vue";
export default {
setup() {
const store = useStore()
return {
num: computed(() => store.state.calculate.num),
bigSum: computed(() => store.getters["calculate/bigSum"]),
increment: (num) => store.commit('calculate/INCREMENT', num),
incrementWait: (num) => store.dispatch('calculate/incrementWait', num)
}
},
computed: {
// 使用指定模块中暴露的 state 数据
...mapState('staff', ['person']),
// 使用指定模块中暴露的 getters 数据
...mapGetters('staff', ['changePerson']),
},
methods: {
// 使用指定模块中暴露的 mutations 方法
...mapMutations('staff', ['ADDPERSON']),
// 使用指定的模块中暴露的 actions 方法
...mapActions('staff', ['addPersonWait'])
},
}
</script>

浙公网安备 33010602011771号