找回密码
 立即注册
首页 业界区 业界 vue2-vuex

vue2-vuex

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

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

1.png

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

  • State(状态):用于数据的存储(对象类型数据),是store中唯一数据源
  • Actions(行为):类似于mutation,用于提交mutation来改变状态,而不直接变更状态,可以包含任意异步事件
  • Mutations(转变):类似函数,改变state数据的唯一途径,且不能用于处理异步事件,Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的事件类型 (type)和一个回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方
  • Getter(数据加工):如vue中的计算属性一样,基于state数据的二次包装,常用于数据的筛选和多个数据的相关计算
  • Module:类似于命名空间,用于项目中将各个模块的状态分开定义和操作,便于维护
由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块
vuex环境


  • 安装vuex
    vue2:使用vuex3版本
    vue3:使用vuex4版本
    1. # 安装3版本
    2. npm i vuex@3   
    复制代码
  • 创建Store
    创建store文件夹,下面创建index.js (官方推荐)  or  创建vuex文件夹,创建store.js文件,自定义写法
    1. import Vue from "vue"
    2. import Vuex from "vuex"
    3. // 使用vuex插件,使用之后,创建vm的时候,可以传入store配置项
    4. // new Vuex.Store 必须使用了Vuex之后,否则报错
    5. // 如果在main.js 使用 然后引包,脚手架会先执行所以import代码再执行其他代码 也会报错
    6. Vue.use(Vuex)
    7. // 定义actions-用于响应组件中的动作(mutations)
    8. const actions = {}
    9. // 定义mutations-用于操作数据(state)
    10. const mutations = {}
    11. // 定义state,用于存储数据
    12. const state = {}
    13. // 创建Store
    14. const store = new Vuex.Store({
    15.     actions,
    16.     mutations,
    17.     state
    18. })
    19. // 暴露store
    20. export  default store
    复制代码

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

1.初始化数据
  1. // 定义state,用于存储数据
  2. // 数据被mutations修改
  3. const state = {
  4.     // 定义一个count
  5.     count: 0
  6. }
复制代码
2. 配置actions
  1. // 定义actions-用于响应组件中的动作(mutations)
  2. // 该对象中的方法用于commit响应mutations中的方法操作数据
  3. // 该对象被dispatch触发
  4. const actions = {
  5.     // 定义add方法
  6.     // context:上下文对象,包含commit、dispatch、getter、state、roomGetter、rootState
  7.     // value是调用方传递的值  
  8.     add: function (context, value) {
  9.         // 将数据提交到ADD方法(mutations中定义的),此时不会直接修改数据
  10.         // 可以通过context.dispatch触发其他actions
  11.         context.commit("ADD", value)
  12.     }
  13. }
复制代码
3. 配置mutations
  1. // 定义mutations-用于操作数据(state)
  2. // 该对象被actions中的commit and 其他地方的commit触发
  3. const mutations = {
  4.     ADD(state, value) {
  5.         // state是数据对象,包含getter、setter等
  6.         // value是调用方传递的值
  7.         // 通过数据对象操作数据,此时会直接修改值
  8.         state.count += value
  9.     }
  10. }
