浅谈Vuex

什么是Vuex?

     首先VuexVue '全家桶'的成员之一,也是一个专为Vue.js应用程序开发的状态管理模式。     官方说法: 它采用集中式存储管理应用的全部组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。javascript

为何要用Vuex?

    由于组件之间是相互独立的,组件之间想要通讯。其中有经过props选项通讯,但这只限于父子组件通讯,远远不能知足组件之间通讯的需求,特别是作中大型的项目。因此就把组件之间须要共享的数据给单独'弄'出来。     经过定义和隔离状态管理中的各类概念并经过强制规则维持视图和状态间的独立性,咱们的代码将会变得更结构化且易维护。vue

什么状况应该用Vuex?

    Vuex能够帮助咱们管理共享状态,并附带了更多的概念和框架,这须要对短时间和长期效益进行权衡。     若是不是开发中大型单页应用,使用Vuex多是繁琐冗余的,不建议使用。java

Vuex的特性

    每个 Vuex应用的核心就是 store(仓库)。“store”基本上就是一个容器,它包含着你的应用中大部分的状态 (state)。Vuex 和单纯的全局对象有如下两点不一样:vuex

  1. Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地获得高效更新。缓存

  2. 你不能直接改变 store 中的状态。改变 store 中的状态的惟一途径就是显式地提交 (commit) mutation。这样使得咱们能够方便地跟踪每个状态的变化,从而让咱们可以实现一些工具帮助咱们更好地了解咱们的应用。框架

Vuex 的核心概念

     state:      把组件须要通讯的数据定义在storestate中。容器的状态(响应式数据,能够触发视图更新的数据)。 举例:异步

//若是在模块化构建系统中,请确保在开头调用了 Vue.use(Vuex)
    //视图状态仓库中(超大的ViewModel,把须要跨组件通讯的数据都放到这里)
    const store = new Vuex.Store({
      //容器状态(响应式数据,能够触发视图更新的数据)
      state: {
        count: 0
      },)
//在组件中经过计算属性来获取 store.state中的成员
 Vue.component('component-b', {
    template: ` <div> componentB <h1>{{count }}</h1> </div> `,
    created () {
    },
    data () {
      return {
      }
    },
    computed: {  //使用computed 来监视count的变化,当count的值一变化,就会调用computed的事件
     count () {
      return store.state.count
     }
    }
  })
复制代码

     getter:      就像计算属性同样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被从新计算。 举例:模块化

const store = new Vuex.Store({
  state: {
   todos: [
    { name: '小张',compoleted: true},
    { name: '小李',compoleted: false }
   ]
  },
getters: {  
  compoletedTodos: state => {   //getter 接受state做为其第一个参数
    return state.todos.filter (todo => toto.compoleted)
  },
comTodosLength: ( state, getters) => { //getter 也能够接受其余的getter做为第二个参数
    return getters.compoletedTodos.length
}
}
})
经过属性访问
store.getters.compoletedTodos

复制代码

     mutation:     它是更改Vuexstore中的状态的惟一方法,很是相似于事件,每一个mutation 都有一个字符串的事件类型type和一个回调函数handle。 举例:函数

const store = new Vuex.Store({
  state: {
    count: 1
  },
  mutations: {
    increment (state) {
      // 变动状态
      state.count++
    }
  }
})

在组件中经过store.commit方法来触发mutation
store.commit('increment ')
复制代码

经过store.commit传入额外的参数,即mutation的载荷(payload): 举例:工具

方式一:
mutations: {
  increment (state,n) {
     state.count += n
  }
}
store.commit('increment',10)
方式二: 载荷应该是一个对象
mutations: {
  increment (state,payload) {
   state.count += payload.amount
  }
}
store.commit('increment',{
  amount: 10
})
方式三:对象风格的提交方式,可是定义mutation函数保持不变
store.commit({
  type:'increment',
  amunt: 10
})
复制代码

     action:      action 相似于 mutation,可是不一样的是:

  • action 提交的是mutation,而不是直接变动状态。
  • action能够包含任何异步操做 举例:
const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment (state) {
      state.count++
    }
  },
  actions: {
  //action 函数接受一个与store实例具备相同方法和属性的context对象
    increment (context) {
      context.commit('increment')
    }
  }
})
复制代码

action 经过 store.dispatch 触发:

store.dispatch('increment')
复制代码

actionmutation最大的不一样是:mutation必须同步执行,而action就不受约束,能够在action内部执行异步操做:

actions: {
  incrementAsync ({ commit }) {
    setTimeout(() => {
      commit('increment')
    }, 1000)
  }
}
复制代码

action支持一样的载荷方式和对象方式进行分发。      module:     当项目很是大的时候,应用的全部状态会集中到一个比较大的对象,store对象就有可能变得至关臃肿。     为了解决以上问题,咱们能够将store分割成模块,同时每一个模块拥有本身的state,mutation,action,getter,还能嵌套子模块,从上至下进行一样方式的分割。

const moduleA = {
    state: { ... },
    mutations: { ... },
    actions: { ... },
    getters: { ... }
  }
 
 const moduleB = {
   state: { ... },
   mutations: { ... },
   actions: { ... }
 }

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

store.state.a // -> moduleA 的状态
store.state.b // -> moduleB 的状态
复制代码

辅助函数

  • mapState辅助函数
  • mapGetters 辅助函数
  • mapMutations 辅助函数
  • mapActions 辅助函数

     其实关于Vuex还有不少知识点,尤大神已经写的很全面了,你们感兴趣的能够参考Vuex(vuex.vuejs.org/zh/)的官网。

     我以为学习最好的办法就是跟着官网敲demo,这样才能学以至用,更好的理解新的技术点。

     好了,不说了,我要去敲代码了。若是我写的对你有些帮助,不要忘了给我点个赞或加个关注哟。ღ( ´・ᴗ・` )比心

相关文章
相关标签/搜索