前端技术简友广场

vuex

2018-12-13  本文已影响112人  前端来入坑

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。

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

安装 npm install vuex --save

使用的时候在main.js中引入

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

Vue.use(Vuex)
学习的最快方法就是看栗子,讲解的最通俗易懂的方法也是举个栗子:
举个栗子.jpg
// 如果在模块化构建系统中,请确保在开头调用了 Vue.use(Vuex)

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

···

store.commit('increment')

console.log(store.state.count) // -> 1

Vuex 允许我们在 store 中定义“getter”(可以认为是 store 的计算属性)。就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。

有时候我们需要从 store 中的 state 中派生出一些状态,例如对列表进行过滤并计数:比如这样

computed: {
  doneTodosCount () {
    return this.$store.state.todos.filter(todo => todo.done).length
  }
}

如果有多个页面需要使用到这个filter处理后的数据,那么可以用getters中这么写:

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)
    }
  }
})

然后每个需要用到的这个数据的页面可以通过这种方式取到处理后的数据

store.getters.doneTodos 
//或者
this.$store.getters.doneTodos
// ...那么这个n就是传入的参数,state是默认有的
mutations: {
  increment (state, n) {
    state.count += n
  }
}

用commit触发increment改变状态,传入的参数10就是n

store.commit('increment', 10)

另一种对象风格提交方式:当然只掌握前面一种提交方式也是可以的

store.commit({
  type: 'increment',
  amount: 10
})
mutations: {
  increment (state, payload) {
    state.count += payload.amount
  }
}

因为mutation 是同步的:所以就有了action

Action 类似于 mutation,不同在于:

举个栗子

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,或者通过 context.state 和 context.getters 来获取 state 和 getters。

Action 通过 store.dispatch 方法触发:

store.dispatch('increment')

乍一眼看上去感觉多此一举,我们直接分发 mutation 岂不更方便?实际上并非如此,还记得 mutation 必须同步执行这个限制么?Action 就不受约束!我们可以在 action 内部执行异步操作:

actions: {
  incrementAsync ({ commit }) {
    setTimeout(() => {
      commit('increment')
    }, 1000)
  }
}

由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。
为了解决以上问题,Vuex 允许我们将 store 分割成模块(module),详情请见官网。

官网https://vuex.vuejs.org/zh/guide/

gzh.jpg

每日分享前端技术知识,致力于帮助更多前端人翻过一座座山,踏过一个个坑。

上一篇下一篇

猜你喜欢

热点阅读