浅谈Vue状态管理器

Vue状态管理器

1.什么是vuex?

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。Vuex 的状态存储是响应式的,当组件从 store 中读取状态时,如果状态发生变化,那么相应的组件也会得到高效更新。

2.使用vuex的原因

  1. 管理共享状态:随着项目的复杂性增加,多个组件可能需要共享同一份数据。Vuex 允许我们将这些数据集中存储在一个地方(即 store),并提供了统一的接口来访问和修改这些数据,从而简化了组件之间的数据共享和管理。
  2. 响应式状态更新:Vuex 的状态存储是响应式的,当组件从 store 中读取状态时,如果状态发生变化,那么相应的组件也会得到高效更新。这确保了组件的状态始终与 Vuex store 中的状态保持同步。
  3. 简化复杂应用的状态管理:对于中大型单页应用,状态管理可能会变得非常复杂。Vuex 提供了简洁的 API 和清晰的模式,帮助开发者更好地组织和维护应用的状态。
  4. 避免直接操作全局对象:在 Vue 应用中,直接操作全局对象可能会导致状态不一致和难以调试的问题。Vuex 通过强制开发者通过明确的方式(即通过提交 mutation)来修改状态,避免了这些问题。
  5. 插件支持:Vuex 支持插件系统,这使得开发者可以扩展 Vuex 的功能,例如添加日志记录、持久化等功能。
  6. 需要注意的是,虽然 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 访问它。不过,为了保持代码的清晰和可维护性,通常建议使用 mapStatemapMutationsmapActionsmapGetters 这些辅助函数来将 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 的值以及修改这些值的地方通常涉及到以下几个步骤:

  1. 从 Vuex Store 中映射状态到组件

    使用 mapState 辅助函数将 Vuex store 中的状态映射到组件的计算属性中。这样,组件就可以像访问本地数据一样访问这些状态。

    import { mapState } from 'vuex';
    
    export default {
      computed: {
        // 使用 mapState 将 Vuex 中的状态映射到组件
        ...mapState(['yourState'])
        // 或者使用对象形式映射具有不同名称的状态
        // ...mapState({
        //   localStateName: state => state.yourState
        // })
      }
    }
    
  2. 在组件中调用 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);
        }
      }
    }
    
  3. 在组件中调用 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);
        }
      }
    }
    
  4. 使用 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 处理异步操作的步骤:

  1. 在 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: {
    // 如果有模块,可以在这里定义
  }
});
  1. 在组件中分发(dispatch)action

在你的 Vue 组件中,你可以使用 this.$store.dispatch 方法来分发(触发)一个 action。

export default {
  created() {
    this.$store.dispatch('asyncFetchData');
  }
}
  1. 处理异步操作的结果

当异步操作完成并且状态被更新后,你的组件将自动重新渲染以反映新的状态。你也可以在组件中使用 watchcomputed 属性来监听状态的变化,并据此执行额外的逻辑。

export default {
  computed: {
    // 根据状态计算属性
    data() {
      return this.$store.state.data;
    }
  }
}
  1. 错误处理

如果在异步操作中发生错误,你可能想要通知用户或执行其他错误处理逻辑。这通常是通过捕获并处理异步操作中的错误来完成的,如上面的 asyncFetchData action 中所示。

请注意,Vuex 的 actions 允许你处理异步操作,但并不意味着你应该把所有的异步操作都放在 Vuex 中。对于与特定组件紧密相关的异步逻辑,通常最好将其保留在组件内部,以保持 Vuex store 的简洁性和可维护性。

7.pc端页面刷新时实现vuex缓存

在PC端页面刷新时实现Vuex缓存,我们通常需要考虑的是如何在页面重新加载后保持Vuex store中的状态。由于浏览器的限制,Vuex store的状态在页面刷新时会丢失,因为Vue实例会被销毁并重新创建。为了解决这个问题,我们可以使用一些策略来持久化Vuex的状态。

以下是几种实现Vuex缓存的方法:

1. 使用浏览器的localStoragesessionStorage

在Vuex的mutations中,你可以监听状态的改变,并将状态保存到localStoragesessionStorage中。在页面加载时,你可以从localStoragesessionStorage中恢复状态。

// 在 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中。

注意事项
  • 当使用localStoragesessionStoragecookies时,请确保你处理了安全性和隐私性的问题。不要在这些存储中保存敏感信息。
  • 在使用第三方库时,请确保它们与你的Vue和Vuex版本兼容,并仔细阅读文档以了解如何正确配置和使用。
  • 考虑你的应用需求,选择最适合你的缓存策略。对于小型应用,localStorage可能就足够了;对于更复杂的应用,你可能需要考虑服务端存储或第三方库。

最后,请注意,虽然缓存Vuex状态可以提高用户体验,但也要确保缓存的数据不会导致应用状态的不一致或错误。在实现缓存策略时,应该充分测试以确保其正确性和可靠性。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值