原创 Vue个人查漏补缺笔记day13 -- Vuex基础使用(state、mutations、actions、getters、module、nameSpaced)

为什么会有Vuex

Vuex是转为vue应用程序开发的状态管理模式,采用集中式存储管理应用的所有组件的状态

  • 作用:采用集中式管理组件依赖的共享数据,解决不同组件数据共享

主要组成

  • state:共享状态数据
  • mutations:修改状态数据,且只执行同步代码操作
  • actions:执行异步操作,提交给mutations修改状态数据
  • getters:处理state中的数据
  • module:实现Vuex模块化

state/mutations/actions/组件间的关系

原创 Vue个人查漏补缺笔记day13 -- Vuex基础使用(state、mutations、actions、getters、module、nameSpaced)_第1张图片


初始使用Vuex

//在脚手架的main.js文件中
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'

Vue.use(Vuex)

//实例化Vuex
const store = new Vuex.store({
     
//在这里定义state/mutations/actions等,且均为对象形式
	state:{
     },
	mutations:{
     },
	actions:{
     }
})

new Vue({
     
  render: h => h(App),
  //注入Vuex
  store
}).$mount('#app')



state使用

state是放置公共状态的属性
定义state

//main.js
const store = new Vuex.store({
     
//在这里定义state/mutations/actions等,且均为对象形式
	state:{
     
		num:0
	}
})

//test.vue
//在组件中获取vuex的state状态数据 有两种方法
//1.通过$store(挂载到Vue中接收Vuex.store的常量名).state获取
//$store.state.num
//2.通过Vuex提供的辅助方法 mapState 获取
//import {mapState} from 'vuex',然后在computed属性中定义
<template>
	<div>原始方法拿count:{
     {
      $store.state.num }}</div>//0
	<div>用computed方法拿num:{
     {
      getNum }}</div>//0
	<div>用辅助函数+computed方法拿num:{
     {
      num }}</div>//0
</template>

<script>
import {
      mapState} from "vuex";
export default {
     
	computed: {
     
		...mapState(["num"]),
		getNum(){
     
			return this.$store.state.num
		}
	}
};



mutations使用

state数据的修改只能通过mutations,并且mutations必须是同步更新

  • 定义mutations