复制代码
4.操作store.js
  1. methods: {
  2.   increment(){
  3.     // 触发回调的时候 调用$store.dispatch,调用actions里的add方法,参数是n
  4.     // actions相当于一个中转,如果参数需要做其他逻辑处理调用dispatch
  5.     this.$store.dispatch("add",this.n)
  6.    
  7.     // 也可以直接操作this.$store.commit("ADD",this.n),调用mutations里的ADD方法
  8.     // 如果不需要其他逻辑处理,直接修改数据调用commit
  9.     this.$store.commit("ADD",this.n)
  10.   }
复制代码
5.模版中访问
  1. {{$store.state.count}}
复制代码
getters配置项

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

  • 定义getters
    1. // 用于将state中的数据进行加工
    2. const getters = {
    3.     // 定义一个doubleCount属性
    4.     doubleCount(state){
    5.         // state 是数据对象
    6.         return state.count * 2
    7.     }
    8. }
    9. const store = new Vuex.Store({
    10.     actions,
    11.     mutations,
    12.     state,
    13.     getters
    14. })
    复制代码
  • 使用getters
    1. this.getters.doubleCount
    复制代码
    1. {{$store.getters.doubleCount}}
    复制代码
store中的map方法

mapState

用于帮助我们映射state中的数据为计算属性
  1.    ```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中的数据为计算属性
  1.       ```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()的函数
  1. import {mapActions} from 'vuex'
  2.         methods: {
  3.       //  等同于 addCount(){this.$store.dispatch("add",value)}
  4.       // 这里的value 需要在使用此回调函数的地方绑定 @click="addCount(要传递的参数)"
  5.       // 如果不在使用的地方绑定,则ADD方法内部收到的value 是点击事件
  6.       ...mapActions({addCount: "add"}),
  7.         
  8.         // 数组写法,原理与mapState一致
  9.       ...mapActions(["add"]),
  10.     },
复制代码
mapMutations

用于帮助我们生成与mutations对话的方法,即:包含$store.commit()的函数
  1. import {mapMutations} from 'vuex'
  2.         methods: {
  3.       //  等同于 increment(){this.$store.commit("ADD",value)}
  4.       // 这里的value 需要在使用此回调函数的地方绑定 @click="increment(要传递的参数)"
  5.       // 如果不在使用的地方绑定,则increment方法内部收到的value 是点击事件
  6.       ...mapMutations({increment: "ADD"}),
  7.         
  8.         // 数组写法,原理与mapState一致
  9.       ...mapMutations(["ADD"]),
  10.     },
复制代码
vuex模块化&命名空间

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


  • 包含多个 module ,一个 module 是一个 store 的配置对象 与一个组件(包含有共享数据)对应

  • 定义模块
    1. // 自定义一个对象,里面包含vuex的对方方法
    2. const sumOptions = {
    3.     actions: {},
    4.     mutations:{},
    5.     state:{},
    6.     getters:{sum:10}
    7. }
    8. // 自定义一个对象,里面包含vuex的对方方法
    9. const countOptions = {
    10.     actions: {},
    11.     mutations:{},
    12.     state:{count:20}
    13. }
    14. //创建并暴露store
    15. export default new Vuex.Store({
    16.     // 模块配置
    17.     modules: {
    18.         // store里面有一个sum模块,对应的是sumOptions对象里面的方法
    19.         sumModules: sumOptions,
    20.         // store里面有一个count模块,对应的是countOptions对象里面的方法
    21.         countModules: countOptions
    22.     }
    23. })
    复制代码
  • 使用模块store数据
    1. {{$store.state.sumModules.sum}}
    复制代码
    1. this.$store.state.sumModules.sum
    复制代码
  • 通过map方法映射模块对象访问
    1.     // 映射的是模块对象
    2.     ...mapState(["sumModules","countModules"])
    复制代码
    1. {{sumModules.sum}}
    复制代码
命名空间

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

  • 通过namespaced开启命名空间
    1. const sumOptions = {
    2.     namespaced:true, // 开启命名空间
    3.     actions: {},
    4.     mutations:{},
    5.     state:{sum:10},
    6. }
    复制代码
  • 读取指定模块的数据
    1. // 使用map读取
    2. // new store的时候指定的模块名、要映射的属性,其他map方法方法映射同理
    3. ...mapState("sumModules",["sum"])
    4. // {{sum}}
    复制代码
    1. // 自己直接读取  state.模块名.属性名
    2. this.$store.state.sumModules.sum
    复制代码
  • 读取getters数据
    1. // 使用map读取
    2. // 模块名,[要映射的数据]
    3. ...mapGetters('countAbout',['bigSum'])
    复制代码
    1. // 直接读取  模块名/属性名
    2. this.$store.getters['sumModules/doubleSum']
    复制代码
  • commit和dispatch
    1. // 直接读取
    2. //  模块名/方法名,参数
    3. this.$store.commit("sumModules/ADD",100)
    4. this.$store.dispatch("sumModules/add",100)
    复制代码
    1. // 使用map映射   模块名  [要映射的方法]
    2. ...mapMutations('sumModules',{setSum:'ADD'}),
    3.   
    4. ...mapActions('sumModules',{commitSum:'add'})
    5. // 传参原理与未开启命名空间原理一致
    复制代码
模块化推荐设计



  • store 文件夹:在项目的根目录下创建一个专门的store文件夹,用于存放所有与 Vuex 相关的代码。这个文件夹是整个 Vuex 模块管理的核心区域。
  • 模块文件夹:在store文件夹内,为每个主要的功能模块创建一个单独的文件夹。例如,如果是一个电商应用,可以有user模块文件夹、product模块文件夹、order模块文件夹等。每个模块文件夹用于存放该模块相关的state、mutations、actions和getters的定义文件,export暴露给外部
  • index中用于注册vuex插件、new vuex对象、导入所有模块,统一管理

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册