vue项目中使用vuex管理公共状态3-vuex模块拆分(modules)

  • 模块拆分, 就是解决当项目的公共状态太多, 或者多人开发时, 吧部分公共状态拆开, 放到各个模块内,

拆分

  • 吧store目录下的 index.js文件进行拆分

创建 cinemaModule.js 文件内容为

import http from '@/util/http'
const module = {
    
    
  namespaced: true, // 命名空间
  // 公共全局状态
  state: {
    
    
    cinemaList: []
  },
  // 集中式修改状态的方法
  mutations: {
    
    
    setCinemaList (state, item) {
    
    
      state.cinemaList = item
    },
    clearCinemaList (state) {
    
    
      state.cinemaList = []
    }
  },
  // 异步请求的方法
  actions: {
    
    
    getCinemaList (store, cityId) {
    
    
      return http({
    
    
        url: `/gateway?cityId=${
      
      cityId}&ticketFlag=1&k=4902196`,
        headers: {
    
    
          'X-Host': 'mall.film-ticket.cinema.list'
        }
      }).then(res => {
    
    
        // console.log(res.data)
        store.commit('setCinemaList', res.data.data.cinemas)
      })
    }
  }
}
// 导出去++++++++这里要导出去+++++++++++++++++++++++++
export default module

在创建 另一个 CityModule.js 文件

const module = {
    
    
  namespaced: true, // 命名空间

  state: {
    
    
    cityId: 310100,
    cityName: '上海'
  },
  mutations: {
    
    
    changeCityId (state, item) {
    
    
      console.log(item)
      state.cityId = item
    },
    changeCityName (state, item) {
    
    
      console.log(item)
      state.cityName = item
    }
  },
  actions: {
    
    

  }
}
// 导出去
export default module

然后把这两个文件在store目录下的 index.js文件内导入
这时 store目录下的 index.js 文件:

import Vue from 'vue'
import Vuex from 'vuex'
// import http from '@/util/http'
import CityModule from './module/CityModule'
import CinemaModule from './module/CinemaModule'

Vue.use(Vuex)

export default new Vuex.Store({
    
    
  // state '全局状态'
  state: {
    
    
  },
  // 集中式修改状态,这里修改会被`监听`
  mutations: {
    
    
  },
  // 异步
  actions: {
    
    
  },
  modules: {
    
    
    CinemaModule, // 记住这个里的名字. 注册为什么后面使用都是依据这个
    CityModule
  }
})

现在看上去这个文件就有点空啦, 下面看使用

使用

es6中... 方法
在这里插入图片描述

state 使用

方式一:

比之前未拆分前多了一层模块的名字
例如: 使用CityModule.js 文件内的 全局状态 cityName

this.$store.state.CityModule.cityName

方式二: mapState

mapState 是把 state 定义的全局状态映射出来

mapState('CityModule', ['cityName', 'cityId'])

mapState 方法第一个参数写模块名, 第二个参数为列表, 列表写需要映射出来的状态, 映射出来的是一个对象列表,
这样就可以使用三个点方法进行展开...mapState, 然后在吧这个方法写入到计算属性 computed中, 这样使用的时候就想是使用自身的状态一样啦

<template>
  <div>
	{
   
   { cityName }}
	{
   
   { cityId }}
  </div>
</template>

<script>
// 不要忘了导入 mapState 
import {
     
      mapState } from 'vuex'

export default {
     
     
  data () {
     
     
    return {
     
     
    }
  },
  computed: {
     
     
    ...mapState('CityModule', ['cityName', 'cityId'])
  },
  mounted () {
     
     
	console.log(cityName, cityId)
  }
}
</script>

mutations 使用

集中式修改全局状态

mapMutations

mutations 里面放的是方法, 不是状态, 再放入计算属性computed中就不合适合适啦, 所以把 mapMutations 放入到 methods 进行映射, 在加上...mapMutations进行展开, 使用的时候就好比使用自身的方法

<template>
  <div>
	<button @click="handleChangeCity('北京', 10010)"></button>
  </div>
</template>

<script>
// 不要忘了导入 mapState 
import {
     
      mapMutations} from 'vuex'

export default {
     
     
  data () {
     
     
    return {
     
     
    }
  },
  methods: {
     
     
    // 使用mapMutations吧CinemaModule中mutations的方法changeCityName和changeCityName映射成自己的方法
    ...mapMutations('CityModule', ['changeCityName', 'changeCityName']),
    
    handleChangeCity (city, id) {
     
     
      // 修改公共状态
      this.changeCityId(id)
      this.changeCityName(city)

      this.$router.back()
    }
  }
}
</script>

actions使用

异步

mapActions

虽然是异步, 但也是方法, 所以也放在 mounted 进行...mapActions映射展开,
使用的时候直接 this.XXXX 即可(与上面的mapMutations差不多)

methods: {
    
    
    // 使用mapActions吧CinemaModule中actions异步getCinemaList映射成自己的方法
    ...mapActions('CinemaModule', ['getCinemaList']),
  },
<template>
  <div>

  </div>
</template>
<script>
// import http from '@/util/http'
import BetterScroll from 'better-scroll'
import Vue from 'vue'
import {
     
      NavBar, Icon } from 'vant'
import {
     
      mapState, mapMutations, mapActions } from 'vuex' // export {mapSate}

Vue.use(NavBar).use(Icon)

export default {
     
     
  data () {
     
     
    return {
     
     
      cinemas: [],
      height: 0
    }
  },
  computed: {
     
     
    // 吧CityModule中的状态映射出来,变成一个计算属性
    ...mapState('CityModule', ['cityId', 'cityName']),
    ...mapState('CinemaModule', ['cinemaList'])
  },
  methods: {
     
     
    // 使用mapMutations吧CinemaModule中mutations的方法clearCinemaList映射成自己的方法
    ...mapMutations('CinemaModule', ['clearCinemaList']),
    // 使用mapActions吧CinemaModule中actions异步getCinemaList映射成自己的方法
    ...mapActions('CinemaModule', ['getCinemaList']),
    onClickLeft () {
     
     
      // Toast('返回,左边按钮点击事件')
      // 点击会清楚城市影院缓存
      this.clearCinemaList()
      this.$router.push('/city')
    },
    onClickRight () {
     
     
      // Toast('按钮, 右边按钮点击事件')
      this.$router.push('/cinema/search')
    }
  },
  mounted () {
     
     
    console.log(mapState('CityModule', ['cityId']))
    // console.log(this.$store.state.cityName)
    // 动态获取影院列表所占用的高度
    this.height = document.documentElement.clientHeight - 100 + 'px'

    if (this.cinemaList.length === 0) {
     
     
      // vuex 异步流程
      this.getCinemaList(this.cityId).then(res => {
     
     
        this.$nextTick(() => {
     
     
          new BetterScroll('.cinema', {
     
     
            mouseWheel: true, // 解决better-scroll在PC端使用,鼠标无法实现滚动的解决
            scrollbar: {
     
      // 滚动条, 要加相对位置
              fade: true
            }
          })
        })
      })
    } else {
     
     
      console.log('使用缓存')
      this.$nextTick(() => {
     
     
        new BetterScroll('.cinema', {
     
     
          mouseWheel: true, // 解决better-scroll在PC端使用,鼠标无法实现滚动的解决
          scrollbar: {
     
      // 滚动条, 要加相对位置
            fade: true
          }
        })
      })
    }
  }
}
</script>

猜你喜欢

转载自blog.csdn.net/lxb_wyf/article/details/113694896