主题
Vuex
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式 + 库。
https://vuex.vuejs.org/zh/index.html
vite创建一个项目
shell
npm init vite@latest my-vuex -- --template vue
cd my-vuex
cnpm install
安装
shell
cnpm install vuex@next --save
state
state -> 存放数据
src/store/index.js
js
import { createStore } from "vuex";
// 创建一个新的 store 实例
const store = createStore({
state() {
return {
count: 0,
};
},
});
export default store;
main.js
js
import { createApp } from "vue";
import App from "./App.vue";
const app = createApp(App);
// 将 store 实例作为插件安装
app.use(store);
app.mount("#app");
vue
<template>
<h1>{{ $store.state.count }}</h1>
<!-- 不建议这样操作数据 -->
<!-- <button @click="$store.state.count++">click</button> -->
</template>
mutation -> 同步修改数据
js
import { createStore } from "vuex";
// 创建一个新的 store 实例
const store = createStore({
state() {
return {
count: 0,
};
},
mutations: {
increment(state, value) {
if (value) {
console.log(value);
state.count += value;
} else {
state.count++;
}
},
},
});
export default store;
vue
<template>
<h1>{{ $store.state.count }}</h1>
<button @click="increment">click</button>
<button @click="increment2(5)">add 5</button>
</template>
<script>
export default {
methods: {
increment() {
// 提交一个变更
this.$store.commit("increment");
},
increment2(num) {
// 传值
this.$store.commit("increment", num);
},
},
};
</script>
getter
src/store/index.js
js
import { createStore } from "vuex";
// 创建一个新的 store 实例
const store = createStore({
state() {
return {
count: 0,
msg: "hello",
};
},
// 可以认为是 store 的计算属性
getters: {
reverMsg(state) {
return state.msg.split("").reverse().join("");
},
// 第二个参数可以拿到getters中的函数
reverMsgLength(state, getters) {
return getters.reverMsg.length;
},
},
mutations: {
increment(state, value) {
if (value) {
console.log(value);
state.count += value;
} else {
state.count++;
}
},
},
});
export default store;
vue
<template>
<h1>{{ $store.state.count }}</h1>
<button @click="increment">click</button>
<button @click="increment2(5)">add 5</button>
<h1>{{ $store.getters.reverMsg }}</h1>
<h1>{{ $store.getters.reverMsgLength }}</h1>
</template>
<script>
export default {
methods: {
increment() {
// 提交一个变更
this.$store.commit("increment");
},
increment2(num) {
// 传值
this.$store.commit("increment", num);
},
},
};
</script>
action
Action 类似于 mutation,不同在于:
- Action 提交的是 mutation,而不是直接变更状态。
- Action 可以包含任意异步操作。
src/store/index.js
js
import { createStore } from "vuex";
// 创建一个新的 store 实例
const store = createStore({
// 存放数据
state() {
return {
count: 0,
msg: "hello",
};
},
// 可以认为是 store 的计算属性
getters: {
reverMsg(state) {
return state.msg.split("").reverse().join("");
},
// 第二个参数可以拿到getters中的函数
reverMsgLength(state, getters) {
return getters.reverMsg.length;
},
},
// 同步变更数据
mutations: {
increment(state, value) {
if (value) {
console.log(value);
state.count += value;
} else {
state.count++;
}
},
updateMsg(state, value) {
state.msg = value;
},
},
// 和后台交互获取数据
actions: {
// context: 一个与store实例具有相同方法和属性的对象
getData(context, params) {
console.log(context);
console.log(params);
fetch("http://localhost/web/api/demo/test/time")
.then((res) => {
return res.json();
})
.then((res) => {
console.log(res);
context.commit("updateMsg", res.data);
});
},
},
});
export default store;
vue
<template>
<h1>{{ $store.state.count }}</h1>
<button @click="increment">click</button>
<button @click="increment2(5)">add 5</button>
<h1>{{ $store.getters.reverMsg }}</h1>
<h1>{{ $store.getters.reverMsgLength }}</h1>
<button @click="getData">getData</button>
</template>
<script>
export default {
methods: {
increment() {
// 提交一个变更
this.$store.commit("increment");
},
increment2(num) {
// 传值
this.$store.commit("increment", num);
},
getData() {
this.$store.dispatch("getData", "666");
},
},
};
</script>
辅助函数
mapState, mapMutations, mapGetters, mapActions
vue
<template>
<h2>{{ getNum }}</h2>
<h2>{{ count }}</h2>
<h2>{{ msg }}</h2>
<h2>{{ reverMsg }}</h2>
<button @click="addNum">{{ count }}</button>
</template>
<script>
import { mapState, mapMutations, mapGetters, mapActions } from "vuex";
export default {
data() {
return {
num: 2,
};
},
// computed: mapState({
// // count: (state) => state.count
// count: "count",
// }),
// computed: mapState(["count", "msg"]),
// 与局部计算属性混合使用
computed: {
getNum() {
return this.num * 2;
},
addNum() {
this.increment(10);
},
...mapState(["count", "msg"]),
...mapGetters(["reverMsg"]),
},
methods: {
...mapMutations(["increment"]),
...mapActions(["getData"]),
},
mounted() {
this.getData();
console.log(this.count);
console.log(this.msg);
},
};
</script>
js
import { createStore } from "vuex";
import user from "./user";
// 创建一个新的 store 实例
const store = createStore({
modules: {
a: user,
},
// 存放数据
state() {
return {
count: 0,
msg: "hello",
};
},
// 可以认为是 store 的计算属性
getters: {
reverMsg(state) {
return state.msg.split("").reverse().join("");
},
// 第二个参数可以拿到getters中的函数
reverMsgLength(state, getters) {
return getters.reverMsg.length;
},
},
// 同步变更数据
mutations: {
increment(state, value) {
if (value) {
console.log(value);
state.count += value;
} else {
state.count++;
}
},
updateMsg(state, value) {
state.msg = value;
},
},
// 和后台交互获取数据
actions: {
// context: 一个与store实例具有相同方法和属性的对象
getData(context, params) {
console.log(context);
console.log(params);
fetch("http://localhost/web/api/demo/test/time")
.then((res) => {
return res.json();
})
.then((res) => {
console.log(res);
context.commit("updateMsg", res.data);
});
},
},
});
export default store;
module
将 store 分割成模块(module)。 每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块
js
const user = {
state: () => ({
name: "Patrick",
}),
getters: {
// rootState: 根节点状态
getName(state, getters, rootState) {
console.log(getters);
console.log(rootState);
return state.name + "666";
},
},
};
export default user;
js
import { createStore } from "vuex";
import user from "./user";
// 创建一个新的 store 实例
const store = createStore({
modules: {
a: user,
},
// 存放数据
state() {
return {
count: 0,
msg: "hello",
};
},
// 可以认为是 store 的计算属性
getters: {
reverMsg(state) {
return state.msg.split("").reverse().join("");
},
// 第二个参数可以拿到getters中的函数
reverMsgLength(state, getters) {
return getters.reverMsg.length;
},
},
// 同步变更数据
mutations: {
increment(state, value) {
if (value) {
console.log(value);
state.count += value;
} else {
state.count++;
}
},
updateMsg(state, value) {
state.msg = value;
},
},
// 和后台交互获取数据
actions: {
// context: 一个与store实例具有相同方法和属性的对象
getData(context, params) {
console.log(context);
console.log(params);
fetch("http://localhost/web/api/demo/test/time")
.then((res) => {
return res.json();
})
.then((res) => {
console.log(res);
context.commit("updateMsg", res.data);
});
},
},
});
export default store;
vue
<template>
<h1>{{ $store.state.count }}</h1>
<button @click="increment">click</button>
<button @click="increment2(5)">add 5</button>
<h1>{{ $store.getters.reverMsg }}</h1>
<h1>{{ $store.getters.reverMsgLength }}</h1>
<button @click="getData">getData</button>
<hr />
<h1>{{ $store.getters.getName }}</h1>
<h1>{{ $store.state.a.name }}</h1>
</template>
<script>
export default {
methods: {
increment() {
// 提交一个变更
this.$store.commit("increment");
},
increment2(num) {
// 传值
this.$store.commit("increment", num);
},
getData() {
this.$store.dispatch("getData", "666");
},
},
};
</script>
命名空间 namespaced: true
js
const user = {
namespaced: true,
state: () => ({
name: "Patrick",
}),
getters: {
// rootState: 根节点状态
getName(state, getters, rootState) {
console.log(rootState);
console.log(getters);
return state.name + "666";
},
},
};
export default user;
vue
<!-- <h1>{{ $store.getters.getName }}</h1> -->
<h1>{{ $store.getters["a/getName"] }}</h1>