Vue 学习笔记 05——状态管理Vuex

Vue 学习笔记 01——iview

Vue 学习笔记 02

Vue 学习笔记 03——组件篇

Vue 学习笔记 04——TabPanel

Vue 学习笔记 05——状态管理Vuex

===================================正文分割线==================================

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。流程如下官网图所示:

Vue 学习笔记 05——状态管理Vuex_第1张图片

基础知识

1.  store 

Vuex 的核心就是 store(仓库),它就像一个容器,包含着应用中大部分的状态 state .Vuex与全局对象的不同在于:

1)Vuex状态存储为响应式的,store中的状态发生改变时,相应的组件也会更新

2)不能直接改变store中的state,唯一途径是显示的提交(commitmutation。这样方便跟踪每一个状态的变化

 

2.  简单的创建store

1)在main.js中引入创建store

     * 创建后可以通过 store.state 来获取状态对象,以及通过 store.commit 方法触发状态变更

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

const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment (state) {
      state.count++
    }
  }
})

 2) 然后在Vue实例中,提供创建好的store,如此便可在组件中访问到this.$store中的property

new Vue({
  el: '#app',
  store: store,
})

3)现在可以在计算属性computed中,返回状态

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

4)当状态需要改变时,可通过在组件的 methods提交(commit) mutation

methods: {
  increment() {
    this.$store.commit('increment')
    console.log(this.$store.state.count)
  }
}

3.四个核心概念

1)State

     a)所有的状态定义在state对象中;

     b)从 store 实例中 读取状态 最简单的方法就是在 计算属性 中返回某个状态;

     c)Vuex提供一种机制将状态从根组件“注入”到每一个子组件中( 需要调用Vue.use(Vuex) ):

const app = new Vue({
  el: '#app',
  // 把 store 对象提供给 “store” 选项,这可以把 store 的实例注入所有的子组件
  store,
  components: { Counter },
  template: `
    
` })

       通过根实例注册的store,改store实例会注入到根组件下的所有子组件,且子组件能通过this.$store访问到,如下:

const Counter = {
  template: `
{{ count }}
`, computed: { count () { return this.$store.state.count } } }

     d)辅助函数 mapState

           当一个组件要获取多个状态的时候,可使用  mapState 辅助函数帮助我们生成计算属性,这样简洁一些。

           当映射的计算属性的名称与 state 的子节点名称相同时,我们也可以给 mapState 传一个字符串数组。

import { mapState, mapGetters } from 'vuex'

...
computed:{
	...mapState(['userInfo']),
	...mapGetters(['memberInfo'])
},
...

2)Getter

可以理解为是获取数据的,有时候我们需要从 store 中的 state 中派生出一些状态,例如根据userState的值显示用户等级:

  a)Getter 接受 state 作为其第一个参数

export default{
	memberInfo(state){
		switch (state.userStatus){
			case 0:
					return '普通会员';
					break;
			case 1:
					return 'VIP会员';
					break;		
			case 2:
					return '高级V'+ state.vipLevel +'会员';
					break;
			default:
					return '普通会员';
					break;

		}

	}
}

   b)使用时,也可用辅助函数 mapGetters

Vue 学习笔记 05——状态管理Vuex_第2张图片

3)Mutation

      a)它是更改 Vuex store 中状态的唯一方法是提交 mutation. 而 mutation 类似一个事件,每一个 mutation 都有一个字符串的事件类型和一个回调函数,回调函数就是我们状态要进行更改的地方,并且它会接受 state 作为第一个参数。

      b)Mutation 必须是同步函数

例如:登录后修改userStatus

//登录组件的login()中
//commit中有两个参数
//第一个参数,对应的是mutation中的函数名
//第二个参数,多数情况下是一个对象
self.$store.commit('setMemberInfo',{
	userStatus:0,
	vipLevel:0
});
//mutations.js中
export default{
	//登录调用,重置用户信息
	login(state, v){
		state.userInfo = v;
	},

	//重新修改用户等级状态
    //第一个参数接收state
    //第二个参数接收组件中commit传来的值
	setMemberInfo(state,v){
		state.userStatus = v.userStatus;
		state.vipLevel =v.vipLevel;
	}
}

4)Action

Action 类似于 mutation,不同在于:

  • Action 提交的是 mutation,而不是直接变更状态。
  • Action 可以包含任意异步操作。

 a)注册一个简单的 action:

const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment (state) {
      state.count++
    }
  },
  actions: {
    increment (context) {
      context.commit('increment')
    }
  }
})

由于 Action函数 接收一个 与store实例具有相同方法和属性 context 对象,因此可以用context.commit来提交一个mutation,

而实践中,我们会经常用到 ES2015 的 参数解构 来简化代码(特别是我们需要调用 commit 很多次的时候),如下案例:

actions: {
  increment ({ commit }) {
    commit('increment')
  }
}
//actions.js中
export default{
    //分发的时候有传值的情况
	buyVip({commit},e){
		//mock api交互
		return new Promise((resolve,reject)=>{
			setTimeout(()=>{
				//修改本地state
				commit('setMemberInfo',{
					userStatus:e.userStatus,
					vipLevel:e.vipLevel
				})
				resolve('购买成功')

			},1000)
		})
		
	},
    //分发的时候无值,但需要使用state的情况
	getFreeVip({commit,state}){
		//mock api 交互
		return new Promise(function(resolve,reject) {
			setTimeout(function(){
				if(state.userStatus === 0){
					//仅限普通会员才能分享获得高级会员资格
					commit('setMemberInfo',{
						userStatus:1,
						vipLevel:0
					});
					resolve('分享成功,您已获得一个月的高级vip');
				}else{
					resolve('分享成功');
				}
			},1000)
		})
	}
}

 b)通过 dispatch 分发 action:

      store.dispatch可以处理被触发的action函数返回的Promise,并且仍旧返回Promise,如下:

methods:{

    buy:function(e){
        //正常是与后台交互,传递会员信息与购买缴费
        //此处是本地数据的处理
        //第一个参数是actions.js中的函数名
        //第二个参数是需要传的值
        store.dispatch('buyVip',e).then(res=>{
            alert(res);
        })
    }
}

 

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