ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Vuex的五个核心概念

2021-04-11 11:05:25  阅读:186  来源: 互联网

标签:核心 state 五个 Mutation 使用 Vuex 我们 store


文章目录

五个核心概念

const store=new Vuex.Store({
  state:{},
  mutations:{},
  actions:{},
  getters:{},
  modules:{}
})

​ 以上为五个核心概念的内容,接下来我们一一介绍:

​ 首先贴出一张图以备我们后面使用:
在这里插入图片描述

1. state

​ 首先我们需要弄清楚的是state的功能,我们前面提到state是用来放置我们所有状态的属性。

​ 在Vuex中提出了单一状态树的概念,也就是单一数据源的意思。意思就是我们全局只有一个store实例,也就是是我们只有一个管家的角色,这样一来统一了数据源,不会造成一些不必要的冲突。

单一状态树让我们能够直接地定位任一特定的状态片段,在调试的过程中也能轻易地取得整个当前应用状态的快照。

​ 我们可以看一下State的定义和使用

定义:

 state:{
    counter:0
  },

使用(可以在模板中使用也可以在计算属性中使用):

<p>{{$store.state.counter}}</p>

2. Getters的使用

​ 这里的getters实际上类似于我们组件中的计算属性,通常用于返回我们某个状态改变后的状态。

​ 并且我们定义的getters函数可以包含一个state的参数,这个参数的含义就是我们的store下的state状态

​ 我们下面可以模拟一个场景:有一组学生我们需要获取其大于20岁的人以及个数。

student状态:

student:[
      {id:1,name:'a',age:12},
      {id:2,name:'b',age:21},
      {id:3,name:'c',age:34},
      {id:4,name:'d',age:26},
    ]

getters:

 getters:{
    more20person(state){
      return state.student.filter((s) => {
        return s.age>20
      })
    }
  },

​ 其实除此之外我们还可以为其传参,比如我们现在想让年不是age,而是我们给定的值。那么我们就需要返回一个函数类型的返回值,给返回的函数设定参数。

moreageperson(state){
      return function (tt) { 
        console.log(tt);
        return state.student.filter((s) =>s.age>tt) 
     }
    },

使用方法:

    <p>{{$store.getters.moreageperson(10)}}</p>

3 Mutations

​ 通过文中一开始贴的图我们看出Vuex的store中状态更新的唯一方式就是通过提交Mutation的方式来进行,因为我么这里需要DevTools进行追踪我们状态的更新情况。

因此我们可以知道Mutation常常用于操作变更状态数据。

3.1 基本使用

​ 一个Mutation主要包括两部分的内容:

  1. 字符串的事件类型
  2. 一个回调函数,其中可以包含两个参数一个是state,另一个是我们自定义传入的参数。

这是一个Mutation的实例代码:

mutations:{
    increment(state){
      state.counter++
    }
  }

使用方法(在组件中直接通过store的commit方法调用):

this.$store.commit('increment')

​ 接下来可以看看它的传参,参数称为Mutaions的载荷(payload).

​ 参数的方式有两种,一种是直接进行传入,这种方式的缺点是只能传入一个参数

​ 第二种是传入一个对象,这就实现了定义多个参数的功能。

3.2 响应规则

通过上面的一些代码我们会发现Vuex中的state数据是响应式的,因为他们在刚一定义时就被加入到Vue的响应式系统中了,因此当我们改变了状态数据之后,我们数据也可以做到响应式了。

但是我们还需要遵守一些规则:

  1. 在刚开始初始化时就将state中的属性定义好
  2. 如果后期想添加或者删除属性,不能通过es的基本语法

我们需要使用Vue.set的方式给其赋值,使用Vue.delete的方式给其删除属性。

我们可以看一下以下的例子:

原数据:

 info:{name:'cc',age:13},

使用普通方式增加属性

updatastate(state){
      state.info['address']='北京'
}

这时运行代码,我们发现在devTools中数据确实更新了,但是我们用在界面上的数据并没有更新。

当我们使用第二种方式时:

   updatastate(state){
      // state.info['address']='北京'
      Vue.set(state.info,'address','北京')
    }

这时我们发现数据和界面都更新了。

这说明我们使用Vue的set方法内部可以将我们增添的属性加入它的响应式系统中

3.3 常量类型

​ 在mutation中, 我们定义了很多事件类型(也就是其中的方法名称),当我们的项目增大时, Vuex管理的状态越来越多, 需要更新状态的情况越来越多, 那么意味着Mutation中的方法越来越多.

​ 方法过多, 使用者需要花费大量的经历去记住这些方法, 甚至是多个文件间来回切换, 查看方法名称, 甚至如果不是复制的时候, 可能还会出现写错的情况.

​ 因此我们使用常量替代Mutation事件的类型(上文提到的type),我们可以将这些常量放在一个单独的文件中, 方便管理以及让整个app所有的事件类型一目了然.

