Vue状态管理器
1.什么是vuex?
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。Vuex 的状态存储是响应式的,当组件从 store 中读取状态时,如果状态发生变化,那么相应的组件也会得到高效更新。
2.使用vuex的原因
- 管理共享状态:随着项目的复杂性增加,多个组件可能需要共享同一份数据。Vuex 允许我们将这些数据集中存储在一个地方(即 store),并提供了统一的接口来访问和修改这些数据,从而简化了组件之间的数据共享和管理。
- 响应式状态更新:Vuex 的状态存储是响应式的,当组件从 store 中读取状态时,如果状态发生变化,那么相应的组件也会得到高效更新。这确保了组件的状态始终与 Vuex store 中的状态保持同步。
- 简化复杂应用的状态管理:对于中大型单页应用,状态管理可能会变得非常复杂。Vuex 提供了简洁的 API 和清晰的模式,帮助开发者更好地组织和维护应用的状态。
- 避免直接操作全局对象:在 Vue 应用中,直接操作全局对象可能会导致状态不一致和难以调试的问题。Vuex 通过强制开发者通过明确的方式(即通过提交 mutation)来修改状态,避免了这些问题。
- 插件支持:Vuex 支持插件系统,这使得开发者可以扩展 Vuex 的功能,例如添加日志记录、持久化等功能。
- 需要注意的是,虽然 Vuex 提供了强大的状态管理功能,但它也附带了额外的概念和框架。对于简单的应用,使用 Vuex 可能是繁琐冗余的。因此,在决定是否使用 Vuex 时,需要权衡其带来的好处和复杂性。
3.vuex的核心概念
(1)State: 存放基本数据 ----辅助函数mapState: 当一个组件需要获取多个状态时候,将这些状态都声明为计算属性会有些重复和冗余。为了解决这个问题,我们可以使用 mapState 辅助函数帮助我们生成计算属性,让你少按几次键。
(2)getters:是从store中的state派生出来的状态,专门来计算state中的数据,相当于state中数据的计算属性 —辅助函数mapGetters辅助函数: mapGetters 辅助函数仅仅是将 store 中的 getters 映射到局部计算属性,与state类似
(3)actions: 是专门操作异步请求的数据和业务逻辑的地方,它不能直接变更state中的状态,而是通过commit来调用mutations里的方法来改变state里的数据。 —辅助函数mapActions 将组建的methods映射为store.dispath调用
(4)mutations:提交mutions是更改Vuex中的状态的唯一方法。mutations必须是同步的,如果要异步需要使用actions。每一个mutations都有一个字符串作为第一个参数,提交载荷作为第二个参数。 —辅助函数mapMutations 将组建中的methods映射为store.commit调用。
(5)Modules:使用单一状态树,导致应用的所有状态几种到一个很大的对象,但是,当应用变得很大时,store对象会变得臃肿不堪,为了解决以上问题,Vuex允许我们将store分割到模块(modules)。每个模块拥有自己的state、mutations、avtions、grtters。
4.vuex在vue-cli中的应用
在 Vue CLI 创建的项目中集成 Vuex 是非常常见的做法,因为这有助于管理跨多个组件的状态。下面是在 Vue CLI 项目中设置和使用 Vuex 的步骤:
1. 安装 Vuex
如果还没有安装 Vuex,可以通过 npm 或 yarn 将其添加到项目中:
npm install vuex --save
# 或者
yarn add vuex
2. 创建 Vuex Store
在 src
目录下创建一个新的 store
目录,并在该目录下创建一个 index.js
文件,用于定义 Vuex store。
// src/store/index.js
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
export default new Vuex.Store({
state: {
// 定义全局状态
},
mutations: {
// 定义修改状态的方法
},
actions: {
// 定义异步操作
},
getters: {
// 定义获取状态的方法
},
modules: {
// 定义模块
}
});
3. 在 Vue CLI 项目中注册 Vuex Store
接下来,需要在项目的入口文件 main.js
中引入并注册 Vuex store。
// src/main.js
import Vue from 'vue';
import App from './App.vue';
import store from './store'; // 引入 Vuex store
new Vue({
store, // 注册 Vuex store
render: h => h(App),
}).$mount('#app');
4. 在组件中使用 Vuex
一旦 Vuex store 被注册,你就可以在任何组件中通过 this.$store
访问它。不过,为了保持代码的清晰和可维护性,通常建议使用 mapState
、mapMutations
、mapActions
和 mapGetters
这些辅助函数来将 Vuex 的状态和方法映射到组件的计算属性和方法中。
// 在组件中使用 mapState
import { mapState } from 'vuex';
export default {
computed: {
...mapState(['yourState']) // 将 state 中的 yourState 映射到组件的 computed 属性
}
}
// 在组件中使用 mapMutations
import { mapMutations } from 'vuex';
export default {
methods: {
...mapMutations(['yourMutation']), // 将 mutation 中的 yourMutation 映射到组件的方法
someMethod() {
this.yourMutation(payload); // 直接调用映射的方法
}
}
}
// 在组件中使用 mapActions
import { mapActions } from 'vuex';
export default {
methods: {
...mapActions(['yourAction']), // 将 action 中的 yourAction 映射到组件的方法
someMethod() {
this.yourAction(payload); // 直接调用映射的方法
}
}
}
// 在组件中使用 mapGetters
import { mapGetters } from 'vuex';
export default {
computed: {
...mapGetters(['yourGetter']) // 将 getter 中的 yourGetter 映射到组件的 computed 属性
}
}
5. 模块化 Vuex Store(可选)
如果 Vuex store 中的状态和方法变得非常复杂,可以考虑使用模块(modules)来将其拆分成多个独立的模块。每个模块可以拥有自己的 state、mutations、actions 和 getters。
// src/store/index.js
export default new Vuex.Store({
modules: {
moduleA: {
// ... moduleA 的 state, mutations, actions, getters
},
moduleB: {
// ... moduleB 的 state, mutations, actions, getters
}
}
});
在组件中使用模块化的 Vuex store 时,你需要通过模块名来访问其状态和方法。
// 在组件中使用模块化的 Vuex
import { mapState, mapMutations, mapActions, mapGetters } from 'vuex';
export default {
computed: {
...mapState('moduleA', ['yourState']), // 第一个参数是模块名
...mapGetters('moduleB', ['yourGetter'])
},
methods: {
...mapMutations('moduleA', ['yourMutation']),
...mapActions('moduleB', ['yourAction'])
}
}
以上就是在 Vue CLI 项目中集成和使用 Vuex 的基本步骤。根据你的项目需求,你可能还需要考虑如何组织和管理 Vuex store 中的状态和方法,以及
5.组件中使用 vuex 的值和修改值的地方?
在 Vue 组件中使用 Vuex 的值以及修改这些值的地方通常涉及到以下几个步骤:
-
从 Vuex Store 中映射状态到组件
使用
mapState
辅助函数将 Vuex store 中的状态映射到组件的计算属性中。这样,组件就可以像访问本地数据一样访问这些状态。import { mapState } from 'vuex'; export default { computed: { // 使用 mapState 将 Vuex 中的状态映射到组件 ...mapState(['yourState']) // 或者使用对象形式映射具有不同名称的状态 // ...mapState({ // localStateName: state => state.yourState // }) } }
-
在组件中调用 Vuex 的 mutations
当需要修改 Vuex store 中的状态时,你应该通过调用 mutations 来完成。mutations 是 Vuex 中唯一允许修改状态的方法。在组件中,你可以使用
mapMutations
来映射这些 mutations。import { mapMutations } from 'vuex'; export default { methods: { // 使用 mapMutations 将 Vuex 中的 mutations 映射到组件的方法 ...mapMutations(['yourMutation']), // 或者在方法中直接调用 this.$store.commit someMethod() { this.$store.commit('yourMutation', payload); } } }
-
在组件中调用 Vuex 的 actions
Actions 是用于处理异步操作或复杂逻辑的方法,它们可以包含任意异步操作,并通过提交 mutations 来间接修改状态。在组件中,你可以使用
mapActions
来映射这些 actions。import { mapActions } from 'vuex'; export default { methods: { // 使用 mapActions 将 Vuex 中的 actions 映射到组件的方法 ...mapActions(['yourAction']), // 或者在方法中直接调用 this.$store.dispatch someMethod() { this.$store.dispatch('yourAction', payload); } } }
-
使用 Vuex 的 getters
Getters 可以认为是 store 的计算属性。就像组件内的计算属性一样,getter 的返回值会根据它的依赖被缓存起来,并且只有当它的依赖值发生改变时才会被重新计算。在组件中,你可以使用
mapGetters
来映射这些 getters。import { mapGetters } from 'vuex'; export default { computed: { // 使用 mapGetters 将 Vuex 中的 getters 映射到组件的计算属性 ...mapGetters(['yourGetter']) // 或者使用对象形式映射具有不同名称的 getter // ...mapGetters({ // localComputedName: state => state.getters.yourGetter // }) } }
这些步骤说明了在 Vue 组件中如何使用 Vuex 的状态、mutations、actions 和 getters。通过合理地使用这些功能,你可以确保组件之间的状态管理是集中、可预测和可维护的。
6.在vuex中使用异步修改
在 Vuex 中,异步操作并不被直接支持在 mutations 中,因为 mutations 必须同步执行。为了处理异步操作,我们通常会在 actions 中进行。Actions 类似于 mutations,但它们可以包含任意异步操作。
以下是使用 Vuex 处理异步操作的步骤:
- 在 actions 中定义异步操作
在你的 Vuex store 中,你可以在 actions
属性中定义一个异步函数。这个异步函数可以包含 API 调用、setTimeout 或其他任何异步操作。
const store = new Vuex.Store({
state: {
// 定义你的状态
},
mutations: {
// 定义同步更新状态的方法
},
actions: {
// 定义异步操作
asyncFetchData({ commit }) {
try {
// 异步操作,例如 API 调用
const response = await axios.get('https://api.example.com/data');
// 当异步操作成功时,通过 mutation 更新状态
commit('setData', response.data);
} catch (error) {
// 处理错误
console.error(error);
}
}
},
modules: {
// 如果有模块,可以在这里定义
}
});
- 在组件中分发(dispatch)action
在你的 Vue 组件中,你可以使用 this.$store.dispatch
方法来分发(触发)一个 action。
export default {
created() {
this.$store.dispatch('asyncFetchData');
}
}
- 处理异步操作的结果
当异步操作完成并且状态被更新后,你的组件将自动重新渲染以反映新的状态。你也可以在组件中使用 watch
或 computed
属性来监听状态的变化,并据此执行额外的逻辑。
export default {
computed: {
// 根据状态计算属性
data() {
return this.$store.state.data;
}
}
}
- 错误处理
如果在异步操作中发生错误,你可能想要通知用户或执行其他错误处理逻辑。这通常是通过捕获并处理异步操作中的错误来完成的,如上面的 asyncFetchData
action 中所示。
请注意,Vuex 的 actions 允许你处理异步操作,但并不意味着你应该把所有的异步操作都放在 Vuex 中。对于与特定组件紧密相关的异步逻辑,通常最好将其保留在组件内部,以保持 Vuex store 的简洁性和可维护性。
7.pc端页面刷新时实现vuex缓存
在PC端页面刷新时实现Vuex缓存,我们通常需要考虑的是如何在页面重新加载后保持Vuex store中的状态。由于浏览器的限制,Vuex store的状态在页面刷新时会丢失,因为Vue实例会被销毁并重新创建。为了解决这个问题,我们可以使用一些策略来持久化Vuex的状态。
以下是几种实现Vuex缓存的方法:
1. 使用浏览器的localStorage
或sessionStorage
在Vuex的mutations
中,你可以监听状态的改变,并将状态保存到localStorage
或sessionStorage
中。在页面加载时,你可以从localStorage
或sessionStorage
中恢复状态。
// 在 Vuex store 中
const store = new Vuex.Store({
state: {
// ...你的状态
},
mutations: {
// ...你的mutations
SET_DATA(state, data) {
// 更新状态
state.data = data;
// 同时将状态保存到 localStorage
localStorage.setItem('vuex-data', JSON.stringify(data));
}
},
actions: {
// ...你的actions
},
getters: {
// ...你的getters
}
});
// 在 main.js 中
// 在页面加载时从 localStorage 恢复状态
const savedState = localStorage.getItem('vuex-data');
if (savedState) {
store.commit('SET_DATA', JSON.parse(savedState));
}
2. 使用浏览器的cookies
类似于localStorage
,你可以使用cookies
来存储和恢复Vuex的状态。不过,cookies
通常用于存储少量数据,并且它们有大小限制(通常是4KB),因此可能不适合存储大量状态数据。
3. 使用服务端存储
如果你的应用有后端服务,你可以在用户每次修改状态时向后端发送请求,将状态保存到服务器。在页面加载时,你可以从服务器获取状态并初始化Vuex store。
4. 使用第三方库
还有一些第三方库,如vuex-persistedstate
,可以帮助你更容易地实现Vuex状态的持久化。这些库通常提供了插件,可以简单地集成到Vuex store中。
注意事项
- 当使用
localStorage
、sessionStorage
或cookies
时,请确保你处理了安全性和隐私性的问题。不要在这些存储中保存敏感信息。 - 在使用第三方库时,请确保它们与你的Vue和Vuex版本兼容,并仔细阅读文档以了解如何正确配置和使用。
- 考虑你的应用需求,选择最适合你的缓存策略。对于小型应用,
localStorage
可能就足够了;对于更复杂的应用,你可能需要考虑服务端存储或第三方库。
最后,请注意,虽然缓存Vuex状态可以提高用户体验,但也要确保缓存的数据不会导致应用状态的不一致或错误。在实现缓存策略时,应该充分测试以确保其正确性和可靠性。