Vuex学习入门

艺术之因此存在,
    就是为了令人恢复对生活的感受,
    为了令人感觉事物,
    使石头显出石头的质感。

                --什克洛夫斯基
复制代码

什么是Vuex

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的全部组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。javascript

Vuex 也集成到 Vue 的官方调试工具 devtools extension,提供了诸如零配置的 time-travel 调试、状态快照导入导出等高级调试功能。html

什么状况下须要用Vuex

Vuex 能够帮助咱们管理共享状态,并附带了更多的概念和框架。这须要对短时间和长期效益进行权衡。vue

若是您不打算开发大型单页应用,使用 Vuex 多是繁琐冗余的。确实是如此——若是您的应用够简单,您最好不要使用 Vuex。一个简单的 store 模式就足够您所需了。可是,若是您须要构建一个中大型单页应用,您极可能会考虑如何更好地在组件外部管理状态,Vuex 将会成为天然而然的选择。java

总结如下,主要是如下两点:git

  1. 方便全部组件共享信息,方便不一样组件共享信息。
  2. 某个组件须要修改状态和需求。

组件之间传值方式

主流的几种Vue的组件间传递信息的方式,无非有如下几种:ajax

  1. 经过$emitprops在父子组件中进行数据传递vuex

  2. eventbus(全局事件)在中进行传递vue-cli

  3. 利用localstorage、sessionstorage等存储手段来进行传递缓存

毫无疑问,这些个方式都能完成咱们所要的需求,可是在某种程度上面或多或少都有一些问题。例如:安全

  1. 利用$emitprops在兄弟关系嵌套比较深的状况之下,代码书写量将会大大的增长

  2. 全局事件在使用的时候可能被被屡次触发、销毁时机掌握等等一系列的问题,同时做为全局事件全部页面都能监听、掌控事件可能会存在安全性问题等等...

  3. ...

针对以上三种传值方式存在各自的缺点,下面着重介绍如下主角Vuex的简单入门。

Vuex核心概念

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

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

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

上面就将vuex的四个核心选项:state mutations getters actions说了出来,下面咱们经过实例来了解这几个概念。

简单入门

  • 第一步

新建一个.js 文件,名字位置任意,按照惯例,建议在/src/store,咱们就在该文件里编辑代码。

文件位置 /src/store/index.js

// 引入vue 和 vuex
import Vue from 'vue'
import Vuex from 'vuex'

// 这里须要use一下,固定写法,记住便可
Vue.use(Vuex)

// 直接导出 一个 Store 的实例
export default new Vuex.Store({
 // 相似 vue 的 data
  state: {
    name: 'oldName'
  },
 // 相似 vue 里的 mothods(同步方法)
  mutations: {
    updateName (state) {
      state.name = 'newName'
    }
  }
})
复制代码

这一步其实就是新建一个store,可是咱们还没在项目中使用。

  • 第二步

在入口文件引入上述文件, 并稍微改一下传给 new Vue()的参数,新增的行后面有备注。

文件位置 /src/main.js

import Vue from 'vue'
import App from './App.vue'
import store from './store'  //新增

Vue.config.productionTip = false

new Vue({
  router,
  store,  //新增
  render: h => h(App)
}).$mount('#app')

复制代码

以上2步,若是咱们使用vue-cli脚手架建立初始化项目的时候,选择了Vuex,以上两步都是默认帮咱们处理好了的,使用起来很方便。

  • 第三步

以上2步,其实已经完成了vuex的基本配置,接下来就是使用了。

文件位置 /src/App.vue

<template>
  <div>
    {{getName}}
    <button @click="changeName" value="改名">改名</button>
  </div>
</template>

<script> export default { computed:{ getName(){ return this.$store.state.name } }, methods:{ changeName () { this.$store.commit('updateName') } } } </script>
复制代码

这里就是一个很普通的vue文件了,有区别的地方是这里咱们须要用computed属性去获取 store 里的 "data"。

还有就是咱们要改变数据的话,再也不用 this.xxx = xxx 改为 this.$store.commit('updateName')

四大核心

State

首先是state,如何来获取state的值呢?通常是将这个值放置在computed里面,这样的话一旦数据发生改变的时候,就反馈到页面上面去。

computed:{
    getName(){
        return this.$store.state.name
    }
 },
复制代码

state总结:用来存放组件之间共享的数据,它跟组件的data选项相似,只不过data选项是用来存放组件的私有数据。

Getter

如今假设逻辑有变,咱们最终指望获得的数据(computed中的getName),是基于 this.$store.state.name 上通过复杂计算得来的,恰好这个getName要在好多个地方使用,那么咱们就得复制好几份。

vuex 给咱们提供了 getter来解决这个问题,能够认为是 store 的计算属性,请看代码:

文件位置 /src/store/index.js

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

