从计数器开始

让我们从一个简单的计数器,开始进入Vuex 的世界:

计数器应用的数据模型很简单:使用一个counter属性来表示计数器的 当前值就够了。

Vue实例的created钩子 中,应用启动了一个定时器,用来周期性地 递增counter属性的值 —— 由于counter是响应式属性,它的变化因而 驱动了视图随之刷新。

可以说counter抽象地表达了计数器视图的本质特征,当counter的 值确定时,我们可以确定地推理出视图的表现。像counter这样可以决定 视图表现的数据,在Vuex中就被称为状态

计数器应用相当简单,因此我们只需要定义一个状态就可以了。稍微复杂 一些的应用,则可能需要我们抽象出成百上千的状态,这时候就需要分类 管理了。

例如,对于一个电商应用,我们将其购物车相关的状态归入cart类:

你看到,应用的全部状态,构成了一棵层级分明的状态树。而Vuex的作用 ,就在于管理一个应用的状态树。

应用单一状态树

Vuex进行应用状态管理 的第一个手段,是要求应用建立并维护一个单一的、全 应用范围共享的状态树,而不是各个组件单独维护自己的状态(在组件中使用data配置项声明) —— 不过这不是绝对的,那些完全不需要在多个组件间 共享的状态,依然可以在组件内部声明。

出于学习的目的,同时为了避免引入复杂的演示代码,我们假设计数器的counter状态需要与其他组件共享,因此我们将其定义迁移到状态树中。

创建状态库

Vuex的Store类 —— 状态库 —— 用于管理状态树,它的实例化配置项state用来声明要创建的状态树。例如,下面的代码创建了一个包含状态counter的 状态库:

conststore =newVuex.Store(

{

            state:{ counter:0}

       }

)

利用状态库的state属性,就可以访问到其管理的状态树了。例如,通过store.state.counter来访问counter状态。

需要指出的是,状态库的state属性 —— 状态树 —— 是一个响应式属性,因此 我们可以使用状态树上的这些状态来驱动视图的自动更新。

使用计算属性访问状态树

在建立了全应用单一状态树之后,接下来我们要考虑的就是在组件中怎么使用 树上的状态了 —— 我们已经决定不声明组件的私有状态。

最简单的方法是将树上的状态,映射为组件的计算属性。例如,下面的代码将 状态树上的counter状态,映射为组件的可读写计算属性:

constEzCounter = { 

    template:'{ {counter} }',  

    computed:{    

        counter:{

            get() {returnstore.state.counter },

            set(v){ store.state.counter = v }    

        }

    }

}

将状态库注入组件

另一种方法是将状态库挂接为Vue实例的一个属性上,这样我们就可以在模板中 直接访问状态树了(模板的上下文对象是所属的Vue实例)。

在创建Vue实例时,使用store配置项,就可以将状态库挂接为Vue实例 的属性$store,而且这个Vue实例的所有后代实例,也都有$store指向 同一个状态库,看起来就像是将状态库注入了组件树上的每一个实例。

例如,下面的代码使用store配置项,将状态库store注入根组件,因此 我们可以在EzCounter组件中利用$store属性访问状态库:

const EzCounter = { 

    template:'{{$store.state.counter}}'

}

new Vue({ 
store:store,         template:'',         components:{EzCounter} })

状态变更管理

Vuex进行状态管理 的第二个手段,是承担起管理状态变更(mutation)的 责任。

Vuex要求组件将状态树视为只读,组件不应该直接修改状态树上的状态, 而是通过提申请的方式,由状态库来实际执行状态变更的操作:

对于计数器应用来讲,修改counter状态的需求有两个:递增和复位。 因此,我们需要首先在状态库中声明两个变更处理器(mutation handler)。

在创建状态库时,使用mutations配置项来声明变更处理器。例如,下面 的代码为状态库声明了两个变更处理器:INCREASE和RESET:

conststore =newVuex.Store({

        state:{counter:0},

        mutations:{
INCREASE:state=>state.counter++ ,
RESET:state=>state.counter =0
}
})

Vuex推荐使用大写字母来命名变更处理器,因为这个名字也将作为 组件提交的变更请求的类型名 —— 从组件的角度看,还有比大写的名字 更能表达出这是一个请求而不是实际操作吗 —— 回忆一下Windows 的WM_系列消息的名字。

状态变更处理器(mutation handler)的参数是一个局部上下文 (local context)对象的state属性,我们需要利用这个参数来 更新状态树上指定的状态。局部上下文是Vuex为实现状态树的模块化管 理而构造的状态库局部镜像,我们将在《模块化管理》章节详细讲解 局部上下文(local context)对象。现在,就把它暂时理解为原始的 状态库好了。

提交变更请求

组件应当调用状态库的commit()方法来提交指定类型的状态变更请求。 例如,下面的代码向状态库提交了递增counter状态的申请:

store.commit('INCREASE')

状态变更的同步性

Vuex进行状态管理 的第三个手段,是要求应用保证状态变更(mutation)的 同步性 —— 状态变更处理器执行完之时,状态更新一定要完成。

这意味着,在状态变更处理器里不能执行异步代码。这一要求直接导致了新的 环节的引入 —— 状态动作(action):

根据作者的说法(原文参见:About mutations usefulness), 引入状态动作(action)这一环节的唯一目的,就是为了保证状态变更(mutation) 的同步性:"Actions vs. mutations is all about separating asynchronicity from actual mutations"

状态动作(action)隔离了组件和状态库,组件现在应当分发执行状态库声明的动作, 然后由状态动作负责提交变更请求。

在创建状态库时,使用actions配置项声明状态动作。例如,下面的代码 声明了两个状态动作inc和reset,分别用来提交INCREASE和RESET变更 请求:

