「后端小伙伴来学前端了」Vuex进阶操作,让你的代码更加高效(简称如何学会偷懒 【手动狗头】)

学妹手机里的美照

前言

前一篇写了Vuex基本使用,用起来还稍稍有些繁琐,代码有很多
冗余的地方,这篇就带着大家用更简单的方式来使用Vuex(其实就是怎么更好的偷懒,用更少的代码来完之前的事情)

进入正文....


一、mapGetters 方法

在我们之前要取出store中的getters,在组件中是需要$store.getters.bigSum 才能取到,为了方便会写成计算属性

bigSum(){
    return this.$store.getters.bigSum
}

一个两个还能接受,但是如果有很多的,代码会显得十分冗余。不太合适,作为一名合格的程序员,偷懒是必备的哈。

我们能想到的,前辈们都已经考虑到了。所以就有了mapGetter辅助函数。

mapGetters 辅助函数仅仅是将 store 中的 getter 映射到局部计算属性:

//第一步得先引入
import {mapGetters} from 'vuex'

// 第二步 写在计算属性中
computed:{
    // 之前的写法
    // bigSum(){
    //   return this.$store.getters.bigSum
    // }
  
    //借助mapGetters生成计算属性:bigSum(对象写法)
    ...mapGetters({bigSum:'bigSum'}),

    //借助mapGetters生成计算属性:bigSum(数组写法)
    // ...mapGetters(['bigSum']),
},

实现效果都是一样的。

如果有多个值需要映射的话, ...mapGetters({bigSum:'bigSum'},{xxxx:'xxxxx'}), 或者...mapGetters(['bigSum','xxxx'])都是可以的,极大的压缩了代码。

二、mapState方法

之前要从store 中取得 state 的话,有下面两种方式

  1. $store.state.sum 或者是下面这种计算属性的方式,但是仍要我们自己写。
  computed:{
    sum(){
      return this.$store.state.sum
    }
  },

自动生成方法,和上面的那个mapGetter 是一样的

// 引入的时候多引入一个 mapState  
import {mapGetters,mapState} from 'vuex'

// 计算属性
computed:{
    // sum(){
    //   return this.$store.state.sum
    // }
    //借助mapState生成计算属性:sum(对象写法)
    ...mapState({sum:"sum"}),
   //借助mapState生成计算属性:sum(数组写法)
    ...mapState(['sum']),
},

即使是多个也会非常方便,自动生成是真的香(😁)

三、mapActions方法

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

之前的写法

methods: {
    increment(){
        this.$store.dispatch("increment",1)
    }
}

在按钮调用处是如下方式调用的

<button @click="increment">点击自加</button>

自动生成的写法

methods:{

    //靠mapActions生成:increment(对象形式)
    ...mapActions({increment:'increment'})
    //靠mapActions生成:increment(数组形式)	
    // .mapActions(['increment'])

    // 	increment(){
    //       this.$store.dispatch("increment",1)
    //     }
    //使用方式 这个时候 组件内定义的方法不能像之前一样 重名了,得改一下
    zijia(){
        // 调用的时候 可以直接this  不用写  $store.dispatch  这个了  后面跟参数即可 
        this.increment(1);
    }

}

四、mapMutations方法

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

methods:{
    
    //靠mapActions生成:increment、decrement(对象形式)
    ...mapMutations({INCREMENT:'INCREMENT'}),
    
    //靠mapMutations生成:JIA、JIAN(对象形式)
    ...mapMutations(['INCREMENT']),

    // 使用方式
   zijia(){
      // 之前的方式    this.$store.commit("INCREMENT",1)
  	  this.INCREMENT(1)
    }   
}