Vue.use(Vuex)

export default new Vuex.Store({
 // 相似 vue 的 data
 state: {
  name: 'oldName'
 },
 // 相似 vue 的 computed -----------------如下5行为新增
 getters:{
  getReverseName: state => {
    return state.name.split('').reverse().join('')
  }
 },
 // 相似 vue 里的 mothods(同步方法)
 mutations: {
  updateName (state) {
   state.name = 'newName'
  }
 }
})
复制代码

而后咱们能够这样使用:

文件位置 /src/App.vue

computed:{
  getName(){
   return this.$store.getters.getReverseName
  }
}
复制代码

事实上, getter 不止单单起到封装的做用,它还跟vue的computed属性同样,会缓存结果数据,只有当依赖改变的时候,才要从新计算。

getter总结:getters主要是用来过滤和重组,这些事件最好也是能在计算属性中完成,用于监听事件变化的。

Mutation

Vuex 中的 mutation 很是相似于事件:每一个 mutation 都有一个字符串的事件类型 (type) 和 一个 回调函数 (handler),且必须是同步方法。

mutation定义:

mutations: {
  increment (state, payload) {
    state.count += payload.amount
  }
}
复制代码

mutation使用:

this.$store.commit('increment', {
  amount: 10
})
复制代码

mutations总结:

  • 在 Vuex store 中,实际改变 状态(state) 的惟一方式是经过 提交(commit) 一个 mutation
  • mutations下的函数接收state做为参数,另外一个参数叫作payload(载荷),payload是用来记录开发者使用该函数的一些信息,好比说提交了什么,提交的东西是用来干什么的,包含多个字段,因此载荷通常是对象(其实这个东西跟git的commit很相似)
  • 还有一点须要注意,mutations方法必须是同步方法!

Action

细心的你,必定发现我以前代码里 mutations 头上的注释了 相似 vue 里的 mothods(同步方法)。

为何要在 methods 后面备注是同步方法呢? 由于mutation只能是同步的函数,只能是同步的函数,只能是同步的函数!!!

那么若是咱们想触发一个异步的操做呢?答案是: action + $dispatch, 咱们继续修改store/index.js下面的代码。

文件位置 /src/store/index.js

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

Vue.use(Vuex)

export default new Vuex.Store({
 // 相似 vue 的 data
 state: {
  name: 'oldName'
 },
 // 相似 vue 的 computed
 getters:{
  getReverseName: state => {
    return state.name.split('').reverse().join('')
  }
 },
 // 相似 vue 里的 mothods(同步方法)
 mutations: {
  updateName (state) {
   state.name = 'newName'
  }
 },
 // 相似 vue 里的 mothods(异步方法) -------- 如下7行为新增
 actions: {
  updateNameAsync ({ commit }) {
   setTimeout(() => {
    commit('updateName')
   }, 1000)
  }
 }
})
复制代码

而后咱们能够再咱们的vue页面里面这样使用:

文件位置 /src/App.vue

methods: {
  rename () {
    this.$store.dispatch('updateNameAsync')
  }
}
复制代码

actions总结:

  • actions的做用其实和mutations是没有差异的,无非就是一个同步、异步的差异罢了。而在功能上面主要有一下两个区别:

    • actions 提交的是mutations,而不是直接变动状态。也就是说,actions会经过mutations,让mutations帮他提交数据的变动

    • actions 能够包含任意异步操做。ajax、setTimeout、setInterval不在话下

    • actions第一个参数是一个与 store 实例具备相同方法和属性的 context 对象,所以你能够调用 context.commit 提交一个 mutation,或者经过 context.state 和 context.getters 来获取 state 和 getters,可是 context 对象不是 store 实例自己。下图是我从控制台打印出来的context对象

总结

解释一下这个图:

  • vuex 的区域是绿色虚线框的位置

  • 流程:

    • 每次 vue 组件须要 给 vuex 分派 一个 actions,actions 提交一个 mutation,由 mutation 来修改 state,而后再返回给 vue 组件渲染

    • state 状态只能由 mutation 来修改

    • actions 会能够封装各类 mutation 来进行修改 state

  • 关于 state:state 就是状态

  • 关于 mutation:mutation 是 vuex 对 state 或者 store提交修改的惟一方式,固定方式

  • 关于 getter:

    • 这里没有出现 getter, 由于 getter 在这个流程里面不须要出现,他只是一个属性,方便从 vuex 的内存里面获取一些信息,可看作state的计算属性
  • 关于 actions:

    • action 提交的是 mutation,而不是直接变动状态

    • action 能够包含任意异步操做

下图是我总结的Vuex功能点思惟导图:

参考文献:

Vuex官网

谈一谈我是怎么学习使用vuex的

简单的三步vuex入门

相关文章
相关标签/搜索