Vuex

基本概念

Vuex 是状态管理工具。集中式存储管理 应用的所有组件的状态,可以简单的将其看成把需要多个组件共享的变量全部存储在一个对象里面,并将这个变量放在顶层的Vue实例中,让其他组件可以使用,并且实现了响应式。
那么什么状态需要多个组件间共享呢?
例如:用户的登录状态、用户名称、头像、地理位置信息 以及 商品的收藏、购物车中的物品等。

安装

npm install vuex --save

基本结构

├── src
  ├── index.js       入口js
  ├── App.vue
  ├── components
  │ ├── HelloWorld.vue
  │ └── …
  └── store
   ├── index.js   我们组装模块并导出 store 的地方
   ├── mutations-types.js    定义类型常量

index.js:

import Vue from 'vue';
import store from './store';
import App from './App.vue';

Vue.config.Vue.config.productionTip = false;

new Vue({
  el: '#root',
  store,  // 挂载之后,每个组件都有一个 $store 对象
  render: h => h(App)
});
store/index.js:

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

//安装插件
Vue.use(Vuex)

//创建并导出对象store
export default new Vuex.Store({
  state:{
  	counter : 0
  },
  mutations:{},
  actions:{},
  getters:{},
  modules:{}
})

每个组件都有一个 $store 对象 , $store 对象有 state 、mutation 、actions 、getters 、modules 属性, 所以各个组件可以通过 ** $store . state . counter ** 来使用此处定义的属性或者方法;通过 this. $state . commit ( mutation 中定义的方法 ) 来修改状态。

【注意】我们通过提交mutation 的方式修改状态,而不是直接更改 $store . state . counter ,这是为了devtools 该工具更明确的追踪状态的变化

getters

getters 相当于计算属性

使用方式一:内部定义的方法默认的参数是 state

getters : {
	powerCounter (state) {
		return state.counter * state.counter
	}
}
<h2>{ $store.getters.powerCounter }</h2>

使用方式二:还能传递另一种参数,就是 getters 本身

getters : {
	//筛选年龄大于20的学生
	more20stu (state) {
		return state.students.filters(s => s.age > 20)
	},
	//求出年龄大于20的学生的数量
	more20stuLength ( state , getters ) {
		return getters.more20stu.length
	}
}
<h2>{ $store.getters.more20stu }</h2>
<h2>{ $store.getters.more20stuLength }</h2>

使用方式三:getters 本身不能传递其他参数,若想传递其他参数,需要return 一个函数

getters : {
	//筛选年龄大于age的学生,age 为传递的参数
	moreAgestu (state) {
		return function (age) {
				return state.students.filters(s => s.age > age)
		}
	},
}
<!-- 年龄大于18 -->
<h2>{ $store.getters.moreAgestu(18) }</h2>

mutations

更改 store 中state 状态的唯一方式是 : 提交 mutation
mutation 中的方法必须是 同步 方法
mutation 的默认第一个参数是 state

使用方式

使用方式一:不传自定义参数
1、定义mutation:

mutations : 
	increment ( state ) {     //   state 是默认参数
		state.counter ++
	}
}

2、在事件发生的组件中定义函数,在此函数内部提交mutation:

	methods : {
		addition () {
			this.$store.commit ( ' increment ' )
		}
	}

使用方式二:传一个自定义参数
1、定义mutation:

mutations : 
	increment ( state  , num) {
		state.count += num
	}
}

2、在事件发生的组件中定义函数,在此函数内部提交mutation:

	methods : {
		addition ( num ) {
			this.$store.commit ( ' increment ' , num )
		}
	}

使用方式三:传多个自定义参数,需要传递一个 payload 对象
1、定义mutation:

mutations : 
	increment ( state  , payload) {
		state.counter +=  payload.num
	}
}

2、在事件发生的组件中定义函数,在此函数内部提交mutation:

	methods : {
		addition ( num ) {
			this.$store.commit ( {
			type :  ' increment ',
			num
			} )
		}
	}

类型常量

在 store 文件下新建一个 mutations-types.js

store/mutations-types.js:

export const INCREMENT = 'increment'
store/index.js:

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

//导入mutations的类型常量
import {
	INCREMENT
} from './mutations-type.js'

//安装插件
Vue.use(Vuex)

//创建并导出对象store
export default new Vuex.Store({
  state:{
  	counter : 0
  },
  mutations:{
  	// 使用类型常量
  	[INCREMENT](state){
  		state.counter ++
  	}
  },
  actions:{},
  getters:{},
  modules:{}
})
App.vue:

<script>
	//导入mutations的类型常量
	import {
		INCREMENT
	} from './store/mutations-type.js'

	export default {
		name: 'App',
		data(){},
		methods : {
 		addition ( num ) {
 			this.$store.commit ( INCREMENT )  // 使用类型常量
 		}
 	}
	}
</script>

actions

actions 中的默认第一个参数context
actions 中的方法必须是 异步 方法
mutation 更改属性,actions 用 commit 提交mutation , 组件里的方法用 dispatch 提交 actions

基本使用方法

store/index.js:

mutations : {
	updateInfo (state) {
		return state.info.name = 'sea'
	}
},
actions : {
	aUpdateInfo (context) {
		setTimeout( () => {
			context.commit('updateInfo') // commit( ' mutations方法 ' )
		} , 1000)
	}
}
App.vue:

methods : {
	update(){
		this.$store.dispatch('aUpdateInfo')  // dispatch( ' actions方法 ' )
	}
}

actions 传递参数

actions 的第二个参数payload , 当传递多个参数时,就传递一个 payload 对象

store/index.js:

mutations : {
	updateInfo (state) {
		return state.info.name = 'sea'
	}
},
actions : {
	//传递 payload 形参
	aUpdateInfo (context , payload) {
		setTimeout( () => {
			context.commit('updateInfo') // commit( ' mutations方法 ' )
			console.log( payload.message )
		} , 1000)
	}
}
App.vue:

methods : {
	update(){
		//传递 payload 实参
		this.$store.dispatch('aUpdateInfo' , {
			message : 'Hello',
			fn : function(){}
		})  // dispatch( ' actions方法 ' )
	}
}

异步 actions 执行成功后,通知组件并执行其他代码

利用 Promise:

store/index.js:

mutations : {
	updateInfo (state) {
		return state.info.name = 'sea'
	}
},
actions : {
	//传递 payload 形参
	aUpdateInfo (context , payload) {
	
		return new Promise(resolve , reject ){
		
			setTimeout( () => {
				context.commit('updateInfo') // commit( ' mutations方法 ' )
				console.log( payload );
				
				resolve('执行成功')
			} , 1000)
		}
	}
}
App.vue:

methods : {
	update(){
		//传递 payload 实参
		this.$store
			.dispatch('aUpdateInfo' , "我是 payload ")
			
			.then(
				res => { console.log (res) }
			)
	}
}

优化:Vuex的辅助函数mapState,mapGetters, mapActions, mapMutations用法

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

优化为:

import { mapState, mapMutations, mapGetters, mapActions } from 'vuex'

computed : {
	...mapState(['count']),
	...mapGetters(['evenOrodd'])
}
methods : {
	...mapMutations({
		increment : 'INCREMENT',
		decrement : 'DECREMENT'
	})
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值