vue2-vuex

专门在 Vue 中实现集中式状态(数据)管理的一个 Vue 插件,对 vue 应 用中多个组件的共享状态进行集中式的管理(读/写),也是一种组件间通信的方式,且适用于任意组件间通信

应用场景:

  • 多个组件依赖于同一状态、共享数据
  • 来自不同组件的行为需要变更同一状态
  • vuex

vuex原理

每一个 Vuex 应用的核心就是 store,里面又包括:

  1. State(状态):用于数据的存储(对象类型数据),是store中唯一数据源
  2. Actions(行为):类似于mutation,用于提交mutation来改变状态,而不直接变更状态,可以包含任意异步事件
  3. Mutations(转变):类似函数,改变state数据的唯一途径,且不能用于处理异步事件,Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的事件类型 (type)和一个回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方
  4. Getter(数据加工):如vue中的计算属性一样,基于state数据的二次包装,常用于数据的筛选和多个数据的相关计算
  5. Module:类似于命名空间,用于项目中将各个模块的状态分开定义和操作,便于维护

由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块

vuex环境

  1. 安装vuex

    vue2:使用vuex3版本

    vue3:使用vuex4版本

    shell 复制代码
    # 安装3版本
     npm i vuex@3    
  2. 创建Store

    创建store文件夹,下面创建index.js (官方推荐) or 创建vuex文件夹,创建store.js文件,自定义写法

    js 复制代码
    import Vue from "vue"
    import Vuex from "vuex"
    
    
    // 使用vuex插件,使用之后,创建vm的时候,可以传入store配置项
    // new Vuex.Store 必须使用了Vuex之后,否则报错
    // 如果在main.js 使用 然后引包,脚手架会先执行所以import代码再执行其他代码 也会报错
    Vue.use(Vuex)
    
    
    // 定义actions-用于响应组件中的动作(mutations)
    const actions = {}
    
    // 定义mutations-用于操作数据(state)
    const mutations = {}
    
    // 定义state,用于存储数据
    const state = {}
    
    
    
    // 创建Store
    const store = new Vuex.Store({
        actions,
        mutations,
        state
    })
    
    // 暴露store
    export  default store

  3. 配置store

    js 复制代码
    // main.js
    
    import  store from "./store"
    
    new Vue({
        render: h => h(App),
        store // 配置导入的store,在vm和vc身上可以通过.$store访问
    
    }).$mount('#app')

基本使用

