Vue——vuex的五个核心概念

70 阅读3分钟

vuex的五个核心概念:

State(存储数据)

共享状态,vuex的基本数据,用来存储变量,相当于组件data里的数据,只不过此时变成了全局变量。

使用方法:

1.创建state状态,状态就是那个存数据的对象

   const store=new Vuex.store({

       state:{msg:"我就是所有共享的数据"}

})

2.组件中访问数据

 this.$store.state.msg

image.png

Getter

getter就像是store的计算属性,它会传入state对象供我们操作(基于state的派生状态,相当于组件中的computed中的属性)

使用方法:

1.设计一个函数(对state里的状态进行操作):

const store = new Vuex.Store({
  state: {
    arr: [
      { id: 1, text: '...', birth: "1997-02-03" },
      { id: 2, text: '...', birth:  "2019-10-03" }
    ]
  },
  getters: {
     bigMans(state) {
      return state.arr.filter((man)=>{
    	  let manY=new Date(man.birth).getFullYear()
    	  let nowY=new Date().getFullYear()
    	  return (nowY-manY)>=18
    	  })
    }
  }
})

2.在组件内使用:

    //在组件内使用getters内的函数,是把它当做一个属性来使用的
    //也就是下面的代码就代表着调用gettersnei的bigMans函数
    //bigMans()
    this.$store.getters.bigMans
    

Mutation(更改仓库状态)

更改vuex中store共享状态的方法(唯一的方式),通过提交mutation来去修改状态,进行同步操作数据,通常用于action获取异步数据,获取通过commit提交数据给mutation,在mutation同步操作state中的数据。

  • 组件中希望更改 Vuex 的 store 中的状态(数据)的唯一方法是提交 mutation

  • 不要用赋值表达式直接在组件中给store设置新数据

  • 这样设计的原因是,只有通过mutation来更新数据,它才会去帮我们通知所有使用数据的组件更新数据 刷新UI

注意:mutations中修改仓库数据,只能在同步代码中实现,不要在异步函数中实现,否则会出现不刷新页面的情况。(如果你想要实现异步的去修改数据,就可以在actions中,异步的提交mutations)

使用方法:

1.设计一个函数

const store = new Vuex.Store({
  state: {
    count: 1
  },
  mutations: {
	//默认传第一个参数传state
	increment (state,obj) {
	  // 变更状态
	  state.count=obj.n
	}
  }
})

2.在组件内使用(有两种):

2.1 直接触发并传值(提交载荷:就是提交mutations)

  //increment:在mutations中设计的函数名
  //{n:100}:向函数传入的参数
  this.$store.commit('increment',{n:100})
  

2.2 以一个对象的形式传入 (传入对象时,当相于把整个对象作为了第二个参数传入mutations )

this.$store.commit({
//type:触发mutations里的函数
  type: 'increment',
  n:100
})

action(可用于异步操作)

支持异步操作,可用于异步获取请求中的数据,并将获取的数据同步commit提交给mutation,实现ajax异步请求数据,mutation将其数据同步到state中。

  • Action 提交的是 mutation,而不是直接变更状态。

  • Action 可以包含任意异步操作。

  • 也就是actions中可以进行异步操作,于是在actions内部再去调用一下mutations内部的函数,从而实现我们想要进行得异步操作。

使用方法:

1.设计一个函数:

const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment (state,obj) {
      state.count=obj.n
    }
  },
  actions: {
	//默认第一个参数传一个跟store一样的对象
	increment (context,obj) {
		setTimeout(() => {
            //context是上下文对象
		  context.commit('increment',obj)
		})      
	}
  }
})

2.在组件内使用(有两种方式): 2.1直接分发:

 this.$store.dispatch('increment',{n:100})

2.2以对象形式分发:

this.$store.dispatch({
  type: 'increment',
  n:100
})

modules(可用于业务分块开发)

产生的原因:

由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。

优点:

模块化vuex,为了方便后期对于项目的管理,可以让每一个模块拥有自己的state、mutation、action、getters,使得结构非常清晰,方便管理。

使用方法:

//分块设计:
const moduleA = {
  namespaced: true,//局部命名空间(让state的中变量与其他模块中的同名变量不冲突)	
  state: { msg:1 },
  mutations: { change(state,n){state.msg=n} },
  actions: { change(context,n){context.commit("change",n)} },
  getters: { x(state){return state.msg} }
}

const moduleB = {
//namespaced: true 局部命名空间:每个模块都可以写一样的变量名,因为它不是一个空间的
   namespaced: true,
   state: {  msg:1 },
   mutations: { change(state,n){state.msg=n} },
   actions: { change(context,n){context.commit("change",n)} },
   getters: { x(state){return state.msg} }
}


const store = new Vuex.Store({
  modules: {
    a: moduleA,
    b: moduleB
  }
})

//组件中的使用:
//使用模块中的state,必须要加上模块名,不然不知道你具体想用哪个模块中state
this.$store.state.a.msg // -> moduleA 的状态,a:代表模块名
this.$store.state.b.msg // -> moduleB 的状态
this.$store.commit("a/change",100)-> moduleA 的mutations
this.$store.commit("b/change",200)-> moduleB 的mutations
this.$store.getters["a/x"]-> moduleA 的getters
this.$store.getters["b/x"]-> moduleB 的getters
this.$store.dispatch("a/change",100)-> moduleA 的actions
this.$store.dispatch("b/change",200)-> moduleB 的actions