vuex详解

vuex

vuex的定义: 

       Vuex是Vue.js应用程序的状态管理模式+库。 vuex采用集中式存储所有组件的数据状态,并且组件状态和后台数据是响应的。

vuex解决的问题:  

1)多个视图依赖于同一状态

2)来自不同视图的行为需要变更同一状态

Vuex则是把组件的共享状态抽取出来,以一个全局单例模式管理

同时,通过定义和隔离状态管理中的各种概念并强制遵守一定的规则,代码变得更结构化、易维护

以上就是vuex的思想

使用:

  script  引入
     <script src="/path/to/vue.js"></script>
           <script src="/path/to/vuex.js"></script>
  包管理安装: npm i vuex -S
  在一个模块化的打包系统中,必须通过显式地通过Vue.use() 来安装vuex:
    import Vue from 'vue'
    import Vuex from 'vuex'
    Vue.use(Vuex) 

vuex的五个核心概念:

  State,Getter,Mutation,Action,Module,

vuex主要有四个部分:

  1. state:包含了 store 中存储的各个状态。
  2. getter: 类似于 Vue 中的计算属性,根据其他 getter 或 state 计算返回值。
  3. mutation: 一组方法,是改变 store 中状态的执行者, 只能是同步操作 。
  4. action: 一组方法,其中可以 包含异步操作 。

vue单页面应用中使用 

import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
  state: {
    count: 0
  },
  getter: {
    doneTodos: (state, getters) => {
      return state.todos.filter(todo => todo.done)
    }
  },
  mutations: {
    increment (state, payload) {
      state.count++
    }
  },
  actions: {
    addCount(context) {
      // 可以包含异步操作
      // context 是一个与 store 实例具有相同方法和属性的 context 对象
    }
  }
})
// 注入到根实例
new Vue({
  el: '#app',
  // 把 store 对象提供给 “store” 选项,这可以把 store 的实例注入所有的子组件
  store,
  template: '<App/>',
  components: { App }
})

State 存储应用中需要共享的状态,存放数据

const Counter = {

  template: `<div>{{ count }}</div>`,

   computed: { count () { return this.$store.state.count // count 为某个状态 } }

}

Getter  Store 的计算属性

const store = new Vuex.Store({
  state: {
    todos: [
      { id: 1, text: '...', done: true },
      { id: 2, text: '...', done: false }
    ]
  },
  getters: {
    doneTodos: state => {
      return state.todos.filter(todo => todo.done)
    }
  }
})

通过属性访问  

我们可以很容易在任何组件中使用他
computed: {
  doneTodosCount () {
    return this.$store.getters.doneTodosCount
  }
}
 通过方法访问

也可以通过让 getter 返回一个函数,来实现给 getter 传参。在对 store 里的数组进行查询时非常有用。

getters: {
  // ...
  getTodoById: (state) => (id) => {
    return state.todos.find(todo => todo.id === id)
  }
}
store.getters.getTodoById(2) // -> { id: 2, text: '...', done: false }

注意:getter 在通过方法访问时,每次都会去进行调用,而不会缓存结果。

mutations 改变状态的执行者 只能同步的更改状态 不能出现异步的方法

 

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

提交载荷(Payload)

// ...
mutations: {
  increment (state, n) {
    state.count += n
  }
}
this.$store.commit('increment', 10)

其中,第一个参数是 state ,后面的参数是向 store.commit 传入的额外的参数,即 mutation 的 载荷(payload) 。

store.commit 方法的第一个参数是要发起的 mutation 类型名称,后面的参数均当做额外数据传入 mutation 定义的方法中。

规范的发起 mutation 的方式如下:

// 以载荷形式
store.commit('increment',{
  amount: 10   //这是额外的参数
})

// 或者使用对象风格的提交方式
store.commit({
  type: 'increment',
  amount: 10   //这是额外的参数
})

额外的参数会封装进一个对象,作为第二个参数传入 mutation 定义的方法中。

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

Action 异步方法(异步的更改状态)
actions: {
  actionA ({ commit }) {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        commit('someMutation')
        resolve()
      }, 1000)
    })
  }
}
Action与mutation的区别   
action提交的是mutation,而不是直接变更状态
action可以包含任意异步操作,而mutation只能且必须是同步操作
 

 module  模块化

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

这时我们可以将 store 分割为 模块(module) ,每个模块拥有自己的 state 、 getters 、 mutations 、 actions 、甚至是嵌套子模块——从上至下进行同样方式的分割。

代码示例:

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 的状态

 

欢迎各位大佬补充! 

 

 

 

posted @ 2019-08-20 20:52  枯桑  阅读(204)  评论(0编辑  收藏  举报