blog
blog copied to clipboard
Vuex 使用入门
Vuex 是什么?
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。Vuex 也集成到 Vue 的官方调试工具 devtools extension,提供了诸如零配置的 time-travel 调试、状态快照导入导出等高级调试功能。
- 状态共享,非父子组件通信
- 数据快照,缓存数据,避免重复请求,影响用户体验
- dev 环境下 time-travel 调试
实现模式
利用 Vue.js 的细粒度数据响应机制来进行高效的状态更新
流程解读
mutation 必须同步执行, Action ,我们则可以在 action 内部执行异步操作:
同步流程:vue component -> commit 触发 mutations 定义的方法 -> store.state -> render
// 如果在模块化构建系统中,请确保在开头调用了 Vue.use(Vuex)
const store = new Vuex.Store({
state: {
count: 0,
},
mutations: {
increment(state) {
state.count++;
},
},
});
触发 mutations
store.commit("increment");
异步流程: vue component -> dispatch 触发 actions 定义的方法 -> commit 触发 mutations 定义的方法 -> store.state -> render
const store = new Vuex.Store({
state: {
count: 0,
},
mutations: {
increment(state) {
state.count++;
},
},
actions: {
increment(context) {
context.commit("increment");
},
},
});
辅助函数
- mapState
- mapMutations
- mapGetter
- mapActions
实例使用
vuex 注册:
import Vue from "vue";
import Vuex from "vuex";
import createPersistedState from "vuex-persistedstate";
import prdConfig from "../../prd-config";
import mutations from "./mutations";
import actions from "./actions";
import todos from "./modules/todos";
Vue.use(Vuex);
const store = () =>
new Vuex.Store({
modules: {
todos,
},
state: {
env: "dev",
},
mutations,
actions,
plugins: [
createPersistedState({
storage: window.sessionStorage, // 持久化默认使用 localStorage
key: `vuex_${prdConfig.productCode}`,
}),
],
});
export default store;
模块化管理使用:
import { getTodoData } from "@/plugins/http/api";
import Vue from "vue";
const todos = {
namespaced: true,
state: () => ({
todos: [],
filterType: "all",
}),
getters: {
displayTodos({ todos, filterType }, getters, rootState, rootGetters) {
return todos.filter((v) => v.type === filterType);
},
doneTodosCount({ todos }) {
return todos.filter((v) => v.isCompleted).length;
},
},
mutations: {
setFilterType(state, val) {
state.filter = val;
},
setTodo(state, obj) {
state.todos = obj;
},
addTodo(state, obj) {
state.todos = state.todos.concat([obj]);
},
clearAllCompleted(state, obj) {
state.todos = state.todos.filter((v) => !v.isCompleted);
},
},
actions: {
async initTodo(
{ commit, dispatch, getters, rootState, state },
payload = {}
) {
try {
let { code, message, data } = await getTodoData(payload);
if (code === "0") {
if (data) {
commit("setTodo", data);
// dispatch('otherModule/updateTODO', data, {root: true});
}
} else {
Vue.prototype.$toast({
text: message,
});
}
} catch (error) {
console.log(error);
Vue.prototype.$toast({ text: "查询 todos 失败,请稍后重试..." });
}
},
},
};
export default todos;
组件中使用:
import { mapActions, mapState, mapMutations, mapGetters } from "vuex";
export default {
name: "TodoList",
computed: {
...mapState({
todos: (state) => state.todos.todos,
filterType: (state) => state.todos.filterType,
}),
...mapGetters({
displayTodos: "todos/displayTodos",
doneTodosCount: "todos/doneTodosCount",
}),
},
methods: {
...mapMutations("todos", ["addTodo", "clearAllCompleted"]),
...mapActions("todos", ["initTodo"]),
},
};