//main.js
const store = new Vuex.store({
     
//在这里定义state/mutations/actions等,且均为对象形式
	state:{
     
		num:0
	},
	mutations:{
     
		// 方法里参数 第一个参数是当前store的state属性
		addNum(state){
     
			state.num ++
		},
		//第二个参数是载荷 运输参数 调用mutaiions的时候 可以传递参数 传递载荷
		numPlusVar(state,var){
     
			state.num += var
	}
})


//使用
//test.vue
//mutations修改vuex的state状态数据 有两种方法,类似于state
//1.通过$store.commit('方法名')方法获取
//2.通过Vuex提供的辅助方法 mapMutations获取
//import  {mapMutations } from 'vuex',然后在methods属性中定义
//如果是带参的,则在方法后面传参即可
<template>
	<div>{
     {
      num }}</div>//0
	<button @click="numAdd1">用commit方法+1</button>
	<button @click="numAddVar">用commit方法传参修改</button>
	<button @click="addNum">用mapMutations方法+1</button>
	<button @click="numPlusVar(100)">用mapMutations方法传参修改</button>
</template>

<script>
import {
      mapState,mapMutations } from "vuex";
export default {
     
	methods:{
     
	//方法1
		numAdd1(){
     
			this.$store.commit('addNum')
		},
		numAddVar(){
     
			this.$store.commit('numPlusVar',100)
		},
	//方法2 -- mapMutations 传入数组,定义函数
	...mapMutations(['addNum','numPlusVar'])
	},
	computed: {
     
		...mapState(["num"])
	}
};



actions使用

mutations是同步更新数据,actions则负责进行异步操作

  • 定义actions
//main.js
const store = new Vuex.store({
     
//在这里定义state/mutations/actions等,且均为对象形式
	state:{
     
		num:0
	},
	mutations:{
     
		numPlusVar(state,var){
     
			state.num += var
		}
	},
	actions:{
     
		//  获取异步的数据 第一个参数context表示当前的store的实例 可以通过 context.state 获取状态 也可以通过context.commit 来提交mutations, 也可以 context.diapatch调用其他的action
		asyncAddNum(context,var){
     
			 setTimeout(function(){
     
     	 	  // 一秒钟之后 去修改state中的num,带参
     	 	  context.commit('numPlusVar', var)
 		     }, 1000)
		}
	}
})

//使用
//有两种方式
//1.通过$store.dispatch('方法名')来使用
//2.通过辅助函数mapActions来使用
//import { mapActions } from 'vuex',然后在methods中定义
<template>
	<div>{
     {
      num }}</div>//0
	<button @click="asyncChange">用原始dispacth方法异步修改</button>
	<button @click="asyncAddNum(100)">用mapActions方法异步修改</button>//一秒后+100
</template>


<script>
import {
      mapState,mapActions } from "vuex";
export default {
     
	computed: {
     
		...mapState(["num"])
	},
	methods:{
     
		//方法1
		asyncChange(){
     
			//一秒后+10
			this.$store.dispatch('asyncAddNum',10)
		},
		//方法2
		...mapActions(['asyncAddNum'])
	}



getters使用

除了state之外,有时我们还需要从state中派生出一些状态,这些状态是依赖state的,此时会用到getters
例如:state中有数组list:[0,1,2,3,4,5,6,7,8,9],但只想要其中大于3的数值,如果不用getters,那么就需要先获取再修改,而getter可以先处理数据,再通过返回值返回数据

  • 定义getters
//main.js
const store = new Vuex.store({
     
	state:{
     
		list:[0,1,2,3,4,5,6,7,8,9]
	},
	getters:{
     
		   // getters函数的第一个参数是 state
  		  // 必须要有返回值
  		  //采用es6的简写
  		  listFilter:state => state.list.filter(item => item > 3)
	}
})

//使用
//两种方法,类似于state
//1.通过$store.getters.函数名,或是在computed中定义
//2.通过辅助函数mapGetters

<template>
	<div>原始方法{
     {
      $store.getters.listFilter }}</div>//[4,5,6,7,8,9]
	<div>原始方法+computed{
     {
      filtedList }}</div>//[4,5,6,7,8,9]
	<div>mapActions方法{
     {
      listFilter }}</div>//[4,5,6,7,8,9]
</template>


<script>
import {
      mapActions } from "vuex";
export default {
     
	computed: {
     
		filtedList(){
     
		//方法1
			return this.$store.getters.listFilter 
		},
		//方法2
		...mapActions(['listFilter'])
	},
</script>



module使用

由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。简而言之:如果把所有的状态都放在state中,当项目变得越来越大的时候,Vuex会变得越来越难以维护,由此,又有了Vuex的模块化
原理:
原创 Vue个人查漏补缺笔记day13 -- Vuex基础使用(state、mutations、actions、getters、module、nameSpaced)_第2张图片

假如: 有两个模块,user模块用来存储token,setting模块用来存储用户名username

  • 定义模块
//main.js
const store  = new Vuex.Store({
     
  modules: {
     
    user: {
     
       state: {
     
         token: '12345'
       }
    },
    setting: {
     
      state: {
     
         name: 'Thomas'
      }
    }
  })


//在模块里面的state是全局vuex可用的,所以获取有两种方法
//1.通过$store.state.模块名称.模块中的state名称
//$store.state.user.token / $store.state.setting.name
//2.通过store中的根getters来定义
 getters: {
     
   token: state => state.user.token,
   name: state => state.setting.name
 } 

//使用
<template>
	<div>原始方法{
     {
      $store.state.user.token }}</div>//'12345'
	<div>mapGetters方法{
     {
      token }}</div>//'12345'
	<div>mapGetters方法{
     {
      name }}</div>//'Thomas'
</template>

<script>
import {
      mapGetters } from "vuex";
export default {
     
	computed: {
     
		//方法2
		...mapGetters(['token','name'])
	},
</script>



命名空间 – namespaced

默认情况下,module模块内部的 action、mutation 和 getter 是注册在全局命名空间的——这样使得多个模块能够对同一 mutation 或 action 作出响应。
简而言之:模块之间的 action、mutation 和 getter 其实并没有区分,都可以直接通过全局的方式调用
原创 Vue个人查漏补缺笔记day13 -- Vuex基础使用(state、mutations、actions、getters、module、nameSpaced)_第3张图片
例如:

  modules: {
     
    user: {
     
       state: {
     
         token: '12345'
       },
       mutations:{
     
       	 //  这里的state表示的是user的state
         updateToken (state) {
     
            state.token = '6789'
       }
    },
}

<template>
	<div>{
     {
      $store.state.user.token }}</div>//'12345'
	<button @click='updateToken'>修改token</button>
</template>

<script>
import {
      mapMutations } from "vuex";
export default {
     
	methods:{
     
		...mapMutations(['updateToken'])//修改module中user的token
	}
}
</script>

但是,如果我们想保证内部模块的高封闭性,我们可以采用nameSpaced:true来进行设置

 modules: {
     
    user: {
     
    	nameSpaced:true,//命名空间
      	state: {
     
         token: '12345'
       },
       mutations:{
     
       	 //  这里的state表示的是user的state
         updateToken (state) {
     
            state.token = '6789'
       }
    },
}

//此时,组件中的	...mapMutations(['updateToken'])将会失效

如果需要使用命名空间中的mutations
方法1:mapMutations带上模块名

...mapMutations(['user/updateToken']),
changeToken(){
     
	this['user/updateToken']()
}

//template
<button @click='changeToken'>修改token</button>

方法2:使用辅助函数createNamespacedHelpers来创建基于某个命名空间辅助函数

import {
       createNamespacedHelpers } from 'vuex' //引入辅助函数
const {
      mapMutations } = createNamespacedHelpers('user') // 拿到模块user,然后拿到user中的mutations 
//相当于 const mapMutations =  createNamespacedHelpers('user').mutations 
export default {
     
	methods:{
     
		...mapMutations(['updateToken ']) //user中的mutations
	}
}

<div>{
     {
     $store.state.user.token}}</div>
<button @click="changeToken">用createNamespacedHelpers来调用命名空间中的mutations</button>

你可能感兴趣的:(javascript,vue.js,vue)