首页 > 其他分享 >vuex的工作流程,模块化使用案例分享,及状态持久化

vuex的工作流程,模块化使用案例分享,及状态持久化

时间:2024-07-25 14:58:21浏览次数:18  
标签:持久 模块化 mutations state Vuex import vuex store

文章目录

一、Vuex 是什么?

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式库。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。Vuex 也集成到 Vue 的官方生态系统中,并且在开发大型、复杂单页应用(SPA)时尤其有用。

二、核心概念

  • state:定义应用程序状态的数据。(数据,类似data)

  • mutations:用于修改状态的方法。(执行,类似methods)

  • actions:用于触发 mutations 的方法。(事件,类似controller)

  • getters:用于获取 state 中的数据。(数据加工,类似computed)

  • modules:使用单一状态树,致使应用的全部状态集中到一个很大的对象,所以把每个模块的局部状态分装使每一个模块拥有本身的 state、mutation、action、getters、甚至是嵌套子模块;

三、Vuex 的工作流程

  • 通过dispatch去提交一个actions,

  • actions接收到这个事件之后,在actions中可以执行一些异步|同步操作,根据不同的情况去分发给不同的mutations,

  • actions通过commit去触发mutations,

  • mutations去更新state数据,

  • state更新之后,就会通知vue进行渲染

四、什么情况下我应该使用 Vuex?

Vuex 可以帮助我们管理共享状态,并附带了更多的概念和框架。这需要对短期和长期效益进行权衡。

如果您不打算开发大型单页应用,使用 Vuex 可能是繁琐冗余的。确实是如此——如果您的应用够简单,您最好不要使用 Vuex。一个简单的 store 模式 (opens new window)就足够您所需了。但是,如果您需要构建一个中大型单页应用,您很可能会考虑如何更好地在组件外部管理状态,Vuex 将会成为自然而然的选择。

五、Vuex 的使用

  • 定义 state:定义应用程序的状态数据。

  • 定义 mutations:定义修改 state 的方法。

  • 定义 actions:定义触发 mutations 的方法,可以包含异步操作。

  • 定义 getters:定义获取 state 中数据的方法。

  • 创建 store:将 state、mutations、actions、getters 组合成一个 store 对象。

  • 在应用程序中使用 store:在应用程序中使用 store 对象的 state、mutations、actions、getters。

Vuex 并不限制你的代码结构。但是,它规定了一些需要遵守的规则:

  • 应用层级的状态应该集中到单个 store 对象中。

  • 提交 mutation 是更改状态的唯一方法,并且这个过程是同步的。

  • 异步逻辑都应该封装到 action 里面。

只要你遵守以上规则,如何组织代码随你便。如果你的 store 文件太大,只需将 action、mutation 和 getter 分割到单独的文件。

对于大型应用,我们会希望把 Vuex 相关代码分割到模块中。

六、使用示例

以购物车为例,介绍vuex的使用全过程。

// vuex的入口文件,封装了cart模块,直接引入使用
// store/index.js

import Vue from 'vue'
import Vuex from 'vuex'
import cart from './cart'
Vue.use(Vuex)
export default new Vuex.Store({
  modules: {cart}
})

// cart模块的首页,引入了getters,actions,mutations
// 以及state中模拟的数据
// store/cart/index.js

import getters from "./getters"
import actions from "./actions"
import mutations from "./mutations"

export default {
    state:{
        goods: [{
            id:1,
            name:'小米手机',
            price: 2000,
            count: 0,
        },{
            id:2,
            name:'苹果手机',
            price: 3000,
            count: 0,
        },{
            id:3,
            name:'华为手机',
            price: 4000,
            count: 0,
        }],
    },
    getters,
    actions,
    mutations
}

// getters文件,计算购物车的总价及数量
// store/cart/getters.js

export default {
  totalPrice(state){
    return state.goods.reduce((total,item)=>{
      total += item.price * item.count
      return total
    },0).toFixed(2)
  },
  count(state){
    return state.goods.reduce((total,item)=>{
      total += item.count
      return total
    },0)
  }
}

// actions文件,用于提交商品数量的变化
// store/cart/actions.js

export default {
    add({commit},payload){
        commit('add',payload)
    },
    reduce({commit},payload){
        commit('reduce',payload)
    }
}

// mutations文件,用于改变state中商品的数量变化
// store/cart/mutations.js

export default {
    add(state,index){
        state.goods[index].count++
    },
    reduce(state,index){
        if(state.goods[index].count>=1){
            state.goods[index].count--
        }
    },
}

// 这里是使用vuex的页面,展示购物车页面
// app.vue

