Vuex 是一个状态管理库,用于管理 Vue.js 应用程序中的共享状态。它可以帮助你在应用程序中保持数据的一致性和可预测性。
Vuex包括以下几个核心概念:
Vuex 官方文档
npm install vuex@next --save
这是一个单向数据流:
但是,当我们的应用遇到多个组件共享状态时,单向数据流的简洁性很容易被破坏:
Vuex 可以帮助我们管理共享状态,并附带了更多的概念和框架。这需要对短期和长期效益进行权衡。
如果您不打算开发大型单页应用,使用 Vuex 可能是繁琐冗余的。确实是如此——如果您的应用够简单,您最好不要使用 Vuex。一个简单的 store 模式就足够您所需了。但是,如果您需要构建一个中大型单页应用,您很可能会考虑如何更好地在组件外部管理状态,Vuex 将会成为自然而然的选择。
每一个 Vuex 应用的核心就是 store(仓库)。“store”基本上就是一个容器,它包含着你的应用中大部分的状态 (state)。
Vuex 和单纯的全局对象有以下两点不同:
用于存储应用程序的状态数据。
this.$store
访问store实例。$store.state
获取状态对象。支持Vuex
import store from "./store";
const app = createApp(App);
// 将 store 实例作为插件安装
app.use(store);
app.mount("#app");
定义store对象
import { createStore } from "vuex";
const store = createStore({
state() {
return {
count: 0,
};
}
});
export default store;
使用store
count: {{ $store.state.count }}
使用mapState
辅助函数可以简化代码,如:将{{ $store.state.count }}
简化为{{ count }}
。
count: {{ $store.state.count }}
{{ count }}
当映射的计算属性的名称与 state 的子节点名称相同时,也可以给 mapState
传一个字符串数组:
count: {{ $store.state.count }}
{{ count }}
{{ msg }}
computed
属性在Vue组件中只能有一个,可以使用对象扩展运算符兼容局部计算属性。
count: {{ $store.state.count }}
{{ count }}
{{ msg }}
{{ addNum }}
提供一种计算派生状态的方式,类似于Vue.js中的计算属性,例如对列表进行过滤并计数。
从 Vue 3.0 开始,getter的结果不再像计算属性一样会被缓存起来。
定义store对象
import { createStore } from "vuex";
const store = createStore({
state() {
return {
msg: "hello world",
};
},
getters: {
reverseMsg(state) {
return state.msg.split("").reverse().join("");
},
reverseMsgLength(state, getters) {
return getters.reverseMsg.length;
},
}
});
export default store;
在Vue中使用
{{ $store.getters.reverseMsg }}
{{ $store.getters.reverseMsgLength }}
可以通过mapGetters
辅助函数将getter映射到计算属性中。
{{ $store.getters.reverseMsg }}
{{ $store.getters.reverseMsgLength }}
{{ reverseMsg }}
{{ reverseMsgLength }}
用于修改状态的方法,但是只能进行同步操作。
$store.commit()
方法触发mutation函数。定义store对象
import { createStore } from "vuex";
const store = createStore({
state() {
return {
count: 0
};
},
mutations: {
//修改状态的方法
increment(state) {
state.count++;
},
},
});
export default store;
在Vue中使用
count: {{ $store.state.count }}
你可以向 store.commit
传入额外的参数,即 mutation 的载荷(payload)。
在store对象中定义
mutations: {
add(state, num) {
state.count += num;
},
},
使用
count: {{ $store.state.count }}
在store对象中定义
mutations: {
add2(state, payload) {
state.count += payload.num;
},
}
使用
count: {{ $store.state.count }}
this.$store.commit({
type: "add",
num: 20
})
定义mutation-type.js文件
export const ADD = "add";
在store对象中使用
import { createStore } from "vuex";
import { ADD } from "../mutation-type";
const store = createStore({
state() {
return {
count: 0
};
},
mutations: {
[ADD](state, num) {
state.count += num;
}
},
});
export default store;
用于提交mutations,可以进行异步操作。
$store.dispatch()
方法触发actions中定义的函数。在store对象中定义
import { createStore } from "vuex";
const store = createStore({
state() {
return {
count: 0
};
},
mutations: {
increment(state) {
state.count++;
}
},
actions: {
increment(context) {
context.commit("increment");
},
},
});
export default store;
在Vue中使用
count: {{ $store.state.count }}
**使用参数解构简化代码 **
actions: {
increment({ commit }) {
commit("increment");
},
},
在store对象中定义
import { createStore } from "vuex";
const store = createStore({
state() {
return {
count: 0,
};
},
mutations: {
increment(state) {
state.count++;
}
},
actions: {
incrementAsync({ commit }) {
setTimeout(() => {
commit("increment");
}, 1000);
},
},
});
export default store;
在Vue中使用
count: {{ $store.state.count }}
将store拆分为模块,每个模块都有自己的state、getters、mutations和actions。
新建user模块
const user = {
state() {
return {
userName: "xiaoming",
};
},
getters: {
userNameAge(state, getters, rootState) {
return state.userName + " 18岁";
},
},
mutations: {
updateUserName(state) {
state.userName = "小明";
},
},
};
export default user;
添加子模块
import { createStore } from "vuex";
import user from "./user";
const store = createStore({
modules: {
user,
},
});
export default store;
访问user模块
{{ $store.state.user.userName }}
{{ $store.getters.userNameAge }}
如果希望你的模块具有更高的封装度和复用性,你可以通过添加 namespaced: true
的方式使其成为带命名空间的模块。当模块被注册后,它的所有 getter、action 及 mutation 都会自动根据模块注册的路径调整命名。
新建Student的store对象
const student = {
namespaced: true, //开启命名空间
state() {
return {
userName: "xiaohei",
};
},
getters: {
userNameAge(state, getters, rootState) {
return state.userName + " 8岁";
},
},
mutations: {
updateStudentName(state) {
state.userName = "小黑";
},
},
};
export default student;
在Vue3中使用
student模块
{{ $store.state.student.userName }}
{{ $store.getters["student/userNameAge"] }}