Vuex

Vuex是一个专门为Vue.js应用程序开发的状态管理模式, 它采用集中式存储管理所有组件的公共状态, 并以相应的规则保证状态以一种可预测的方式发生变化.image-20210115112340949

上图中绿色虚线包裹起来的部分就是Vuex的核心, state中保存的就是公共状态, 改变state的唯一方式就是通过mutations进行更改. 可能你现在看这张图有点不明白, 等经过本文的解释和案例演示, 再回来看这张图, 相信你会有更好的理解. 整体可以理解为一个特别的数据库,这样可以避免复杂的组件通讯。


State

state就是Vuex中的公共的状态, 我是将state看作是所有组件的data, 用于保存所有组件的公共数据.

组件导入state中数据的方式:

  1. $store.state.val

    <template>
     <div>
       <h2>最新的count为: {{$store.state.count}}</h2>
       <button>+1</button>
     </div>
    </template>

    <script>
    export default {
     data () {
       return {}
    }
    }
    </script>

     

  2. 导入并使用 ...mapstate([val1,val2])

    <template>
     <div>
       <h2>最新的count为: {{count}} </h2>
       <button>-1</button>
     </div>
    </template>

    <script>
    import {mapState} from 'vuex'
    export default {
     data () {
       return {}
    },
     computed: {
         ...mapState(['count'])
    }
    }
    </script>

     

修改vuex中的值:

非法方式: this.$store.state++;

正规方法 Mutation,相对繁琐,但是保险,可以查看是哪个文件修改的数据

index.js
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
 state: {
   count: 0
},
 mutations: {
   add(state){
     state.count++;
  },
   substract(state){
     state.count--;
  },
   multi(state, step){
     state.count = state.count * step;
  },
   substractN(state, step){
     state.count -= step;
  },
},
 actions: {
},
 modules: {
}
})
组件内
<template>
 <div>
   <h2>最新的count为: {{$store.state.count}}</h2>
   <button @click="add">+1</button>
   <button @click="multi(2)">x2</button>
 </div>
</template>

<script>
export default {
 data () {
   return {}
},
 methods:{
     add(){
         // 非法写法
         // this.$store.state.count++;
         // 合法操作
         this.$store.commit("add");
    },
     multi(step){
         this.$store.commit("multi", step);
    }
}
}
</script>

或者mapMutation

组件内

<template>
 <div>
   <h2>最新的count为: {{count}} </h2>
   <button @click="sub">-1</button>
   <button @click="subN(5)">-5</button>
 </div>
</template>

<script>
import {mapMutations, mapState} from 'vuex'
export default {
 data () {
   return {}
},
 computed: {
     ...mapState(['count'])
},
 methods: {
     ...mapMutations(['substract', 'substractN']),
     sub(){
         // 非法写法
         // this.$store.state.count--;
         // 合法操作1
         // this.$store.commit("substract");
         // 合法操作2
         this.substract();
    },
     subN(n){

         this.substractN(n);
    }
},
}
</script>

注意,Mutation里不能直接写原生异步代码,会导致调试出错

因此需要Action来处理异步任务

再index.js中,添加如下,把异步操作包入action中定义的函数中,用commit触发mutation中的add()

action中无法直接使用state中的数据,只有mutation中的函数才可以修改state中的数据,传参方式是典型的mutation传参

actions: {
   asyncAdd(context){
     setTimeout(()=>{
       context.commit('add');
    }, 5000);
  }
},
   asyncAddN(context,n){
     setTimeout(()=>{
       context.commit('addN',n);
    }, 1000*n);
  }
}

再让组件接收到action中的函数,用dispatch接收action中commit出来的‘add’。 再methods里面添加如下代码

      asyncAdd(){
        this.$store.dispatch("asyncAdd");
    },
    asyncAddN(n){
        this.$store.dispatch("asyncAddN", n);
    },

组件接收action还可以使用以下方式 - mapActions([..., ..., ...])

methods: {
...
    ...mapActions(['asyncSubN']),
...
}

 

Getter: 对于store中已有的数据进行加工形成新的数据,类似map方法

index.js

getters: {
    showNum(state){
      return "当前最新数据"+state.count;
    }
  },

组件内使用getters

<template>
  <div>
    <p>{{$store.getters.showNum}}</p>
  </div>
</template>

或者

<template>
  <div>
    <p>{{showNum}}</p>
  </div>
</template>

<script>
import {mapMutations, mapState} from 'vuex'
import {mapActions, mapGetters} from 'vuex';

export default {
  data () {
    return {}
  },
  computed: {
      ...
      ...mapGetters(['showNum']),
      ...
  },
  ...
}

 

posted @ 2021-01-15 18:45  SvenWayne  阅读(78)  评论(0)    收藏  举报