Vuex进阶篇——Module模块化学习(前端必会)

简介: vue必会的技术vuex

我之前发布了一篇vuex的基础,如果你巧妙的将它遗忘,这是个传送门,点击复习。

我也是一直在看vuex,里边需要了解的知识其实不少,但是因为项目并不常用,所以也总是忘记,今天整理下来,和大家谈谈vueX的模块化开发。这个重要不? 这么说:大厂必会,项目必备!若是不会,学!(●'◡'●)

写前吐槽:我参考了很多人写的博客,并不是很清晰,甚至有人直接把vue官网复制到了博客,浏览了一下,居然一个字都不差。所以博主很是无语,今天就说一下vuex的模块化。写这篇文章,博主的头发又掉了一根,先哭一会。。。

问题:什么是vuex module,为什么要使用vuex模块化?

答: 模块化,就是将vuex分为不同的模块,无论从项目上还是结构上,都容易维护,我们再平时写的vuex中,都是在一个文件中,写state,getters,mutations,actions。想象一下,如果我们的项目特别大,比如淘宝那么大,那么我们vuex中要维护的内容会特别多的时候,例如“购物车”需要用到vuex,“设置”需要用到vuex,“首页”也需要用到vuex。那么如果我们都写到一个文件中,就会出现代码相当的“臃肿”。这一个store文件最后好几万行代码,还怎么维护?

所以,我们vue官网就给出了办法,使用vuex模块化开发。

今天我们简单学习使用,学会后,你要查阅官网,深入学习,才能提高这个技术。

模块化有很多写法,今天按照我的习惯,简单的写一下,我们和以前一样,需要下载vuex,会得到一个store文件夹,内部我们有一个index根文件。并且,我们需要自己创建一个module文件夹,里边放入我们想要区分的js模块文件,你想分成多少个模块,就分成多少个,我目前写了两个模块,一个是购物车car.js,一个是我的my.js,type.js先不用管。如图:

image

首先我们需要先将module中的所有文件引入到index.js根文件中,(以前我们是导出mutations等方法,现在这个文件中,我只引入了模块,所以只需要导出模块),如图:

image

然后我们就可以在每个模块当中,写入独立的state,mutations等等。。。这样我们在使用的时候,购物车就用car.js;我的就用my.js。用购物车car.js举例(其他文件同理),如图:

image

这里就可以像以前一样写我们的vuex方法了。细心的同学会注意到,我们导出时,会多出一个namespaced: true,一般我们在模块使用时,都会加入这个属性。

命名空间:namespaced: true:当模块被注册后,它的所有 getter、action 及 mutation 都会自动根据模块注册的路径调整命名,也就是说,我们在调用这些方法时,需要加上这个文件的路径(比如我要访问这个文件中的state里边的某个属性:this.$store.state.car。后边这个car就是多了个car.js模块名,因为如果不加模块名,那我们会访问所有模块中的属性,那就乱了),所以我们要加上命名空间,相当于独立的区块去使用,模块和模块之间互不干扰。

和平时一样,我们跟个案例:

点击增加数值:
-----------------car.js中

// car.js

const state = {
  number: 100
}
const getters = {

}
const mutations = {
  add () {
    state.number++
  }
}

export default {
  namespaced: true,
  state,
  getters,
  mutations
}

我们重点说一下vue中怎么获取模块中的内容。我们可以和平常一样,直接用this.$store.state.car.number来获取到state中的number内容。我们今天说说在项目中最常使用的:辅助函数mapStatemapGettersmapActions mapMutations

不一一举例,简单说两个mapStatemapActions ,深入理解可去看官网

我们在使用时,需要先引入:

import { mapState,mapActions } from 'vuex'

这两个函数,前者写在计算属性computed中,后写是方法,写在 methods中;

在写入时,需要用到展开符...,它可以将内容一 一的展开

举例:var a = [1,2,3] var b = [4,5,6] var c = [...a,...b] // 打印c为:[1,2,3,4,5,6]

那我们获取一下state中的number:

computed: {
    ...mapState({
      a: state => state.car.number
    })
  },

 methods: {
    ...mapMutations(['car/add']),
    add () {
      this['car/add']() // 注意,这里this后没有点
    }
  }

展开mapState,定义一个a,然后返回state中的car模块下的number常量。
展开mapMutations,返回是个数组,数组中是个字符串,返回car模块下的add方法,定义一个add,直接触发就可以。有人会问,触发mutations中的方法不是应该用commit吗,答案是我们用了mapMutations,它会将这个路径直接映射成commit方法,所以我们直接用就行,这也是与原来的区别。
我们定义的这个a,就是想要的数值,可以在标签中展示出来,add也直接使用:

<template>
  <div class="home">

    <div>{{a}}</div>
    <div @click="add">点击增加</div>

  </div>
</template>

这样写出来,是好用的,但是看起来会有问题。想一下,car是个模块,我们现在只是举例而已,但是如果,我们在开发中,这个模块下命名空间比较深入,还有其他模块,一层一层比较多,就会变成这个样子:

computed: {
    ...mapState({

      a: state => state.car.xx.xx.xx.number
      // 如果下边还有很多,就要写很多重复的 car.xx.xx.xx,如:
      b: state => state.car.xx.xx.xx.name
      c: state => state.car.xx.xx.xx.key
    })
  },

 methods: {
    ...mapMutations(['car/xx/xx/xx/add']),
    add () {
      this['car/xx/xx/xx/add']()
    }
  }

这个层层的嵌套,那就要写很多重复的car/xx/xx/xx/,所以我们可以,将这个模块当作字符串提取出来,换个写法,按照我们的举例:

computed: {
    // 第一个参数,我们放模块,将它提取出来,统一写在这里。这样下边就不用重复的去写了。
    ...mapState('car', {
      a: state => state.number
    })
  },
  methods: {
    ...mapMutations('car', ['add'])
  }

如上所示,我们可以将他作为参数,放到前面,这样所有绑定都会自动将该模块作为上下文,写出来也简单不少。当然我们还可以再简化一些。我们可以通过使用 createNamespacedHelpers 创建基于某个命名空间辅助函数。它返回一个对象,对象里有新的绑定在给定命名空间值上的组件绑定辅助函数。

就是我们可以从vuex中引入 createNamespacedHelpers ,然后将刚才的字符串作为参数,传进来,如下:

<template>
  <div class="home">

    <div>{{a}}</div>
    <div @click="add">点击增加</div>

  </div>
</template>
// 这里引入createNamespacedHelpers 
import { createNamespacedHelpers } from 'vuex'
// 定义mapState, mapMutations ,并将car 传入 createNamespacedHelpers
const { mapState, mapMutations } = createNamespacedHelpers('car')
// import { mapState, mapMutations } from 'vuex'

export default {

  computed: {
    ...mapState({
      a: state => state.number
    })
  },

  methods: {
    // 这里可以直接使用add
    ...mapMutations(['add'])
  }
}

这就是vuex模块化,写法都很多,看我们自己的习惯,当然了,我们在模块中,还可以使用常量替代 Mutation 事件类型。在多人开发时,我们知道 mutations 中放入了方法,如果有很多方法,多人协作时找起来会比较麻烦,那我们可以创建一个放入常量的文件(前文中我们创建的 type.js 文件),在里边我们可以定义常量,但注意的是,我们开发中习惯常量要大写,单词之间用下划线分开。并且,在模块中引入这个文:

一、首先,我们创建一个js文件 ,我们前文图片中的 type.js,在里边创建一个常量,开发时前后要一致,并加以标注:

// 前后都要大写,一般前后名称一致,但是为了我们能够理解,本次我们写两个不一致的。

// 开发中,我们应该这样写:export const ADD_NUMBER = 'ADD_NUMBER'

// 本次我们定义前后不一样的

export const ADD_NUMBER = 'AAA' // 点击增加数字

二、在car模块中引入 type.js 并使用引入进来的常量:

import { ADD_NUMBER } from './type' // 按需引入常量

const state = {
  number: 100
}
const getters = {

}
const mutations = {

  // 使用常量命名,注意,这里 [ADD_NUMBER] 映射出来的名称,其实是 AAA
  // 我们写成固定的数字,也可以设置参数,灵活传参
  // 第一个参数是state,第二个参数是传入参数payload
  
  [ADD_NUMBER](state, payload) {
    state.number += payload
  }
}

const actions = {

}

export default {
  namespaced: true,
  state,
  getters,
  mutations,
  actions
}

三、vue页面,由于刚才我们用了payload参数,所以我们也需要传入参数,然后我们可以思考下,我们触发的名称应该写哪一个?

methods: {
  
    // 思考一下问号的地方,应该写 ADD_NUMBER 还是 AAA ?
    ...mapMutations(['???'])
  }

这个问题也就是我刚才故意在常量中,前后不一样的原因,由于我们前后都写一样,有些小白会不知道,这里定义的到底是前边的名称, 还是后边字符串的名称。答案是 AAA,也是ES6中对象的扩展写法

最后的写法是这样的:

<template>
  <div class="home">
    <div>{{a}}</div>
    <!-- mutations 中的payload 参数,可以在这里直接传递 -->
    <div @click="aaa(100)">点击增加</div>
  </div>
