Vuex —— 状态管理 | Module

         在前面讲到了关于Vuex数据状态管理的内容,讲了Vuex的五大核心属性,在这五大核心属性中就 state、mutation 和 actions 在前面介绍 Vuex 状态管理和讲 Vuex 中的同步和异步操作已经比较熟悉了,getter 是基于state 的计算属性,vue 中 computed从data中派生出的计算属性, vuex中 getter是从state中派生出的属性,对于getter的使用还是比较简单的,那么本篇主要来讲关于这最后一个核心属性 —— Module .

        创建项目之后在 /store/index.js 文件后,将之前编写获取swiperList的操作放进入之后:

import Vue from 'vue'
import Vuex from 'vuex'
import { reqSwiperList } from '@/api'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    swiperList: [] // swiperList-轮播列表
  },
  getters: {

  },
  actions: {
    async getSwiperList (store) {
      const result = await reqSwiperList()
      console.log(result)
      if (result.meta.status === 200) {
        const data = result.data.swiperList
        store.commit('receive_SwiperList', data)
      }
    }
  },
  mutations: {
    receive_SwiperList (state, data) {
      state.swiperList = data
    }
  },
  modules: {

  }
})

        设想一下假设项目中还有其他模块内容,这些模块内容在编写上还是相信你可以完成而且排序整齐,但项目完成会发现这个index.js的文件太大了且可维护性差,项目的开发是一个团队的事情,而且负责的模块内容也需要编写到这里,团队成员的合作就会产生一些冲突,使用 Vuex 状态管理的本意是让团队的协助会变得方便且后期维护起来方便,但现在仅仅将所有的内容放置在index.js 下就不合理,所以就需要将内容分为模块(module),最后将模块在index.js进行管理!

        下面来进行模块(Module)的引入使用:

Module 

        上面编写的是一个获取swiperList(轮播)数据,现在它是分到了项目中的首页去展示的,那么就来创建一下首页模块:

        创建 /store/Module 文件夹来存放各模块内容,并在该文件目录下创建 HomeModule.js 模块文件:

// store/Module/HomeModule.js

/* 首页数据状态管理模块 */
import { reqSwiperList } from '@/api/index'

const module = {
  state: {
    swiperList: [] // swiperList-轮播列表
  },
  mutations: {
    receive_SwiperList (state, data) {
      state.swiperList = data
    }
  },
  actions: {
    async getSwiperList (store) {
      const result = await reqSwiperList()
      console.log(result)
      if (result.meta.status === 200) {
        const data = result.data.swiperList
        store.commit('receive_SwiperList', data)
      }
    }
  }
}

export default module

        这个内容就是首页模块需要管理的数据状态了,那么还需要将它引入到 /store/index.js 的文件中去,如下:

// store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
import HomeModule from '@/store/Module/HomeModule'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
  },
  getters: {
  },
  mutations: {
  },
  actions: {
  },
  modules: {
    HomeModule
  }
})

        可以看到现在 /store/index.js 的文件中引入 modules: { HomeModule } 首页数据状态管理的模块,如果要引入其他的模块,例如:服务模块,在Module文件夹中创建服务模块ServiceModule.js后,编写需要管理的数据状态即可,接着将在/store/index.js文件中去引入该模块就好了,妙哉!

下面来测试运行一下是否成功:(实践是检验真理的唯一标准)

        通过 Devtools 拓展工具就可以看到加载了HomeModule模块以及有对应模块的state数据状态管理,到这一步是不是隐隐约约有个老头撅个嘴说 "Nice!!!" 别急,还有下一步呢!

        如果是上一篇目到达此地,可能就说,视图怎么没更新?

        不应该是如下面这般的吗?

        就挺秃然的是吧,那下面就来讲怎么让它出来好吧!

渲染视图

        Vuex状态模式改变了,对应的渲染视图操作也需要调整;首先先来打开命名空间:

namespace 命名空间

        在编写的模块当中添加一个namespace属性,属性值为true!

// store/Module/HomeModule.js

/* 首页数据状态管理模块 */
import { reqSwiperList } from '@/api/index'

