Vuex深入浅出,实例讲解。

1 篇文章 0 订阅

Vuex深入浅出,实例讲解。

**Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。
调试工具:vue devtools

Vuex就像眼镜:您自会知道什么时候需要它**

首先创建一个vue项目之后,安装vuex

cnmp  install   vuex  --save

1,state的用法

在store中定义数据 ,在组件中直接使用
在这里插入图片描述

//这个文件在  store包下的index.js就是用来做状态管理的 ,并且将这个文件引入到全局文件中

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

Vue.use(Vuex)


//暴露的第一种方式

export default new Vuex.Store({

//相当于组件中的data,专门用来存放全局的数据,他是一个对象
  state:{
    //定义一个变量
    num:0
  },
  getters:{},
  mutations:{},
  actions:{},
  modules:{}
})

//暴露的第二种方式
/*
const store=new Vuex.Store({

})

export  default store
*/


将创建的store仓库导入到main.js中

在这里插入图片描述

创建一个views的包来创建组件

在这里插入图片描述

Home.vue(第一种方式引入仓库中的值)

<template>
  <div class="home">
<!-- 使用$store  来引入仓库中的值-->
  <h1>Home页面的数字={{$store.state.num}}</h1>

  </div>
</template>

<script>
export default {

}
</script>

About.vue(第二种方式引入仓库中的值)

<template>
  <div class="about">

    <h1>About页面的数字={{num}}</h1>

  </div>
</template>

<script>
export default {
// 使用  computed  来给变量赋值 this指向的是整个vue的实例,直接指向仓库的值
  computed:{
    num(){
      return this.$store.state.num
    }
  }
}
</script>

Btn.vue 组件

<template>
  <div>

  <button @click="$store.state.num++">点击加1</button>
  </div>
</template>

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

    }
  },
}
</script>

<style scoped>

</style>

将各个组件来引入到App.vue组件中

<template>
  <div id="app">


    <Home></Home>
    <About></About>
    <Btn></Btn>
  </div>
</template>

<script>
//引入home  组件
import Home from "./views/Home";

//引入about组件
import About from "./views/About";

//引入btn组件

import Btn from "./views/Btn";
export default {

//  注册组件
  components: {

    Home,
    About,
    Btn

  }
}
</script>

效果显示页面

在这里插入图片描述
2,getters的用法,主要作用就是声明使用,减少代码的冗余,将组件中的统一使用的computed都放在getters里面来操作
这个属性的使用方法,好像看起来 s t o r e . s t a t e . n u m 和 store.state.num 和 store.state.numstore.getters.getNum差不多,但是具体来看的话,一个直接得到的属性的值,一个是通过方法的得到的返回值,类似于面型对象的get方法

store中的index.js页面

//这个文件的作用就是做转状体管理


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

Vue.use(Vuex)


//暴露的第一种方式

export default new Vuex.Store({

//相当于组件中的data,专门用来存放全局的数据,他是一个对象
  state:{

    //定义一个变量
    num:0
  },


  //getters相当于组件中到的computed,getter是全局的,computed是组件内部使用的
  //可以将  computed中的 num(){}   放在getters中统一全局使用
  getters:{
    //第一种方式
   /* num(){
      return this.$store.state.num
    }*/

    //第二种方式  参数为state,指向  上面的state
    getNum(state){
      return state.num
    }

  },



  mutations:{},
  actions:{},
  modules:{}
})



//暴露的第二种方式
/*
const store=new Vuex.Store({

})

export  default store
*/

通过getters的设置之后,我们可以直接通过getters方法直接返回数据,就不直接使用computed属性了,所以Abou.vue可以改为以下形式

<template>
  <div class="about">

    <h1>About页面的数字={{$store.getters.getNum}}</h1>

  </div>
</template>

<script>
export default {

}
</script>

页面展示

在这里插入图片描述
3,mutation的用法
mutation是更改store中的状态的唯一方法是提交mutation,Vuex中mutation是非常类似于每一个mutation都有一个字符串的事件类型和一个回调函数,这个回调函数就是我们实际进行修改的状态的地方,并且他会接收state作为第一个参数,类似于组件中methods,在这个属性中创建方法,来修改state中的属性的值