五、模块化+命名空间

  1. 目的:让代码更好维护,让多种数据分类更加明确。

  2. 原因:项目应用中存在多个模块,多个模块下又分为多个组件,我们将store分模块,管理数据起来更加的方便,也更易进行数据的维护和扩展。

  3. 修改store.js

    const countAbout = {
      namespaced:true,//开启命名空间
      state:{x:1},
      mutations: { ... },
      actions: { ... },
      getters: {
        bigSum(state){
           return state.sum * 10
        }
      }
    }
    
    const personAbout = {
      namespaced:true,//开启命名空间
      state:{ ... },
      mutations: { ... },
      actions: { ... }
    }
    
    const store = new Vuex.Store({
      modules: {
        countAbout,
        personAbout
      }
    })
    
  4. 开启命名空间后,组件中读取state数据:

    //方式一:自己直接读取
    this.$store.state.personAbout.list
    //方式二:借助mapState读取:
    ...mapState('countAbout',['sum','school','subject']),
    
  5. 开启命名空间后,组件中读取getters数据:

    //方式一:自己直接读取
    this.$store.getters['personAbout/firstPersonName']
    //方式二:借助mapGetters读取:
    ...mapGetters('countAbout',['bigSum'])
    
  6. 开启命名空间后,组件中调用dispatch

    //方式一:自己直接dispatch
    this.$store.dispatch('personAbout/addPersonWang',person)
    //方式二:借助mapActions:
    ...mapActions('countAbout',{incrementOdd:'jiaOdd',incrementWait:'jiaWait'})
    
  7. 开启命名空间后,组件中调用commit

    //方式一:自己直接commit
    this.$store.commit('personAbout/ADD_PERSON',person)
    //方式二:借助mapMutations:
    ...mapMutations('countAbout',{increment:'JIA',decrement:'JIAN'}),
    

六、项目结构

vuex并没有强制大家使用什么样的结构,更多的是一种规则、习惯、建议。

大部分时候Vuex会遵守以下几个规则:

  1. 应用层级的状态应该集中到单个 store 对象中。
  2. 提交 mutation 是更改状态的唯一方法,并且这个过程是同步的。
  3. 异步逻辑都应该封装到 action 里面。

另外就是,当我们的项目变得十分庞大的时候,我们可以将action、mutation 和 getter 分割到单独的文件。引入,最后直接导出 store即可,之后再在main.js中引入。

对于大型应用,vuex建议大致如下的项目结构。(我们在平时开发时也应该要有这种分模块的思想,无论在前端还是后端都应如此,因为这会让接手你项目的人更为轻松)

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

后语

大家一起加油!!!如若文章中有不足之处,请大家及时指出,在此郑重感谢。

纸上得来终觉浅,绝知此事要躬行。

大家好,我是博主宁在春主页

一名喜欢文艺却踏上编程这条道路的小青年。

希望:我们,待别日相见时,都已有所成

推荐文章

搜索方法更快

搜索方法更快

推荐文章

在bash中进行并行处理?

在bash中进行并行处理?

推荐文章

关于静态文本链接

关于静态文本链接

推荐文章

是否可以使用应用程序分发填充的密钥链

是否可以使用应用程序分发填充的密钥链

推荐文章

导出到excel问题

导出到excel问题

推荐文章

TabControl中Tab的DataContextChanged引发得太早

TabControl中Tab的DataContextChanged引发得太早

推荐文章

为什么OpenMP原子指令不支持赋值?

为什么OpenMP原子指令不支持赋值?

推荐文章

运行Android1.6和QVGA的模拟器上的缩放控件

运行Android1.6和QVGA的模拟器上的缩放控件

推荐文章

如何禁用跨域限制

如何禁用跨域限制

推荐文章

发送消息时JSkype出错

发送消息时JSkype出错

推荐文章

除了将MetadataTypeAttribute直接放在类上之外,是否有其他方法可以向ASP.NET MVC指示某些类元数据?

除了将MetadataTypeAttribute直接放在类上之外,是否有其他方法可以向ASP.NET MVC指示某些类元数据?

推荐文章

如何使用“shift+tab”和“tab”处理焦点丢失和焦点获得事件?

如何使用“shift+tab”和“tab”处理焦点丢失和焦点获得事件?

推荐文章

为什么黑暗比灰色轻?

为什么黑暗比灰色轻?

推荐文章

Android中的条码扫描器

Android中的条码扫描器

推荐文章

使用firebug调试时,没有错误

使用firebug调试时,没有错误

推荐文章

扩展“WhenNull”以检查null并通过lambda初始化基础对象

扩展“WhenNull”以检查null并通过lambda初始化基础对象