具体做法:

  1. 创建一个专门终于储存常量type名的文件,并导出
  2. 使用es6函数命名方式导出进行使用
[常量](state,payload){

}

3.4 同步函数

​ 通常情况下, Vuex要求我们Mutation中的方法必须是同步方法.

​ 我们可以看上面的图,会发现Vuex主要将后端的异步操作都交给了Action处理,异步操作结束后再交给Mutation。最主要的是在Mutation这一环节有一个DevTools追踪记录环节。

​ 因而如果我们在这里使用异步的耗时操作DecTools是追踪不到我们我们的记录的。

​ 我们可以在Mutation中加一个异步操作测试以下DevTools会不会追踪到我们数据的改变。

就用我们上文的改变属性操作:

 updatastate(state){
        setTimeout(() => {
          Vue.set(state.info,'address','北京')          
        }, 1000);
      }
  },

这时我们发现DevTools是没有这条属性增加的记录的。

因此我们得出结论:不要再Mutation中执行任何异步的操作。

4. Action

​ 经过文上对Mutaion同步函数的介绍你是否对Action有一定的理解,对,就是Vuex为我们专门用于异步耗时操作的一个环节。之后再取将我们数据提交到Mutation。

​ Action中的函数是可以有两个参数的,一个是context,一个是我们的payload,payload参数和Mutation的参数使用是一样的。

​ 其中context是指上下文,代表了我们的store对象。

这里我们依然使用上文的实例来进行对增添属性的异步操作:

actions: {
    undatadata(context) {
      setTimeout(() => {
        context.commit('updatastate')
      }, 2000);
    } 
  },

使用dispeach进行调用事件:

<button @click="$store.dispatch('undatadata')">updata</button>

这时我们发现再devtools监听到了数据的变化。

4.1 使用Promise

如果我们这里增加需求,当异步操作完成之后来提醒我们异步操作完成。

这里有两种方式来处理,一种是回调函数的形式,一种就是promise:

我们这里直接来看promise:

 actions: {
    undatadata(context) {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          context.commit('updatastate');
          resolve('改变成功')
        }, 2000);
      });
    }
  },

使用:

 datachange(){
      this.$store.dispatch('undatadata').then((result) => {
        console.log(result);
      }).catch((err) => {
        
      });
    }

这里我们使undatadata方法返回一个Promise对象,然后世界this.$store.dispatch(‘方法名’)就可以直接拿到它的返回值,我们就可以直接在这里进行操作。

5 Moudle

​ Module是模块的意思, 为什么在Vuex中我们要使用模块呢? Vue使用单一状态树,那么也意味着很多状态都会交给Vuex来管理。当应用变得非常复杂时,store对象就有可能变得相当臃肿.

​ 为了解决这个问题, Vuex允许我们将store分割成模块(Module), 而每个模块拥有自己的state、mutation、action、getters等

这时从官网直接copy下来的代码:

const moduleA = {
  state: () => ({ ... }),
  mutations: { ... },
  actions: { ... },
  getters: { ... }
}

const moduleB = {
  state: () => ({ ... }),
  mutations: { ... },
  actions: { ... }
}

const store = new Vuex.Store({
  modules: {
    a: moduleA,
    b: moduleB
  }
})

store.state.a // -> moduleA 的状态
store.state.b // -> moduleB 的状态

​ 定义了两个模块AB,直接再store的moudles中进行注册

​ 但是再使用时我们需要注意要直接再store.state.模块名.内容中调用,并不是再moudles中,这时vuex将moudles里面的内容放入到store的state中了。

​ 需要注意的是我们moudles中的Mutation也是和普通的调用方法一样直接从store中调用的,注意不要于其他地方的mutation重名。但是模块里面Mutation中的参数state是模快内部的状态数据。

​ 同样,对于模块内部的 action,局部状态通过 context.state 暴露出来,根节点状态则为 context.rootState,具体我们可以打印context的内容来根据我们需求进行变换。这里的context对应的是本模块下的内容,root层需要其他的方法调用

​ 对于模块内部的 getter,根节点状态会作为第三个参数暴露出来:state, getters, rootState。

6 项目结构

再开发中我们的vuex内容一般不会写在一个js文件中,回具体的分成不同文件结构,这样让我们的代码更加清晰。

来自官网

├── index.html
├── main.js
├── api
│   └── ... # 抽取出API请求
├── components
│   ├── App.vue
│   └── ...
└── store
    ├── index.js          # 我们组装模块并导出 store 的地方
    ├── actions.js        # 根级别的 action
    ├── mutations.js      # 根级别的 mutation
    └── modules
        ├── cart.js       # 购物车模块
        └── products.js   # 产品模块

标签:核心,state,五个,Mutation,使用,Vuex,我们,store
来源: https://blog.csdn.net/M_Edison/article/details/115591300

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有