vuex的基本使用

vuex的基本使用
安装:(可以参考vuex官网:https://vuex.vuejs.org/zh/)
下面是从官网截的图:
vuex的基本使用
(以下是学习时进行的一些小案例,具体项目中不会只建一个store.js文件,而是使用modules模块化。)

新建一个store.js的文件进行配置

	import Vue from 'vue'
	import Vuex from 'vuex'
	
	Vue.use(Vuex)
	
	export default new Vuex.Store({
	   state:{ },
	   getters:{},
	   mutations:{},
	   actions:{},
  })

同时在main,js里引入

import store from './store'

new Vue({
   store
})

1、vuex中的state和mapState

例子:
在store.js中写入数据

 state:{
       count:0,
       todos:[
        {
            id: 1,
            title: 'todo item 1',
            completed: true
          },
          {
            id: 2,
            title: 'todo item 2',
            completed: true
          }, 
          {
            id: 3,
            title: 'todo item 3',
            completed: false
          }
       ]
   },

在vue的文件里获取数据:

<template>
   <div>count的值:{{count}}<br/>{{todos}}</div>
</template>

获取写在计算方法属性里:
方法1:

computed:{
    count(){
      return this.$store.state.count
    },
    todos(){
      return this.$store.state.todos
    }
  }

方法2:

import {mapState} from 'vuex'

export default {
	computed:mapState({
	    count:state => state.count,
	    todos:state => state.todos
	  })
}

方法3:

import {mapState} from 'vuex'

export default {
	 computed:mapState(["count","todos"])
}

这三种方法的显示效果都是一样的,只是书写的复杂程度不同。
运行结果:
vuex的基本使用
2、vuex中的getters和mapGetters
有时候我们需要从 store 中的 state 中派生出一些状态。
使用getters可以对数据进行改变
例子:
在store,js中

export default new Vuex.Store({
   state:{
       count:0,
       todos:[
        {
            id: 1,
            title: 'todo item 1',
            completed: true
          },
          {
            id: 2,
            title: 'todo item 2',
            completed: true
          }, 
          {
            id: 3,
            title: 'todo item 3',
            completed: false
          }
       ]
   },
   getters:{
       count:state => {
           return ++state.count
       },
       completedTodos: state => {
           return state.todos.filter(todo => todo.completed);
        // 这里是使用一个过滤,将todos数组中completed为true的过滤出来。
       },
       completedTodosCount:(state,getters) => {
           return getters.completedTodos.length;
       },
       // 这里传入的第一个是参数state,第二个是外部传过来的参数id
        getTodosById:state => id =>{
            return state.todos.find(todo => todo.id === id);
        }
   },
   mutations:{},
   actions:{},

})

.vue文件里获取数据:

<div class='container'>
	  <div>count的值:{{count}}<br/>
	  {{completedTodos}}   <br/>
	  todos 过滤后的长度{{completedTodosCount}}	  <br/>
	  <div>{{getTodosById(2)}}</div>
	  </div>
</div>

获取方法写在计算属性里:
方法1:

  computed:{
    count(){
      return this.$store.getters.count;
    },
    completedTodos(){
      return this.$store.getters.completedTodos;
    },
    completedTodosCount(){
      return this.$store.getters.completedTodosCount;
    },
    getTodosById(){
      return this.$store.getters.getTodosById;
    }
  }

方法2:

import {mapState,mapGetters} from 'vuex'

export default {
   computed:mapGetters(['count','completedTodos','completedTodosCount','getTodosById'])
 }

这两种方法显示结果也是一样的。
关于getters的测试,这里写了四个方法,分别是显示四种数据:
第一个方法count是显示state中的数据count+1之后的值;
第二个方法completedTodos显示的是过滤出state中completed的值为true的数据;
第三个方法completedTodosCount是显示出completedTodos的长度
第四个方法是根据传入的id来决定显示的数据。
运行结果:
vuex的基本使用
3、vuex中的mutation和mapMutations
类似于事件中的方法!
例:
在store.js中

    mutations:{
        // 不带参数改变
       incrementCount(state){
           state.count++;
       },
       // 携带参数
       decrementCount(state,n) {
           state.count -= n;
       },
       // 携带参数,且参数是对象
       btncrementCount(state,payload){
           state.count -= payload.amount;
       }
   },

在.vue中

<div class='container'>
   {{count}}
   <button @click="decrement(10)"> 带参数减 </button>
   <button @click="increment"> 不带参数加 </button>
   <button @click="btncrement({amount:5})">参数是对象减</button>
</div>

获取数据写在methods方法里:

  methods:{
    decrement(m){
      this.$store.commit("decrementCount",m)
    },
    increment(){
      this.$store.commit("incrementCount");
    },
    btncrement(m){
      this.$store.commit("btncrementCount",m)
    }
  },

写法二与前面两种写法一样,只是将computed换为methods。
vuex的基本使用
注意:一条重要的原则就是要记住 mutation 必须是同步函数

4、vuex中的actions和mapActions
actions里主要进行一些异步额操作,比如请求接口,进行计时器等等。
1------计数器例子:
在store.js中:

 actions:{
      // 这里的意思是执行actions的时候,延迟两秒去提交mutations  
        // (不带参数延迟两秒增加)---写法1:
       incrementCountAsync(context){
          setTimeout(() => {
             //在这里的context相当于vue文件中的this.$store 
              context.commit('incrementCount')
          },2000)
       },
         // (不带参数延迟两秒增加)---写法2:
         incrementCountAsync({commit}){
            setTimeout(() => {
                commit('incrementCount')
            },2000)
         },

        //  携带参数延迟两秒减少
         decrementCountAsync({commit}, payload){
            setTimeout(() => {
                commit('decrementCount',payload)
            },2000)
         }
   },

.vue文件中:

methods:{
    increment(){
       this.$store.dispatch("incrementCountAsync");
    },
    decrement(m){
       this.$store.dispatch("decrementCountAsync",m);
    }
 },

以上可以实现点击按钮之后,延迟两秒,数据改变。
2------请求接口
首先,要引入axios
然后,在store.js中

import Vue from 'vue'
import axios from 'axios'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
   state:{
       count:0,
       todos:[]
   },
   getters:{
       count:state => {
           return ++state.count
       },
       completedTodos: state => {
           return state.todos.filter(todo => todo.completed);
          // 这里是使用一个过滤,将todos数组中completed为true的过滤出来。
       },
   },
   mutations:{
       //    请求接口
       setTodos:(state,todos) => (state.todos = todos)
   },
   actions:{
        //  请求接口
        async fetchTodos({commit}){
            const response = await axios.get('http://jsonplaceholder.typicode.com/todos');
            console.log(response);
            commit('setTodos',response.data);
        }
   },
})

在.vue文件中

<div class='container'>
  <!-- fetchTodos -->
   <div>{{completedTodos}}</div>
   <br/>
   <br/>
   <button @click="fetchTodos">拉取api接口数据</button>
</div>

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

export default {
  methods:{
    fetchTodos(){
      this.$store.dispatch("fetchTodos");
    }
  },
  computed:mapGetters(['count','completedTodos'])
}
</script>

思路分析:在store里进行接口请求;在触发fetchTodos的方法是,会去store的actions里请求接口,然后actions再触发mutations将数据传递给vue文件,而getters则对数据进行了过滤。

actions的简写的方法也和上面是一样的。