什么是Vuex
全局状态管理插件
Vuex是一个专为Vue.js应用程序开发的状态管理模式. 它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化,Vuex也集成到Vue的官方调试工具devtools extension,提供了诸如零配置的 time-travel 调试、状态快照导入导出等高级调试功能
Vuex 核心概念
单向数据流
什么是单向数据流呢?它指的是通过一定的规则去改变数据,数据触发视图的更新,通过视图中的方法去触发数据的更新,形成一个闭环。如下图所示:
但事与愿违,复杂应用里会遇到多个组件共享同状态,不同视图的行为变更同一个状态等等问题,这时单向数据流就会被破坏。
Vuex 的出现就是为了解决这类复杂场景应用,那么我们在看看一张官方提供的流程图:
Vuex如何存储数据
Vuex 使用一个名为 "store" 的中央化存储来管理应用程序的状态。存储中的数据被称为 "state",它是一个响应式的对象。你可以在 store 中定义和访问 state,并使用 mutations 来修改 state。
Vuex 的基本流程:
// main.js
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
const store = new Vuex.Store({
// 1.store
// 在 Vue 入口页构造 Vue 实例的时候引入 store 之后,
// 可以在组件中通过this.$store.state 拿到。
state: {
count: 0 // 初始的 count 状态为 0
},
// 2.mutations
// 我们修改 State 状态,需要触发一些方法,这些方法就放在 mutations 属性中,
// mutations 属性中的方法接受 2 个参数,第一个参数是state,内部包含所有状态值。
// 第二个参数为提交载荷(Playload),
// 也就是在外部通过 store.commit方法触发 mutations 时额外带入的值。
mutations: {
increment(state) {
state.count++; // 增加 count 状态
},
decrement(state) {
state.count--; // 减少 count 状态
}
},
// 3.action
// 其实 Action 很好理解,它与 Mutation 类似,
// 只不过 Action 是提交 mutation 而不是直接改变状态,
// 并且 Action 被赋予异步的能力,也就是能在里面请求异步数据之后再触发状态的更新。
actions: {
incrementAsync(context) {
setTimeout(() => {
context.commit('increment'); // 异步地触发 increment mutation
}, 1000);
}
},
getters: {
doubleCount(state) {
return state.count * 2; // 计算 count 的两倍
}
}
});
new Vue({
store,
// ...
}).$mount('#app');
<!-- MyComponent.vue -->
<template>
<div>
<!-- 访问 count 状态 -->
<p>Count: {{ count }}</p>
<!-- 访问 doubleCount getter -->
<p>Double Count: {{ doubleCount }}</p>
<!-- 调用 increment mutation -->
<button @click="increment">Increment</button>
<!-- 调用 decrement mutation -->
<button @click="decrement">Decrement</button>
<!-- 调用 incrementAsync action -->
<button @click="incrementAsync">Increment Async</button>
</div>
</template>
<script>
import { mapState, mapGetters, mapMutations, mapActions } from 'vuex';
export default {
computed: {
...mapState(['count']), // 将 count 状态映射为计算属性
...mapGetters(['doubleCount']) // 将 doubleCount getter 映射为计算属性
},
methods: {
increment() {
this.$store.commit('increment');
},
decrement() {
this.$store.commit('decrement');
}
},
created() {
// 组件创建时执行的逻辑
console.log('Component created');
},
watch: {
count(newCount, oldCount) {
// 监听 count 的变化
console.log(`count changed from ${oldCount} to ${newCount}`);
}
}
}
</script>
触发 Vuex store 中的 action 事件时,在 mothods 使用以下几种方式:
1.使用 mapActions
辅助函数将 action 映射为组件方法:
import { mapActions } from 'vuex';
methods: {
...mapActions(['incrementAsync']),
increment() {
this.incrementAsync();
}
}
2.直接通过 store.dispatch 方法来触发 action 事件:
methods: {
incrementAsync() {
this.$store.dispatch('incrementAsync');
}
}
3.使用对象风格的提交来触发 action 事件 :
methods: {
incrementAsync() {
this.$store.commit({
type: 'incrementAsync',
amount: 5
});
}
}
4.使用辅助函数 createAction 创建可以直接触发 action 的函数
import { createAction } from 'vuex';
const incrementAsync = createAction('incrementAsync');
methods: {
increment() {
this.$store.dispatch(incrementAsync());
}
}
通过这种方式,我们可以在 Vuex store 中定义和访问状态,并通过 mutations 来修改状态。这种集中化的状态管理方式使得状态的变化更可控,组件之间共享状态更加方便。
这样存储数据的好处:
-
中央化的数据管理:Vuex 将应用程序的状态存储在一个中央化的地方,即 Vuex store。这意味着所有的组件都可以从同一个地方访问和修改状态,而不需要通过传递 props 或事件来传递数据。这种集中式的数据管理简化了组件之间的通信,提高了代码的可维护性和可扩展性。
-
响应式的数据更新:Vuex 的 state 是响应式的,当 state 发生变化时,订阅了该状态的组件会自动更新。这意味着你不需要手动追踪和同步状态的变化,而是让 Vue 框架自动处理更新。这简化了状态管理的复杂性,减少了手动编写代码的工作量。
-
可预测的状态变化:在 Vuex 中,所有对 state 的修改都必须通过 mutations 来进行。这样做的好处是,你可以清楚地追踪到状态的变化,因为所有的修改都集中在 mutations 中。这使得状态的变化变得可预测,更易于调试和维护。
-
严格的状态变更规则:Vuex 强制实施了一些规则,以确保状态的变化是可跟踪和可控的。例如,通过 mutations 修改 state 是同步的,这样可以避免异步操作带来的状态不一致性。此外,Vuex 还提供了严格模式,用于检测对 state 的直接修改,以帮助开发者遵循更好的状态管理实践。
-
开发者工具支持:Vuex 提供了强大的开发者工具,用于调试和监控应用程序的状态变化。你可以轻松地查看和追踪 state 的变化历史,甚至可以回溯到之前的状态。这对于调试和排查问题非常有帮助,帮助开发者更好地理解应用程序的状态变化。
总结:
Vuex 可以帮助我们管理好共享状态,但是也不是所有的应用都要用上 Vuex,需要对项目的短期和长期效益进行权衡,如果不是开发大型的单页应用,就不必使用 Vuex,因为这样会让项目变得繁琐冗余,简单的小应用可以通过结合 localStorage 封装一个简单的状态管理插件。