</template>

<script>
import { createNamespacedHelpers } from 'vuex'
const { mapState, mapMutations } = createNamespacedHelpers('car')
// import { mapState, mapMutations } from 'vuex'
export default {
  computed: {
    ...mapState({
      a: state => state.number
    })
  },
  methods: {
    // 我们除了可以写成数组,还可以用对象的写法
    ...mapMutations({
      aaa: 'AAA'
    })

    // 你也可以按照原始写法写,当然要去掉div标签中的参数,参数改成在下边传递。
    //aaa () {
    //  this.$store.commit('car/AAA', 100)
    //}

  }
}
</script>

这就是module模块化的开发写法,希望看完,你们会有所收获。有错误的地方请指出,我们及时更正。

目录
相关文章
|
1月前
|
移动开发 前端开发 JavaScript
从零开始学习前端开发:入门指南
本文将介绍从零开始学习前端开发的入门指南。通过学习HTML、CSS和JavaScript等基础知识,读者将了解前端开发的基本概念和工具,并学会如何构建简单的网页应用程序。无论您是初学者还是有一定经验的开发人员,本文都将帮助您打下坚实的前端开发基础。
|
2月前
|
资源调度 前端开发 JavaScript
构建高效前端项目:现代包管理器与模块化的深度解析
【2月更文挑战第21天】 在当今快速演变的前端开发领域,高效的项目管理和代码组织已成为成功交付复杂Web应用的关键。本文将深入探讨现代前端包管理器如npm, yarn和pnpm的工作原理,以及它们如何与模块化编程实践(例如CommonJS、ES6模块)协同工作以优化开发流程。我们将剖析这些工具的内部机制,了解它们如何解决依赖冲突,提高安装速度,并保证项目的健壮性。同时,本文还将介绍模块化编程的最佳实践,包括代码拆分、重用和版本控制,帮助开发者构建可维护且性能卓越的前端项目。
|
2月前
|
前端开发 JavaScript jenkins
构建高效前端项目:从模块化到自动化
【2月更文挑战第13天】 随着Web技术的不断进步,前端项目的复杂性日益增加。为了确保可维护性和性能,前端工程师必须采用模块化和自动化的策略来优化开发流程。本文将探讨如何使用现代前端工具和最佳实践来构建一个高效的前端项目架构,包括模块打包、代码分割和持续集成等方面。
|
12天前
|
前端开发 JavaScript 安全
【Web 前端】怎么实现Module模块化?
【5月更文挑战第1天】【Web 前端】怎么实现Module模块化?
|
14天前
|
JavaScript 前端开发 开发者
【Web 前端】JS模块化有哪些?
【4月更文挑战第22天】【Web 前端】JS模块化有哪些?
|
14天前
|
存储 移动开发 JavaScript
学习javascript,前端知识精讲,助力你轻松掌握
学习javascript,前端知识精讲,助力你轻松掌握
|
14天前
|
JavaScript 算法 前端开发
【专栏】前端开发中的slot算法和shadow DOM,两者提供更灵活、高效和模块化的开发方式
【4月更文挑战第29天】本文探讨了前端开发中的slot算法和shadow DOM,两者提供更灵活、高效和模块化的开发方式。slot算法允许在组件中定义插槽位置,实现内容的灵活插入和复用,提高代码可读性和维护性。shadow DOM则通过封装DOM子树,实现样式和事件的隔离,增强组件独立性和安全性。这两种技术常应用于组件开发、页面布局和主题定制,但也面临兼容性、学习曲线和性能优化等挑战。理解并掌握它们能提升开发效率和用户体验。
|
17天前
|
前端开发 JavaScript 测试技术
VueX解耦:前端开发的音乐大师
VueX解耦:前端开发的音乐大师
15 4
|
1月前
|
前端开发 JavaScript 安全
前端模块化发展
前端模块化发展
|
1月前
|
前端开发 JavaScript Java
通过学习mayfly,我学会了前端如何优雅设计字典值
`shigen`是一位擅长多种编程语言的博主,他在探索[mayfly-go](https://juejin.cn/post/7319365035552309248)项目后,发现了对枚举值管理的优雅设计。他分享了如何将字典和枚举值结构化,使用Vue+typescript实现更易维护的代码。通过创建`TagType`和`EnumValue`类,以及提供静态方法,实现了模块化和简洁的字典处理。示例展示了如何在页面中高效引用和显示字典数据,提高了代码的可读性和可维护性。
22 3
通过学习mayfly,我学会了前端如何优雅设计字典值