store中的index.js页面

//这个文件的作用就是做转状体管理
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)


//暴露的第一种方式

export default new Vuex.Store({

//相当于组件中的data,专门用来存放全局的数据,他是一个对象
  state:{

    //定义一个变量
    num:0
  },


  //getters相当于组件中到的computed,getter是全局的,computed是组件内部使用的
  //可以将  computed中的 num(){}   放在getters中统一全局使用
  getters:{
    //第一种方式
   /* num(){
      return this.$store.state.num
    }*/

    //第二种方式  参数为state,指向  上面的state
    getNum(state){
      return state.num
    }

  },

  
  //mutations相当于组件中的methods,但是他不能使用异步方法(定时器,axios),这个属性存放方法来修改state属性的值
  mutations:{
    //创建一个方法,来修改state属性的值,参数就是state
    //payload是一个形参,如果组件在commit时,有传这个参数过来,就存在,如果没有传参过来,就是undefined
    increase(state,payoad){
      state.num+=payoad ? payoad :1;
    }
  },

  
  actions:{},
  modules:{}
})



//暴露的第二种方式
/*
const store=new Vuex.Store({

})

export  default store
*/

Btn.vue页面代码

<template>
  <div>

    <button @click="addFn">点击加1</button>
  </div>
</template>

<script>
export default {
  methods: {
    addFn(){
      //调用仓库中的mutation属性中的方法,这时不传payload,每次只加1
      this.$store.commit('increase')
     /* //这个是加入payload的参数,每次加6
     *this.$store.commit('increase',6)
     */

    }
  }
}
</script>

<style scoped>

</style>

页面效果

在这里插入图片描述
4,actions的用法
actions属性是专门处理异步请求的,实际修改状态值的是mutation
action函数 接收一个与store实例具有相同方法的和属性的context对象,因此你可以调用context.commit,提交一个mutation,或者通过
context.getters 来获取state和 getters。在之后的Moudles被介绍到的时候,你就知道,context对象为什么不是store实例本身了
简单来说就是有了context对象就可以使用commit

store中的index.js页面,在 action属性中添加异步的犯法,实际修改状态值的是mutation

//这个文件的作用就是做转状体管理
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)


//暴露的第一种方式

export default new Vuex.Store({

//相当于组件中的data,专门用来存放全局的数据,他是一个对象
  state:{
    //定义一个变量
    num:0
  },


  //getters相当于组件中到的computed,getter是全局的,computed是组件内部使用的
  //可以将  computed中的 num(){}   放在getters中统一全局使用
  getters:{
    //第一种方式
   /* num(){
      return this.$store.state.num
    }*/

    //第二种方式  参数为state,指向  上面的state
    getNum(state){
      return state.num
    }

  },


  //mutations相当于组件中的methods,但是他不能使用异步方法(定时器,axios),这个属性存放方法来修改state属性的值
  mutations:{
    //创建一个方法,来修改state属性的值,参数就是state
    //payload是一个形参,如果组件在commit时,有传这个参数过来,就存在,如果没有传参过来,就是undefined
    increase(state,payoad){
      state.num+=payoad ? payoad :1;
    },
    //创建一个方法来修改状态值
    decrease(state){

      state.num--;
    }

  },


  //actions属性是专门处理异步请求的,实际修改状态值的是mutations
  //action函数  接收一个与store实例具有相同方法的和属性的context对象,因此你可以调用context.commit,提交一个mutation,或者通过
  //context.getters 来获取state和 getters。在之后的Moudles被介绍到的时候,你就知道,context对象为什么不是store实例本身了
  //简单来说就是有了context对象就可以使用commit

  actions:{
    //点击减1按钮,实现 时间过去一秒之后再  执行减1的操作的异步方法
    decreaseAsync(context){
      context.commit('decrease')
    }
  },
  modules:{}
})



//暴露的第二种方式
/*
const store=new Vuex.Store({

})

export  default store
*/

About.vue使用映射来给拿仓库中的store的state中的getNumf方法 mapGetters

<template>
  <div class="about">

