vuex的使用(模块化管理)

  • Post author:
  • Post category:vue


  1. 首先,Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。
  2. 再奉上官方流程图(“单向数据流”理念)

    在这里插入图片描述
  3. 也就是说按照这个模式可以结合vue-devtools浏览器插件调试监听数据在哪个位置改变(这就是不建议直接更改,要按照这个流程来写(可能会显得麻烦,但是对于中大型项目是很有用以及易于管理的))。刚开始可能会不熟悉,会觉得麻烦,可能暂时觉得没什么用,再其以后维护就会变得轻松。
  4. 先给上管理vuex的文件布局。

    文件布局

    5.其次就是各个文件的大概内容,首先是index
// 以下是引入的模块
import Vue from 'vue'
import Vuex from 'vuex'
import mutations from './mutations'
import actions from './actions'
import getters from './getters'
import moduleA from './modules/moduleA'
import moduleB from './modules/moduleB'
//使用vuex
Vue.use(Vuex)
// 数据仓库
const state={
  count:1,
  info:{
    name:'飘飘',
    age:18,
    sex:'男'
  }
}
// 以下是模块化导入的使用
export default new Vuex.Store({
  state,
  mutations,
  actions,
  getters,
  modules: {
    moduleA,
    moduleB
  }
})

6.其次就是同步操作mutations的模块

const mutations = {
  //  这里是同步操作addNumber是组件当中传入的事件名
  //  state 是 vuex状态管理器里面的数据,number是组件当中传入的值
  addNumber(state, number) {
    state.count += number
  },
  decreaseNumber(state, number) {
    state.count -= number
  },
  onchangeObj(state, obj){
    // 对象的值全部改变 也就是重新赋值
    // state.info = obj
    // 如果只改了部分值或者只能改部分值 直接用重新赋值拼接的方法
    state.info ={...state.info,name:obj.name}
  },
//   所有的异步操作都要经过我(亦可以不经过我,但是最好经过我,我好监听)
  actionsDemo(state){
    state.count++
  }
}
// 需要默认导出,不要忘记了
export default mutations

7.还有就是异步操作,我用setTimeout来模拟的异步操作。

const actions={
  actionsDemo(context){
    return new Promise(resolve => {
      setTimeout(()=>{
        // context上下文,包含mutations等
        context.commit('actionsDemo')
        // 让其变成同步,当然也是需要把actionsDemo提交到mutations里面的
        //  返回最新的数据过后可以在其组件当中一样的使用最新的数据 在其组件直接使用.then(成功)或者.catch(失败)
        resolve(context.state.count)
      },1000)
    } )
  }
}
export default actions

8.计算属性getters也就是和computed一样的道理。

const getters = {
  // 计算属性和computed是一样的道理
  countAddSix(state){
   return state.count+5
  }
}
export default getters

9.两个模块化modulesA和modulesB

const moduleA = {
  // 适用于我们协作开发时的管理(相当于每个人的模块写在这里)
  state:{
    aData:'moduleA'
  },
  mutations:{
    moduleMutations(state){
      state.aData='更新moduleA'
    }
  },
  actions:{
    // context 上下文
    moduleMutations(context){
      context.commit('moduleMutations')
    }
  },
  getters: {
    gettersOneA(state){
      return state.aData+'更新了'
    }
  }
}

export default moduleA

// 适用于我们协作开发时的管理(相当于每个人的模块写在这里)
const moduleB = {
  state: {
    bData: 'moduleB'
  },
  mutations: {
    moduleMutationsB(state) {
      state.bData = '更新moduleB'
    }
  },
  actions: {
    // context 上下文
    moduleMutationsB(context) {
      context.commit('moduleMutations')
    }
  },
  getters: {
    gettersOneB(state){
      return state.bData+'更新了'
    }
  }
}
export default moduleB

10.组件当中的方法,数据的使用。

<template>
    <div class="about">
        <h1> 我是moduleA:{{$store.state.moduleA.aData}}</h1>
        <h1> 我是moduleB:{{$store.state.moduleB.bData}}</h1>
        <h2>我是vuex管理器里面的值:{{$store.state.count}}</h2>
        <h3>我是vuex对象里面的数据:{{$store.state.info}}</h3>
          <!--           点击事件 -->
        <button @click="onchangeObj">我是对象</button>
        <button @click="actionsDemo">我是异步传值</button>
        <button @click="addNumber(5)">加上5</button>
        <button @click="decreaseNumber(2)">减小2</button>
             <!--           映射所在区域 -->
        <h1>我是mapstate映射count:{{count}}</h1>
        <h1>我是mapstate映射info(对象):{{info.name}}</h1>
        <h1>我是mapGetters映射count:{{countAddSix}}</h1>
        <!-- 当映射关系也可以把事件这样写 -->
        <button @click="$store.commit('addNumber',5)">我是mapMutations映射count:{{count}}</button>
        <button @click="$store.dispatch('actionsDemo')">我是mapActions映射count:{{count}}</button>
    </div>
</template>
<script>
  //vuex映射
  import {mapState,mapMutations,mapActions,mapGetters} from 'vuex'
  // 等价与 import mapState from 'vuex'
  // import mapMutationsfrom 'vuex'
  // import mapActionsfrom 'vuex'
  // import mapGettersfrom 'vuex'
  // 默认导出组件
  export default {
    // 组件名
    name: 'about',
     // 存放 数据
    data: function () {
      return {
        count:$store.state.count  // 最好把值赋值到当前组件而不是直接是 <h1> 我是moduleA:{{$store.state.moduleA.aData}}</h1> 这样来操作,避免看起臃肿,看个人习惯(个人认为每个地方做自己的事情很方便,也就是面向对象的思想,易于管理,只是前期看起来更麻烦臃肿,但当以后项目越来越大的时候就不易管理了)
      }
    },
    // mapState,mapGetters是映射到计算属性里面的。
    computed:{
    // 直接映射属性名即可
      ...mapState(['count','info']),
      ...mapGetters(['countAddSix'])
    },
    // 存放 方法
    methods: {
      // methods里面是映射mapMutations以及mapActions的
      ...mapMutations(['addNumber']),
      ...mapActions(['actionsDemo']),

      // 以下就是结合官方图来的操作。
      // 异步的方法actions  异步使用dispatch来传值 ,在其actions当中拿到值做对应的事情。
      actionsDemo(){
       this.$store.dispatch('actionsDemo','我是异步传值').then( res=>{
         // 回调函数直接可以使用then的方法先dispatch,再actions再到mutations里,
         // 最后直接回到这也就直接可以调用成功或者失败的操作了
         console.log(res)   // 这个就是其actions中resolve返回的最新的数据
       })
      },
      onchangeObj(){
        // 整个对象的值
        // this.$store.commit('onchangeObj',{name:'倩倩',age:15,sex:'女'})
        // 只传一个的值
        this.$store.commit('onchangeObj',{name:'倩倩'})
      },
      // vuex 加减
      addNumber(number){
        this.$store.commit('addNumber',number)
        // this.$store.state.count = this.$store.state.count+number
      },
      decreaseNumber(number){
        this.$store.commit('decreaseNumber',number)
      },
    },

  }
</script>

<!--scoped是在这个组件才能使用的样式-->
<style scoped>
</style>

最后,开发中遇到过很多的坑,知道模块化管理的重要性,虽然刚开始不习惯,但是到了以后自己也会习惯,喜欢这种方式(勇于接收新事物,敢于尝试)



版权声明:本文为qq_45366081原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。