const module = {
  // 命名空间
  namespace: true,
  state: {
    swiperList: [] // swiperList-轮播列表
  },
...

mapState 映射状态

        那么就来到首页页面MusicView.vue中来导入vuex,通过 mapState 来映射状态,那么现在在mounted生命周期打印一下,使用 mapState 来将 HomeModule 模块中 state.swiperList 进行切割出来;

mapState('模块名称',[切割内容])

注:使用数组[ ] 是因为在模块中的state中的数据状态不止一个,比如有swiperList,可能还有navList 等这些其他数据状态;

<!--MusicView.vue-->
...
<script>
import { mapState } from 'vuex'
export default {
  mounted () {
    console.log(mapState('HomeModule', ['swiperList']))
  },
...

        可以知道拿到的是一个对象,怎么来使用呢?那么在这个对象中呢有这样一个方法供你在计算属性当中来使用;在 第十六篇 Computed 计算属性的应用 中就讲过了计算属性的使用,举一个简单的例子:computed:{ sum(){ return ... } } ,在页面中直接把 sum 拿过来用就可以了对吧,那么现在就是去展开这个对象,然后将它取出来用!

... mapState()

        在计算属性中通过三个点 ' ... ' 就可以展开一个数组或是一个对象(ES6语法),如下:

         通过以上的讲解你就知道这块 ...mapState('HomeModule',['swiperList']) 是什么了,就是展开切割出来的对象,这对象就是映射该模块的所要取的状态;现在来计算属性中展开:

...
<script>
import { mapState } from 'vuex'
export default {
  computed: {
    ...mapState('HomeModule', ['swiperList'])
  },

  mounted () {
    console.log(mapState('HomeModule', ['swiperList']))
  },
...

        依然没有视图,打开控制台出现这一句(心想:"真的要奔溃啦"):

         同理,mapState 将状态映射出来,同理,这里也需要将 actions 的方法进行映射出来这个模块的方法 getSwiperList ;

...mapActions

        将mapActions引入之后,通过在methods中将方法进行映射;

...
<button @click="getSwiperList">同步获取swiperList数据</button>
...
<script>
import { mapActions, mapState } from 'vuex'
export default {
  computed: {
    ...mapState('HomeModule', ['swiperList'])
  },
  methods: {
    ...mapActions('HomeModule', ['getSwiperList']),
    // 按钮事件
    getSwiperList () {
      // 通过dispatch触发actions调用
      this.$store.dispatch('getSwiperList')
    }
  }
...

        别急,现在已经将 getSwiperList 方法引入了,就不需要通过this.$store.dispatch()来调用函数了,直接调用该函数就可以了;[ 注:把按钮的触发事件名称修改一下,避免冲突 ]

<button @click="getSwiperData">同步获取swiperList数据</button>
...
methods: {
    // 按钮事件
    getSwiperData () {
      // 通过dispatch触发actions调用
      this.getSwiperList()
    }
}

现在来测试一下代码:在页面使用v-for做渲染的时候,也不需要使用 this.$store.state.swiperList 

通过 mapState 映射状态可以直接使用 swiperList 即可!

<template>
    <div>
        <h3>分享音乐社区</h3>
        <router-link to="/music/kugou" active-class="chosen_cl"><li>分享酷狗Music</li></router-link>
        <router-link to="/music/kuwo" active-class="chosen_cl"><li>分享酷我Music</li></router-link>
        <router-view></router-view>
        <button @click="getSwiperData">同步获取swiperList数据</button>
        <li v-for="item in swiperList" :key="item.goods_id">
          <img :src="item.imgUrl" alt="">
        </li>
    </div>
</template>

<script>
import { mapActions, mapState } from 'vuex'
export default {
  computed: {
    ...mapState('HomeModule', ['swiperList'])
  },
  methods: {
    ...mapActions('HomeModule', ['getSwiperList']),
    // 按钮事件
    getSwiperData () {
      // 通过dispatch触发actions调用
      // this.$store.dispatch('getSwiperList')
      this.getSwiperList()
    }
  }
}
</script>

<style lang="scss">
  .chosen_cl{
    color:skyblue;
    font-weight: bold;
  }
  img{
    width: 200px;
  }
</style>

        本篇目讲到这里就已然结束了,在此关于对Vuex的数据状态管理有了一个比较充分的认识,对Vuex中的五大核心属性也有了了解,在之后的项目开发中可以尝试着使用Vuex数据状态管理的模式来开发项目,希望本篇能助你在项目开发这条路上的起初是一块垫脚石!感谢大家的支持!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

灵魂学者

你的鼓励是我最大的动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值