<!--    直接访问仓库中的getters中的方法    不须要添加 computed-->
<!--    <h1>About页面的数字={{$store.getters.getNum}}</h1>-->


    <!--使用映射来获取 getters方法中的方法,必须要添加 computed-->
    <h1>About页面的数字={{getNum}}</h1>


  </div>
</template>

<script>

//使用映射导入  vuex中所有的getters都导入过来
import { mapGetters }  from  'vuex'

export default {

  computed:{
    ...mapGetters(['getNum'])
  }

}
</script>

Home.vue使用映射来给拿仓库中的store的getters中的num值 mapState

<template>
  <div class="home">
<!-- 使用$store  来引入仓库中的值  不须要添加 computed-->
<!--  <h1>Home页面的数字={{$store.state.num}}</h1>-->

<!--    使用映射的方法来获取 state中的值,使用的是mapState数组  必须要添加 computed属性-->
  <h1>Home页面的数字={{num}}</h1>

  </div>
</template>

<script>

//{ mapState }   是把整个vuex中的state整个映射过来
import { mapState } from 'vuex'

export default {

//  使用  computed属性
  computed:{
    //使用这个方法来拿到  mapState,mampstate的参数就是一个数组,数组的成员就是  仓库中给store的state属性
    ...mapState(['num'])
  }
}
</script>

Btn.vue 使用映射来得到mutation 和action中的方法 mapMutations , mapActions

<template>
  <div>

<!--    不用映射方法-->

<!--    <button @click="addFn">点击加1</button>-->
<!--&lt;!&ndash;    可以指直接访问 仓库中mutations中的方法&ndash;&gt;


    <button @click="$store.commit('decrease')">点击减1</button>-->

<!--    <button @click="reduceFn">点击减1</button>-->





<!--    使用映射方法-->


    <button @click="increase()">点击加1</button>
    <button @click="decreaseAsync()">点击加1</button>


  </div>
</template>

<script>

//导入映射,再调用的时候要 放在  methods属性中
import { mapMutations , mapActions} from 'vuex'

export default {
  methods: {
    addFn(){
      //调用仓库中的mutation属性中的方法,这时不传payload,每次只加1
      this.$store.commit('increase')
     /* //这个是加入payload的参数,每次加6
      this.$store.commit('increase',6)*/

    },

    reduceFn(){
      //执行异步方法 action中的使用dispatch来执行
      this.$store.dispatch('decreaseAsync');
    },




    /*
    * 调用映射中的方法
    * */
    ...mapActions(['decreaseAsync']),
    ...mapMutations(['increase'])

  }
}
</script>

<style scoped>

</style>

显示效果

在这里插入图片描述
5,仓库拆分写法,将仓库中的属性都独立出来

strore中的所有属性,都可以拆分成单独的js文件来书写。

在这里插入图片描述

index.js文件

//这个文件的作用就是做转状体管理
import Vue from 'vue'
import Vuex from 'vuex'

//导入拆分的state
import state from "./state";
//导入拆分的getters
import getters from "./getters";
//导入拆分的mutaion
import mutations from "./mutations";
//导入拆分的actions
import actions from "./actions";
//导入拆分的moudels
import modules from "./modules";

//表示使用 vuex
Vue.use(Vuex)




//暴露的第一种方式

export default new Vuex.Store({

//相当于组件中的data,专门用来存放全局的数据,他是一个对象
  state,


  //getters相当于组件中到的computed,getter是全局的,computed是组件内部使用的
  //可以将  computed中的 num(){}   放在getters中统一全局使用
  getters,


  //mutations相当于组件中的methods,但是他不能使用异步方法(定时器,axios),这个属性存放方法来修改state属性的值
  mutations,


  //actions属性是专门处理异步请求的,实际修改状态值的是mutations
  //action函数  接收一个与store实例具有相同方法的和属性的context对象,因此你可以调用context.commit,提交一个mutation,或者通过
  //context.getters 来获取state和 getters。在之后的Moudles被介绍到的时候,你就知道,context对象为什么不是store实例本身了
  //简单来说就是有了context对象就可以使用commit

  actions,




  modules
})



//暴露的第二种方式
/*
const store=new Vuex.Store({

})

export  default store
*/

state.js文件