1.初始化数据
js 复制代码
// 定义state,用于存储数据
// 数据被mutations修改
const state = {
    // 定义一个count
    count: 0
}
2. 配置actions
js 复制代码
// 定义actions-用于响应组件中的动作(mutations)
// 该对象中的方法用于commit响应mutations中的方法操作数据
// 该对象被dispatch触发
const actions = {
    // 定义add方法
    // context:上下文对象,包含commit、dispatch、getter、state、roomGetter、rootState 
    // value是调用方传递的值  
    add: function (context, value) {
        // 将数据提交到ADD方法(mutations中定义的),此时不会直接修改数据
        // 可以通过context.dispatch触发其他actions
        context.commit("ADD", value)


    }
}
3. 配置mutations
js 复制代码
// 定义mutations-用于操作数据(state)
// 该对象被actions中的commit and 其他地方的commit触发
const mutations = {
    ADD(state, value) {
        // state是数据对象,包含getter、setter等
        // value是调用方传递的值
        // 通过数据对象操作数据,此时会直接修改值
        state.count += value

    }

}
4.操作store.js
js 复制代码
methods: {
  increment(){
    // 触发回调的时候 调用$store.dispatch,调用actions里的add方法,参数是n
    // actions相当于一个中转,如果参数需要做其他逻辑处理调用dispatch

    this.$store.dispatch("add",this.n)
    
    // 也可以直接操作this.$store.commit("ADD",this.n),调用mutations里的ADD方法
    // 如果不需要其他逻辑处理,直接修改数据调用commit
    this.$store.commit("ADD",this.n)

  }
5.模版中访问
html 复制代码
<!-- 模版中直接通过$store访问 -->
{{$store.state.count}}

getters配置项

getters的功能类似于 Vue 组件中的计算属性。它们都是用于对已有的数据(在 Vuex 中是state)进行计算或者过滤后返回一个新的值

  1. 定义getters

    js 复制代码
    // 用于将state中的数据进行加工
    const getters = {
        // 定义一个doubleCount属性
        doubleCount(state){
            // state 是数据对象
            return state.count * 2
    
        }
    }
    
    const store = new Vuex.Store({
        actions,
        mutations,
        state,
        getters
    })
  2. 使用getters

    js 复制代码
    this.getters.doubleCount
    html 复制代码
    <!-- 模版中使用 -->
    {{$store.getters.doubleCount}}

store中的map方法

mapState

用于帮助我们映射state中的数据为计算属性

复制代码
   ```js

import {mapState} from "vuex";

computed: {

// 对象写法 等同于 count(){{return this.$store.state.count}}

// 如果要修改state中的值 可以写箭头函数返回

...mapState({count: "count", count2: (state)=> state.count * 2}),

// 数组写法

// 等同于 count(){return this.$store.state.count}

// 相当于把stage中的数据以同名的方式映射到计算属性中

...mapState("count")

}

```

mapGetters

用于帮助我们映射getters中的数据为计算属性

复制代码
      ```js

import {mapGetters} from "vuex"

computed: {

// 数组写法 doubleCount(){ return this.$store.getters.doubleCount}

...mapGetters("doubleCount"),

// 对象写法 doubleCount(){ return this.$store.getters.doubleCount}

...mapGetters({doubleCount: "doubleCount"})

}

```

mapActions

用于帮助我们生成与actions对话的方法,即:包含$store.dispatch()的函数

js 复制代码
import {mapActions} from 'vuex'


	methods: {

      //  等同于 addCount(){this.$store.dispatch("add",value)}
      // 这里的value 需要在使用此回调函数的地方绑定 @click="addCount(要传递的参数)"
      // 如果不在使用的地方绑定,则ADD方法内部收到的value 是点击事件
      ...mapActions({addCount: "add"}),
        
        // 数组写法,原理与mapState一致
      ...mapActions(["add"]),
    },
mapMutations

用于帮助我们生成与mutations对话的方法,即:包含$store.commit()的函数

js 复制代码
import {mapMutations} from 'vuex'

	methods: {

      //  等同于 increment(){this.$store.commit("ADD",value)}
      // 这里的value 需要在使用此回调函数的地方绑定 @click="increment(要传递的参数)"
      // 如果不在使用的地方绑定,则increment方法内部收到的value 是点击事件
      ...mapMutations({increment: "ADD"}),
        
        // 数组写法,原理与mapState一致
      ...mapMutations(["ADD"]),

    },

vuex模块化&命名空间

当 Vue 应用规模变大时,store中的状态(state)、变更操作(mutations)、异步操作(actions)和获取器(getters)也会变得复杂繁多。Vuex 模块化允许将store分割成多个模块,每个模块都有自己独立的statemutationsactionsgetters,就像有多个小的 Vuex store一样。
模块化使得代码结构更加清晰,便于团队开发和维护。不同的功能模块可以有各自独立的状态管理逻辑,例如一个电商应用中,可以有用户模块、商品模块、订单模块等,每个模块管理自己相关的状态和操作

模块化
  • 包含多个 module ,一个 module 是一个 store 的配置对象 与一个组件(包含有共享数据)对应
  1. 定义模块

    js 复制代码
    // 自定义一个对象,里面包含vuex的对方方法
    const sumOptions = {
        actions: {},
        mutations:{},
        state:{},
        getters:{sum:10}
    
    }
    
    // 自定义一个对象,里面包含vuex的对方方法
    const countOptions = {
        actions: {},
        mutations:{},
        state:{count:20}
    
    }
    
    
    //创建并暴露store
    export default new Vuex.Store({
        // 模块配置
        modules: {
            // store里面有一个sum模块,对应的是sumOptions对象里面的方法
            sumModules: sumOptions,
    
            // store里面有一个count模块,对应的是countOptions对象里面的方法
            countModules: countOptions
        }
    
    })
  2. 使用模块store数据

    html 复制代码
    {{$store.state.sumModules.sum}}
    js 复制代码
    this.$store.state.sumModules.sum
  3. 通过map方法映射模块对象访问

    js 复制代码
        // 映射的是模块对象
        ...mapState(["sumModules","countModules"])
    html 复制代码
    <!--在模版中可以使用 {{模块名.属性访问}}-->
    {{sumModules.sum}}
命名空间

可以开启模块的命名空间,使用map方法的时候通过指定模块名字和属性、方法名字进行映射

  1. 通过namespaced开启命名空间

    js 复制代码
    const sumOptions = {
        namespaced:true, // 开启命名空间
        actions: {},
        mutations:{},
        state:{sum:10},
    
    }
  2. 读取指定模块的数据

    js 复制代码
    // 使用map读取
    // new store的时候指定的模块名、要映射的属性,其他map方法方法映射同理
    ...mapState("sumModules",["sum"])
    // {{sum}}
    js 复制代码
    // 自己直接读取  state.模块名.属性名
    this.$store.state.sumModules.sum
  3. 读取getters数据

    js 复制代码
    // 使用map读取
    // 模块名,[要映射的数据]
    ...mapGetters('countAbout',['bigSum'])
    js 复制代码
    // 直接读取  模块名/属性名
    this.$store.getters['sumModules/doubleSum']
  4. commit和dispatch

    js 复制代码
    // 直接读取
    //  模块名/方法名,参数
    this.$store.commit("sumModules/ADD",100)
    this.$store.dispatch("sumModules/add",100)
    js 复制代码
    // 使用map映射   模块名  [要映射的方法]
    ...mapMutations('sumModules',{setSum:'ADD'}),
      
    ...mapActions('sumModules',{commitSum:'add'})
    
    // 传参原理与未开启命名空间原理一致
模块化推荐设计
  • store 文件夹:在项目的根目录下创建一个专门的store文件夹,用于存放所有与 Vuex 相关的代码。这个文件夹是整个 Vuex 模块管理的核心区域。
  • 模块文件夹:在store文件夹内,为每个主要的功能模块创建一个单独的文件夹。例如,如果是一个电商应用,可以有user模块文件夹、product模块文件夹、order模块文件夹等。每个模块文件夹用于存放该模块相关的statemutationsactionsgetters的定义文件,export暴露给外部
  • index中用于注册vuex插件、new vuex对象、导入所有模块,统一管理
相关推荐
mldong2 小时前
你的 Vue3 项目也能有钉钉同款审批流设计器:npm 装包,10 分钟画出第一条审批流
前端·vue.js
2分钟速写快排3 小时前
什么是 RAG?如何用 RAG 实现一个用户记忆?
前端·后端·ai编程
passerby60614 小时前
如何自己造一个时间处理库
前端·javascript·github
走到天涯海角5 小时前
react里面的长列表渲染优化
前端·react.js·前端框架
小羊没烦恼!5 小时前
Hello Web API系列教程——Web API与国际化
java·服务器·前端·javascript·php
北岛贰5 小时前
迷茫焦虑期,我做了一个带支付带官网的 AI 聊天虚拟恋人 App
前端·人工智能·后端
mayaairi7 小时前
Vue2 组件通讯(三):全局事件总线、PubSub、插槽与组件实例属性
前端·javascript·vue.js
kyriewen7 小时前
面试官问我:AI 都能写代码了,前端凭什么还值 25K
前端·javascript·人工智能
风骏时光牛马8 小时前
AI源码分析:拆解模型底层实现逻辑
前端
IT_陈寒8 小时前
React子组件莫名其妙重渲染?你可能漏了这个Hook
前端·人工智能·后端