【笔记】Vuex学习笔记

前言

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式 + 库。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。(官网

通过Vuex实现对Vue项目的状态管理

下载依赖

1
npm install vuex

Store

定义Store

src/store/index.js
1
2
3
4
5
6
7
8
9
10
11
import { createStore } from "vuex"

const store = createStore({
state: function () {
return {
key: "value"
}
}
});

export default store;

挂载Store

src/main.js
1
2
3
4
5
6
7
import { createApp } from "vue"
import store from "./store/index.js"
import App from "./App.vue"

const app = createApp(App);
app.use(store);
app.mount("#app");

获取Store中的State

通过template获取Store中的State

1
2
3
<template>
{{ $store.state.key }}
</template>

通过script获取Store中的State

OptionsAPI
1
2
3
4
5
6
7
<script>
export default {
created: function () {
console.log(this.$store.state.key); // "value"
}
}
</script>
CompositionAPI
1
2
3
4
5
6
<script setup>
import { useStore } from "vuex"

const store = useStore();
console.log(store.state.key); // "value"
</script>

映射为计算属性

OptionsAPI

  • 通过mapState()将多个状态映射为函数数组,通过展开运算符赋值给计算属性
1
2
3
4
5
6
7
8
9
10
11
12
13
<template>
{{ key }}
</template>

<script>
import { mapState } from "vuex"

export default {
computed: {
...mapState(["key"])
}
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<template>
{{ key }}
</template>

<script>
import { mapState } from "vuex"

export default {
computed: {
...mapState({
key: state => state.key
})
}
}
</script>

CompositionAPI

1
2
3
4
5
6
7
8
9
10
11
12
<template>
{{ key }}
</template>

<script setup>
import { computed } from "vue"
import { useStore } from "vuex"

const store = useStore();

const key = computed(() => store.state.key);
</script>

Getters

  • 通过Getters获取Store中的值

定义Getters

  • 在Store对象中通过getters属性定义Getters
src/store/index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import { createStore } from "vuex"

const store = createStore({
state: function () {
return {
key: "value"
}
},
getters: {
getKey: function (state) {
return state.key;
},
getOther: function (state, getters) {
return getters.getKey();
},
getFn: function (state) {
return function (key) {
return key;
};
}
}
});

export default store;

挂载Store

src/main.js
1
2
3
4
5
6
7
import { createApp } from "vue"
import store from "./store/index.js"
import App from "./App.vue"

const app = createApp(App);
app.use(store);
app.mount("#app");

获取Getters的返回值

通过template获取Getters的返回值

1
2
3
4
5
<template>
{{ $store.getters.getkey }}
{{ $store.getters.getOther }}
{{ $store.getters.getFn("value") }}
</template>

通过script获取Getters的返回值

OptionsAPI
1
2
3
4
5
6
7
<script>
export default {
created: function () {
console.log(this.$store.getters.getkey); // "value"
}
}
</script>
CompositionAPI
1
2
3
4
5
6
<script setup>
import { useStore } from "vuex"

const store = useStore();
console.log(store.getters.getkey); // "value"
</script>

映射为计算属性

OptionsAPI

  • 通过mapGetters()将多个状态映射为函数数组,通过展开运算符赋值给计算属性
1
2
3
4
5
6
7
8
9
10
11
12
13
<template>
{{ key }}
</template>

<script>
import { mapGetters } from "vuex"

export default {
computed: {
...mapGetters(["getKey"])
}
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<template>
{{ key }}
</template>

<script>
import { mapGetters } from "vuex"

export default {
computed: {
...mapGetters({
key: getters => getters.getKey
})
}
}
</script>

CompositionAPI

1
2
3
4
5
6
7
8
9
10
11
12
<template>
{{ key }}
</template>

<script setup>
import { computed } from "vue"
import { useStore } from "vuex"

const store = useStore();

const key = computed(() => store.getters.getKey);
</script>

Mutation

  • 通过Mutation修改Store中的值
  • Mutation中不要进行异步操作

定义Mutation

  • 在Store对象中通过mutations属性定义Mutation
src/store/index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import { createStore } from "vuex"

const store = createStore({
state: function () {
return {
key: "value"
}
},
mutations: {
setKey: function (state) {
state.key = "value";
}
}
});

export default store;
src/store/index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import { createStore } from "vuex"

const store = createStore({
state: function () {
return {
key: "value"
}
},
mutations: {
setKey: function (state, payload) {
state.key = payload;
}
}
});

export default store;

挂载Store

src/main.js
1
2
3
4
5
6
7
import { createApp } from "vue"
import store from "./store/index.js"
import App from "./App.vue"

const app = createApp(App);
app.use(store);
app.mount("#app");

提交Mutation

  • 通过提交Mutation以修改Store中的值

OptionsAPI

1
2
3
4
5
6
7
8
9
10
11
12
13
<template>
<div v-on:click="fn"></div>
</template>

<script>
export default {
methods: {
fn: function () {
this.$store.commit("setKey");
}
}
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
<template>
<div v-on:click="fn"></div>
</template>

<script>
export default {
methods: {
fn: function () {
this.$store.commit("setKey", "value");
}
}
}
</script>

CompositionAPI

1
2
3
4
5
6
7
8
9
10
11
12
13
<template>
<div v-on:click="fn"></div>
</template>

<script setup>
import { useStore } from "vuex"

const store = useStore();

function fn() {
store.commit("setKey");
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
<template>
<div v-on:click="fn"></div>
</template>

<script setup>
import { useStore } from "vuex"

const store = useStore();

function fn() {
store.commit("setKey", "value");
}
</script>

映射为方法

OptionsAPI

1
2
3
4
5
6
7
8
9
10
11
12
13
<template>
<div v-on:click="setKey"></div>
</template>

<script>
import { mapMutations } from "vuex"

export default {
methods: {
...mapMutations(["setKey"])
}
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
<template>
<div v-on:click="setKey('value')"></div>
</template>

<script>
import { mapMutations } from "vuex"

export default {
methods: {
...mapMutations(["setKey"])
}
}
</script>

CompositionAPI

1
2
3
4
5
6
7
8
9
10
11
<template>
<div v-on:click="fn"></div>
</template>

<script setup>
import { mapMutations, useStore } from "vuex"

const store = useStore();

const fn = mapMutations(["setKey"])["setKey"].bind({ $store: store });
</script>
1
2
3
4
5
6
7
8
9
10
11
<template>
<div v-on:click="fn('value')"></div>
</template>

<script setup>
import { mapMutations, useStore } from "vuex"

const store = useStore();

const fn = mapMutations(["setKey"])["setKey"].bind({ $store: store });
</script>

Action

  • 通过在Action中提交Mutation以修改Store中的值
  • Action中可以进行异步操作

定义Action

src/store/index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import { createStore } from "vuex"

const store = createStore({
state: function () {
return {
key: "value"
}
},
mutations: {
setKey: function (state) {
state.key = "value";
}
},
actions: {
setKeyAction: function (context) {
console.log(context.state);
console.log(context.getters);
context.commit("setKey");
}
}
});

export default store;
src/store/index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import { createStore } from "vuex"

const store = createStore({
state: function () {
return {
key: "value"
}
},
mutations: {
setKey: function (state, payload) {
state.key = payload;
}
},
actions: {
setKeyAction: function (context, payload) {
context.commit("setKey", payload);
}
}
});

export default store;

挂载Store

src/main.js
1
2
3
4
5
6
7
import { createApp } from "vue"
import store from "./store/index.js"
import App from "./App.vue"

const app = createApp(App);
app.use(store);
app.mount("#app");

派发Action

  • 通过提交Mutation以修改Store中的值

OptionsAPI

1
2
3
4
5
6
7
8
9
10
11
12
13
<template>
<div v-on:click="fn"></div>
</template>

<script>
export default {
methods: {
fn: function () {
this.$store.dispatch("setKeyAction");
}
}
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
<template>
<div v-on:click="fn"></div>
</template>

<script>
export default {
methods: {
fn: function () {
this.$store.dispatch("setKeyAction", "value");
}
}
}
</script>

CompositionAPI

1
2
3
4
5
6
7
8
9
10
11
12
13
<template>
<div v-on:click="fn"></div>
</template>

<script setup>
import { useStore } from "vuex"

const store = useStore();

function fn() {
store.dispatch("setKeyAction");
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
<template>
<div v-on:click="fn"></div>
</template>

<script setup>
import { useStore } from "vuex"

const store = useStore();

function fn() {
store.dispatch("setKeyAction", "value");
}
</script>

映射为方法

OptionsAPI

1
2
3
4
5
6
7
8
9
10
11
12
13
<template>
<div v-on:click="setKeyAction"></div>
</template>

<script>
import { mapActions } from "vuex"

export default {
methods: {
...mapActions(["setKeyAction"])
}
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
<template>
<div v-on:click="setKeyAction('value')"></div>
</template>

<script>
import { mapActions } from "vuex"

export default {
methods: {
...mapActions(["setKeyAction"])
}
}
</script>

CompositionAPI

1
2
3
4
5
6
7
8
9
10
11
<template>
<div v-on:click="fn"></div>
</template>

<script setup>
import { mapActions, useStore } from "vuex"

const store = useStore();

const fn = mapActions(["setKeyAction"])["setKeyAction"].bind({ $store: store });
</script>
1
2
3
4
5
6
7
8
9
10
11
<template>
<div v-on:click="fn('value')"></div>
</template>

<script setup>
import { mapActions, useStore } from "vuex"

const store = useStore();

const fn = mapActions(["setKeyAction"])["setKeyAction"].bind({ $store: store });
</script>

Module

不使用命名空间

  • Getters、Mutation、Action都会合并到根命名空间内

定义Module

src/store/modules/home.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
export default {
state: function () {
return {
key: "value"
}
},
getters: {
getKey: function (state, getters, rootState) {
return state.key;
}
},
mutations: {
setKey: function (state) {
state.key = "value";
}
},
actions: {
setKeyAction: function (context) {
context.commit("setKey");
}
}
}
src/store/index.js
1
2
3
4
5
6
7
import HomeModule from "./module/home.js"

const store = createStore({
modules: {
home: HomeModule
}
});

获取Store中的状态

1
2
3
<template>
{{ $store.state.home.key }}
</template>

获取Getters的返回值

1
2
3
<template>
{{ $store.getters.getkey }}
</template>

提交Mutation

1
2
3
4
5
6
7
8
9
10
11
12
13
<template>
<div v-on:click="fn"></div>
</template>

<script>
export default {
methods: {
fn: function () {
this.$store.commit("setKey");
}
}
}
</script>

派发Action

1
2
3
4
5
6
7
8
9
10
11
12
13
<template>
<div v-on:click="fn"></div>
</template>

<script>
export default {
methods: {
fn: function ({ state, commit, rootState}) {
this.$store.dispatch("setKeyAction");
}
}
}
</script>

使用命名空间

  • Getters、Mutation、Action会放到模块的命名空间内

定义Module

namespaced:是否启用命名空间

false:缺省值,禁用
true:启用

src/store/modules/home.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
export default {
namespaced: true,
state: function () {
return {
key: "value"
}
},
getters: {
getKey: function (state, getters, rootState) {
return state.key;
}
},
mutations: {
setKey: function (state) {
state.key = "value";
}
},
actions: {
setKeyAction: function (context) {
context.commit("setKey");
}
}
}
src/store/index.js
1
2
3
4
5
6
7
import HomeModule from "./module/home.js"

const store = createStore({
modules: {
home: HomeModule
}
});

获取Store中的状态

1
2
3
<template>
{{ $store.state.home.key }}
</template>

获取Getters的返回值

1
2
3
<template>
{{ $store.getters["home/getkey"] }}
</template>

提交Mutation

1
2
3
4
5
6
7
8
9
10
11
12
13
<template>
<div v-on:click="fn"></div>
</template>

<script>
export default {
methods: {
fn: function () {
this.$store.commit("home/setKey");
}
}
}
</script>
提交根命名空间的Mutation
1
2
3
4
5
6
7
8
9
10
11
12
13
<template>
<div v-on:click="fn"></div>
</template>

<script>
export default {
methods: {
fn: function () {
this.$store.commit("setKey", null, { root: true });
}
}
}
</script>

派发Action

1
2
3
4
5
6
7
8
9
10
11
12
13
<template>
<div v-on:click="fn"></div>
</template>

<script>
export default {
methods: {
fn: function ({ state, commit, rootState}) {
this.$store.dispatch("home/setKeyAction");
}
}
}
</script>
派发根命名空间的Action
1
2
3
4
5
6
7
8
9
10
11
12
13
<template>
<div v-on:click="fn"></div>
</template>

<script>
export default {
methods: {
fn: function ({ state, commit, rootState}) {
this.$store.dispatch("setKeyAction", null, { root: true });
}
}
}
</script>

完成