Vue2---Vuex

59 阅读2分钟

仓库vuex

Vuex简介

1.为了方便实现组件之间的数据共享,Vuex是他们团队借鉴了redux,用来实现vue组件全局状态(数据)管理的一种机制.

2.特点(面试)

能够在vuex中集中管理共享的数据,易于开发和后期维护

能够高效地实现组件之间的数据共享, 提高开发效率

存储在 vuex中的数据都是响应式的,能够实时保持数据与页面的同步

一般情况下,只有组件之间共享的数据,才有必要存储到vuex中;

对于组件中的私有数据,依旧存储在组件自身的data中即可.

3.使用场景

如果你实在不知道开发中什么数据才应该保存到Vuex中,那你就先不用Vuex,需要的时候自然就会想到它

Vuex的官网:

引入方式

1.自己下载引入

2.cli脚手架引入

安装:

​
npm i vuex --save
​
导入:
​
import Vuex from "vuex"
​
Vue.use(Vuex)

创建仓库:

const store=new Vuex.Store({
​
           state:{msg:"我就是所有共享的数据"}
​
})

把仓库挂载到vm对象:

new Vue({
​
     render(h){return h(app)},
​
     router,
​
     store//挂载以后  所有的组件就可以直接从store中获取全局数据
​
}).$mount( "#app")

vue create app

选择配置vuex

State

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

const store=new Vuex.store({
​
           state:{msg:"我就是所有共享的数据"}
​
})

2.组件中访问数据

this.$store.state.msg

Getter

getter就就像是store的计算属性,它会传入state对象供我们操作 //1.设计

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.使用

this.$store.getters.bigMans

Mutation

组件中希望更改 Vuex 的 store 中的状态(数据)的唯一方法是提交 mutation 不要用赋值表达式直接在组件中给store设置新数据 这样设计的原因是,只有通过mutation来更新数据,它才会去帮我们通知所有使用数据的组件更新数据 刷新UI

//1.设计

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

//2.组件中使用 //2.1 直接触发并传值(提交载荷)

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

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

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

注意:一条重要的原则就是要记住 mutation 必须是同步处理 下面是错误的方式:

mutations: {
  increment (state,obj) {
    //如果fnAsync函数是一个异步业务函数,就会导致更新失败
    fnAsync(() => {
      state.count=obj.n
    })
  }
}

Action

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

//设计

const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment (state,obj) {
      state.count=obj.n
    }
  },
  actions: {
    //默认第一个参数传一个跟store一样的对象
    increment (context,obj) {
        //假设fnAsync是一个异步业务函数
        fnAsync(() => {
          context.commit('increment',obj)
        })      
    }
  }
})

//使用也是两种: //1.直接分发

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

//2.以对象形式分发

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

Module

可用于业务分块开发: 由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。 为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter

//分块设计:
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,//局部命名空间    
   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
  }
})
​
//组件中的使用:
this.$store.state.a.msg // -> moduleA 的状态
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

技术厉害的同学拓展:mapState,mapGetters,mapMutation,mapAction和使用常量替代 Mutation 事件类型,

使用常量替代 mutation 事件类型在各种 Flux 实现中是很常见的模式。同时把这些常量放在单独的文件中可以让你的代码合作者对整个 app 包含的 mutation 一目了然

用不用常量取决于你——在需要多人协作的大型项目中,这会很有帮助。但如果你不喜欢,你完全可以不这样做。