conststore =newVuex.Store({

    state:{counter:0},

    mutations:{INCREASE:state=>state.counter++,RESET:state=>state.counter =0},

    actions:{inc:context=>context.commit('INCREASE'),

    reset:context=>context.commit('RESET')  }

})

状态动作(action handler)的参数是一个局部上下文(local context)对象, 我们已经知道它是Vuex为模块构造的状态库局部镜像,因此调用它的commit()方法, 就可以提交变更请求了。

分发执行状态动作

调用状态库的dispatch()方法来分发执行指定名称的状态动作。例如, 下面的代码要求状态库执行inc动作:

store.dispatch('inc')

更多关于vuex的精彩内容请到这里来:

最新的 Vuex 2 入门与提高教程

Vuex 2 入门与提高。的更多相关文章

  1. webdriver实用指南迁移至gitbbok并改名为selenium webdriver从入门到提高

    背景 几年前我写了一本关于selenium webdriver的小册子,主要讲了一些selenium在进行测试过程中会遇到的场景以及解决方案,陆陆续续在github上收到了100+的star,在这里我 ...

  2. SignalR 2.0 入门与提高

    SignalR 2.0 入门与提高 SignalR 2.0 最近整理了SignalR2.0 部分知识点,原文翻译,由于自己是土鳖,翻译得不好的地方,欢迎指正!仅供各位初学者学习! 第一节. 入门ASP ...

  3. 【转载】【时序约束学习笔记1】Vivado入门与提高--第12讲 时序分析中的基本概念和术语

    时序分析中的基本概念和术语 Basic concept and Terminology of Timing Analysis 原文标题及网址: [时序约束学习笔记1]Vivado入门与提高--第12讲 ...

  4. Android 开发 音视频从入门到提高 任务列表 转载

    <Android 音视频从入门到提高 —— 任务列表> 1. 在 Android 平台绘制一张图片,使用至少 3 种不同的 API,ImageView,SurfaceView,自定义 Vi ...

  5. 包建强的培训课程(16):Android新技术入门和提高

    @import url(/css/cuteeditor.css); Normal 0 10 pt 0 2 false false false EN-US ZH-CN X-NONE $([{£¥·‘“〈 ...

  6. 关东升的iOS实战系列图书 《iOS实战:入门与提高卷(Swift版)》已经上市

             承蒙广大读者的厚爱我的 <iOS实战:入门与提高卷(Swift版)>京东上市了,欢迎广大读者提出宝贵意见.http://item.jd.com/11766718.html ...

  7. Vuex的入门教程

    前言 在 Vue.js 的项目中,如果项目结构简单, 父子组件之间的数据传递可以使用  props 或者 $emit 等方式,详细点击这篇文章查看. 但是如果是大型项目,很多时候都需要在子组件之间传递 ...

  8. vuex 基本入门和使用(三)-关于 mutation

    vuex 基本入门和使用(三)-关于 mutation vuex 版本为^2.3.1,按照我自己的理解来整理vuex. 关于 mutation 这里应该很好理解. 更改 Vuex 的 store 中的 ...

  9. vue学习【四】vuex快速入门

    大家好,我是一叶,今天我们继续踩坑.今天的内容是vuex快速入门,页面传值不多的话,不建议vuex,直接props进行父子间传值就行,使用vuex就显得比较臃肿. 我们先预览一下效果,如图1所示. 图 ...

随机推荐

  1. Redis Exception: Exceeded timeout of 00:00:03

    Redis Exception: Exceeded timeout of 00:00:03 居然是 重启了网管, 把网络禁用重启就好了. 服 最终更新: 原来是架构湿      设置为每分钟只能读取6 ...

  2. mysql-root本地无法登录处理

    主要有以下几种情况: 1.忘记密码 2.丢失root对localhost的访问权限或者对应的host授权 解决方案: ----------------------------------------- ...

  3. 【java】乱码处理+编码转化+判断字符串编码方式

    之前有一篇是修改IDE的编码,服务器的编码等处理乱码,但是在所有环境因素上,保证了编码方式之后,也会有前台传递给后台[get方式提交]传递给后台的编码方式是非UTF-8的,也会有例如FTP服务器的编码 ...

  4. Mysql的共享锁和排他锁(转载)

    mysql锁机制分为表级锁和行级锁,本文就和大家分享一下我对mysql中行级锁中的共享锁与排他锁进行分享交流. 共享锁又称为读锁,简称S锁,顾名思义,共享锁就是多个事务对于同一数据可以共享一把锁,都能 ...

  5. sqlmapapi的跨域访问Access-Control-Allow-Origin:*;ajax

    1.做sqlmapapi的二次开发时,需要通过ajax方式调用sqlmapapi,但是默认情况下,sqlmapapi是不允许跨域访问的 2.尝试增加ajax的header,修改origin的值,来避免 ...

  6. insert语句太长,有StringBuilder优化一下

    private void btnSave_Click(object sender, RoutedEventArgs e) { if (IsInsert) { //假设日历控件没有选日期,那帮它赋一个当 ...

  7. mysql性能检查脚本-部分

    #!/bin/sh #ocpyang@126.com export black='\033[0m' export boldblack='\033[1;0m' export red='\033[31m' ...

  8. asp.net权限控制的方式

    我们在使用asp.net开发Web程序的时候经常需要进行一些权限控制,如: 限制用户没有登陆就无法查看一些页面,又或者是说登陆之后如果不是管理员,或是没有响应的权限就无法进行相关的操作. 实现的方法有 ...

  9. Sublime Theme

    Package Control Messages======================== Theme - Spacegray----------------- Thanks for insta ...

  10. css - margin-padding

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...