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

拆分

  • 吧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中... 方法

vuex demo vuex的modules模块_VUEX

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>