export default {
  //定义一个变量
  num:0
}

getters.js文件

export default {
  //第一种方式
  /* num(){
     return this.$store.state.num
   }*/

  //第二种方式  参数为state,指向  上面的state
  getNum(state){
    return state.num
  }

}

mutations.js文件

export default {
  //创建一个方法,来修改state属性的值,参数就是state
  //payload是一个形参,如果组件在commit时,有传这个参数过来,就存在,如果没有传参过来,就是undefined
  increase(state,payoad){
    state.num+=payoad ? payoad :1;
  },
  //创建一个方法来修改状态值
  decrease(state){

    state.num--;
  }

}

actions.js文件

export default {
  //点击减1按钮,实现 时间过去一秒之后再  执行减1的操作的异步方法
  decreaseAsync(context){
    context.commit('decrease')
  }
}

modules.js文件

export default {
  
}

6,modules
我们的store可以认为是一个主模块,他下边可以分解为多个子模块,子模块可以单独拎出来写,写完再导入主模块中。
就比如users模块举例,users模块也可以拥有state,getters,mutations,和actions,所有的属性和方法该怎么写就怎么写。但是再users中index.js文件中,需要写入
namespace:true 命名空间
然后在store的index.js中引入到moudles中
在组件中获取值的方法

 $store.state.users.nickName

在组件中引入子模块方法

//在组件触发子模块的方法:

<script>
//{ mapState }   是把整个vuex中的state整个映射过来
import { mapState,mapMutations } from 'vuex'