<template>
  <div class="about">
    <div v-for="(item, index) in goods" :key="index">
      <div>{{ item.name }}</div>
      <div>{{ item.price }}</div>
      <div style="display: flex">
        <button @click="reduce(index)">-</button>
        <div>{{ item.count }}</div>
        <button @click="add(index)">+</button>
      </div>
    </div>
    <div style="display: flex;">
      <div>总计:{{ count }}</div>
      <div>结算:{{ totalPrice }}</div>
    </div>
  </div>
</template>

<script>
import { mapGetters,mapState } from 'vuex'
export default {
  computed: {
    ...mapState({
      goods(state) {
        return state.cart.goods
      },
    }),
    ...mapGetters(['count', 'totalPrice'])
  },
  methods: {
    add(index) {
      this.$store.dispatch('add', index)
    },
    reduce(index) {
      this.$store.dispatch('reduce', index)
    }
  }
}
</script>

七、状态持久化

vuex优势: 相比sessionStorage,存储数据更安全,sessionStorage可以在控制台被看到。

vuex劣势: 在F5刷新页面后,vuex会重新更新state,所以,存储的数据会丢失。(即刷新浏览器,vuex数据丢失)

1、手动利用HTML5的本地存储

vuex的state在localStorage或sessionStorage或其它存储方式中取值 在mutations定义的方法里对vuex的状态操作的同时对存储也做对应的操作。这样state就会和存储一起存在并且与vuex同步

2、利用vuex-persistedstate插件
2.1、安装
npm install vuex-persistedstate
2.2、配置
  • vuex-persistedstate默认存储于localStorage
// 在store/index.js
import Vue from 'vue';
import Vuex from 'vuex';
import createPersistedState from 'vuex-persistedstate';
 
Vue.use(Vuex);
 
export default new Vuex.Store({
  // ...
  plugins: [createPersistedState()]
  // ...
});
  • 存储sessionStorage的情况
plugins: [
    createPersistedState({
      storage: window.sessionStorage
    })
  ]
  • 存储cookie的情况
import Cookies from 'js-cookie'

plugins: [
    persistedState({
      storage: {
        getItem: key => Cookies.get(key),
        setItem: (key, value) => Cookies.set(key, value, { 
          expires: 7 
        }),
        removeItem: key => Cookies.remove(key)
      }
    })
  ]
  • 指定需要持久化的state

在vuex-persistedstate中,如果你想要指定需要持久化的state(即只持久化Vuex store中的部分状态,而不是全部),你可以通过paths配置选项来实现。paths是一个数组,其中的每个元素都是一个字符串,表示Vuex store中需要被持久化的状态的路径。

import Vue from 'vue'
import Vuex from 'vuex'
import createPersistedState from 'vuex-persistedstate'
import cart from './cart'
import user from './user'
Vue.use(Vuex)
export default new Vuex.Store({
  plugins: [
    createPersistedState({
      paths:['cart','userSettings','user.name'] 
      // 持久化'cart'模块的全部状态
      // 持久化全局状态中的'userSettings'
      // 只持久化'user'模块中的'name' 
    })
  ],
  state: {  
    // 你的全局状态  
    token: '',  
    userSettings: {  
      theme: 'dark',  
      notifications: true  
    }  
  },  
  // 你的模块  
  modules: {cart,user}
})
  • 过滤需要持久化的state

在vuex-persistedstate中,reducer是一个可选的配置项,它的作用是对即将被持久化到存储(如localStorage或sessionStorage)中的Vuex状态进行过滤或转换。通过使用reducer,你可以控制哪些数据被保存,以及如何保存这些数据,从而实现更细粒度的状态持久化控制。

reducer通常是一个函数,它接收当前的state(或特定部分的state,取决于你的配置)作为参数,并返回一个新的对象,该对象包含了应该被持久化的数据。


plugins: [
    createPersistedState({
        storage: window.sessionStorage,
        reducer(state) {  
          // 只返回需要被持久化的部分state  
            return {  
                // 假设我们只想持久化user模块中的name和avatar字段  
                user: {  
                  name: state.user.name,  
                  avatar: state.user.avatar  
                }  
            };  
        }
    })
  ]

如果path和reducer同时存在则使用reducer, 忽悠paths属性。

  • API 配置

createPersistedState([options])使用给定的选项创建插件的新实例。可以提供以下选项来配置您的特定需求的插件:

API参数类型说明默认值
keyString用于存储持久状态的键。vuex
pathsArray部分保持状态的任何路径的数组。如果没有给定路径,则完整状态将持久化。如果给定一个空数组,则不会持久化任何状态。如果使用模块,请包括模块名称。[]
reducerFunction一个将被调用的函数,对即将被持久化到存储中的Vuex状态进行过滤或转换。都包含这些值
subscriberFunction被调用以设置突变订阅的函数。store => handler => store.subscribe(handler)
storageString指定存储数据的方式。localStorage
getStateFunction用来重新补充先前持久状态的功能。storage
setStateFunction用以保持给定状态的函数。storage
filterFunction一个将被调用以过滤setState最终将在存储中筛选过滤的函数。() => true