//使用methods来访问  store中的方法
  methods:{
    //调用user模块中的chanegeNickName的方法,并且需要指定确定路径的方法
    ...mapMutations({
      'changeNickName':"changeNickName"
    })


</script>

实例说明

在这里插入图片描述

主模块index.js

//这个文件的作用就是做转状体管理
import Vue from 'vue'
import Vuex from 'vuex'

//导入拆分的state
import state from "./state";
//导入拆分的getters
import getters from "./getters";
//导入拆分的mutaion
import mutations from "./mutations";
//导入拆分的actions
import actions from "./actions";

import modules from "./modules";


//表示使用 vuex
Vue.use(Vuex)




//暴露的第一种方式

export default new Vuex.Store({

//相当于组件中的data,专门用来存放全局的数据,他是一个对象
  state,


  //getters相当于组件中到的computed,getter是全局的,computed是组件内部使用的
  //可以将  computed中的 num(){}   放在getters中统一全局使用
  getters,


  //mutations相当于组件中的methods,但是他不能使用异步方法(定时器,axios),这个属性存放方法来修改state属性的值
  mutations,


  //actions属性是专门处理异步请求的,实际修改状态值的是mutations
  //action函数  接收一个与store实例具有相同方法的和属性的context对象,因此你可以调用context.commit,提交一个mutation,或者通过
  //context.getters 来获取state和 getters。在之后的Moudles被介绍到的时候,你就知道,context对象为什么不是store实例本身了
  //简单来说就是有了context对象就可以使用commit

  actions,


//这是一个主模块,在这个主模块可以引用 子模块
  modules,

})



//暴露的第二种方式
/*
const store=new Vuex.Store({

})

export  default store
*/

主模块moudles.js

import users from './users/index'

export default {
  users
}

users模块index.js

import state from "./state";

import getters from "./getters";

import mutations from "./mutations";

import actions from "./actions";



export default {

//命名空间,可以通过users(包名)来访问 属性
 namespace:true,


  state,



  getters,



  mutations,



  actions,


  modules:{}
}

users子模块的state.js文件

export default {
  nickName:'孙悟空',
  token:'jiasfjasdfj'
}

users子模块的mutations.js文件

//创建一个方法来将孙悟空改为猪八戒
export default {

  changeNickName(state){
    state.nickName='猪八戒';
  }

}

users子模块的acitons.js 和 getters.js都为空

在这里插入图片描述

Home.vue组件

在这里插入图片描述

<template>
  <div class="home">
<!-- 使用$store  来引入仓库中的值  不须要添加 computed-->
<!--  <h1>Home页面的数字={{$store.state.num}}</h1>-->

<!--    使用映射的方法来获取 state中的值,使用的是mapState数组  必须要添加 computed属性-->
  <h1>Home页面的数字={{num}}</h1>
    <li>{{$store.state.users.nickName}}</li>
    <button @click="changeNickName()">将孙悟空改为猪八戒</button>

  </div>
</template>

<script>

//{ mapState }   是把整个vuex中的state整个映射过来
import { mapState,mapMutations } from 'vuex'

export default {

//  使用  computed属性来访问  store中属性
  computed:{
    //使用这个方法来拿到  mapState,mampstate的参数就是一个数组,数组的成员就是  仓库中给store的state属性
    ...mapState(['num'])
  },

  //使用methods来访问  store中的方法
  methods:{
    //调用user模块中的chanegeNickName的方法,并且需要指定确定路径的方法
    ...mapMutations({
      'changeNickName':"changeNickName"
    })



  }
}
</script>

效果演示

在这里插入图片描述

在这里插入图片描述
7,modules_type
将所有的modutations中的方法归纳起来。

主模块中index.js文件

在这里插入图片描述

//这个文件的作用就是做转状体管理
import Vue from 'vue'
import Vuex from 'vuex'

//导入拆分的state
import state from "./state";
//导入拆分的getters
import getters from "./getters";
//导入拆分的mutaion
// import mutations from "./mutations";
import mutations from "./mutations_type";
//导入拆分的actions
import actions from "./actions";

import modules from "./modules";


//表示使用 vuex
Vue.use(Vuex)




//暴露的第一种方式

export default new Vuex.Store({

//相当于组件中的data,专门用来存放全局的数据,他是一个对象
  state,


  //getters相当于组件中到的computed,getter是全局的,computed是组件内部使用的
  //可以将  computed中的 num(){}   放在getters中统一全局使用
  getters,


  //mutations相当于组件中的methods,但是他不能使用异步方法(定时器,axios),这个属性存放方法来修改state属性的值
  mutations,


  //actions属性是专门处理异步请求的,实际修改状态值的是mutations
  //action函数  接收一个与store实例具有相同方法的和属性的context对象,因此你可以调用context.commit,提交一个mutation,或者通过
  //context.getters 来获取state和 getters。在之后的Moudles被介绍到的时候,你就知道,context对象为什么不是store实例本身了
  //简单来说就是有了context对象就可以使用commit

  actions,


//这是一个主模块,在这个主模块可以引用 子模块
  modules,

})



//暴露的第二种方式
/*
const store=new Vuex.Store({

})

export  default store
*/

mutations.js文件

在这里插入图片描述

export const MUTATIONS_TYPE={
    INCREASE:'increase',
    DECREASE:'decrease'
}


export default {
  //创建一个方法,来修改state属性的值,参数就是state
  //payload是一个形参,如果组件在commit时,有传这个参数过来,就存在,如果没有传参过来,就是undefined
  [MUTATIONS_TYPE.INCREASE](state,payoad){
    state.num+=payoad ? payoad :1;
  },
  //创建一个方法来修改状态值
  [MUTATIONS_TYPE.DECREASE](state){

    state.num--;
  }

}

About.vue组件

在这里插入图片描述

<template>
  <div class="about">

<!--    直接访问仓库中的getters中的方法    不须要添加 computed-->
<!--    <h1>About页面的数字={{$store.getters.getNum}}</h1>-->


    <!--使用映射来获取 getters方法中的方法,必须要添加 computed-->
    <h1>About页面的数字={{getNum}}</h1>
    <button @click="increase()">Aboute页面的按钮,点击加1</button>


  </div>
</template>

<script>

//使用映射导入  vuex中所有的getters都导入过来
import { mapMutations,mapGetters}  from  'vuex'
import {MUTATIONS_TYPE} from "../store/mutations_type";

export default {

  computed:{
    ...mapGetters(['getNum'])
  },
  methods:{


//第一种方式
    ...mapMutations([MUTATIONS_TYPE.INCREASE])
    
    
    
    
    
    //第二种方式
    // increase() {
    //   this.$store.commit(MUTATIONS_TYPE.INCREASE)
    // }


  }

}
</script>

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值