注意,getState 和 setState 是高级选项,它们允许你完全控制状态的存储和恢复过程。然而,在大多数情况下,简单地使用 paths 或默认行为可能就足够了。

在这里插入图片描述

标签:持久,模块化,mutations,state,Vuex,import,vuex,store
From: https://blog.csdn.net/shanghai597/article/details/140325438

相关文章

  • redis的持久化和集群模式
    redis的持久化什么是持久化把内存中的数据存储到磁盘的,同时也可以把磁盘中的数据加载到内存中redis实现持久化的方式erdis实现持久化的方式有两种:RDB、AOF第一种RDB(RedisDataBase快照模式,每隔一段时间对内存数据进行快照存储)触发方式手动触发:使用save或bgsave触发r......
  • 如何找到 Cech 复合体在 1 维上具有持久同源性但 Vietoris Rips 复合体没有的点集?
    我尝试解决的练习:“找到一个点集,使得Cech复合体在1维上具有持久同源性,而VietorisRips复合体则没有。通过计算两个复合物的持久同源性来验证您的解决方案。“这可能吗?据我所知,这两个复合体在欧几里得子空间上重合。我可以改变云的度量,但这感觉就像作弊。我想......
  • 使用 LangChain 从短暂记忆到持久记忆
    在聊天机器人中构建长期记忆:详细介绍如何将简单的聊天机器人转变为具有长期记忆和上下文理解能力的复杂AI助手   欢迎来到雲闪世界。在聊天机器人中构建长期记忆详细介绍如何将简单的聊天机器人转变为具有长期记忆和上下文理解能力的复杂AI助手   在之......
  • redis的使用场景和持久化方式
    redis的使用场景热点数据的缓存。热点:频繁读取的数据。限时任务的操作:短信验证码。完成session共享的问题完成分布式锁。redis的持久化方式什么是持久化:把内存中的数据存储到磁盘的过程,同时也可以把磁盘中的数据加载到内存中。redis持久化分为两种:RDB和AOFRDB:什......
  • 前端模块化CommonJS、AMD、CMD、ES6
    在前端开发中,模块化是一种重要的代码组织方式,它有助于将复杂的代码拆分成可管理的小块,提高代码的可维护性和可重用性。CommonJS、AMD(异步模块定义)和CMD(通用模块定义)是三种不同的模块规范,它们在定义模块、加载模块以及依赖管理等方面存在差异,并适用于不同的场景。CommonJS、A......
  • 登陆京东(滑块验证),验证码识别,Scrapy框架介绍及其使用,持久化存储到本地
    Ⅰ案例登陆京东(滑块验证)【一】下载opencv库pipinstallopencv-python【二】数据准备先将京东的滑块图片下载到本地背景图background.png滑块图tag.png【三】展示获取滑块的移动数据importos.path#使用opencv识别图像计算滑块之间的距离importcv2impo......
  • Vuex 和 Pinia两种状态管理工具,该选择哪一个呢?
    文章目录1,Vuex2,Pinia3,计数器应用3.1,使用Vuex3.2,使用Pinia4,结论当项目逐渐变大时,状态管理的问题开始显现了出来。这时,两个强大的状态管理工具:Vuex和Pinia。该选择哪一个呢?1,VuexVuex是Vue.js的官方状态管理库。它采用集中式存储管理应用的所有组件的状态,并以......
  • 09 ES6的模块化语法
    ECMAScript6(简称ES6)是JavaScript语言的下一代标准,其中引入了许多新特性,包括模块化语法。ES6的模块化语法允许开发者将代码分割成独立的模块,每个模块可以包含变量、函数和其他资源,并且可以在不同的文件中进行导入和导出。导出模块(Export)在ES6中,可以使用export关键字来导出......
  • 谷粒商城实战笔记-43-前端基础-Vue-使用Vue脚手架进行模块化开发
    文章目录一,Vue的模块化开发1,目录结构2,单文件组件(SFC)3,模块化路由4,Vuex模块5,动态组件和异步组件6,抽象和复用7,构建和打包8,测试9,文档和注释10,持续集成/持续部署(CI/CD)二,实战1,全局安装webpack2,全局安装vue脚手架3,初始化vue项目4,启动vue项目三,Vue应用原理初探1,m......
  • Redis7(二)Redis持久化双雄
    持久化之RDBRDB的持久化方式是在指定时间间隔,执行数据集的时间点快照。也就是在指定的时间间隔将内存中的数据集快照写入磁盘,也就是Snapshot内存快照,它恢复时再将硬盘快照文件直接读回到内存里面。RDB保存的是dump.rdb文件。自动触发默认redis是有三种自动触发的规则,在配置......