vue2.0一起在懵逼的海洋里越陷越深(四)


前言

承接上文vue2.0一起在懵逼的海洋里越陷越深(三)
前面一篇讲了vue-router的router-link,
有读者说希望能先看到vuex的文章
其实vuex在我的vue2.0的demo里已经在使用了
想想确实应该先来点vuex的了,因为有些有关的状态管理急需vuex的加入
好,那么这次就先上vuex吧!

正文

OK!先介绍下vuex
vuex是vuejs的状态管理方案
因为vuex有些复杂,一般应用在较复杂的状态环境下,如果是比较简单的应用就不需要安装vuex了

vuex单向数据流

vuex单向数据流

如上图所示是vuex单向数据流的流程

** 我知道,如果是第一次接触这玩意,到这就懵逼了,就像我第一次看文档一样 **


** 下面解释下State **
前面说了vuex是vuejs的状态管理方案,这里的状态就是图中的state
在平时写写前端的过程中,都会涉及到状态的问题,
比如你看到了一篇文章写的不错,就想要收藏,
然后又对作者有些兴趣,于是又加了关注,当然这些最后都是需要前端来表达出来
这里面就涉及了两个状态就是收藏与关注
这里的收藏与关注我们可以将其用一个变量来表示,当然如这两种只存在两个相对状态的用布尔值(bool)来表示就可以了

** 然后是view **
view就是视图,也就是前端所写的页面,前面的state就可以在view里面得到体现,即是你看到的是否关注了作者

** 而后是Actions **
ActionsView用来改变State的方法,通过改变State从而改变View的显示

这么说有些抽象,打个比方
假设学生小明生病了
小明要向班主任请假(小明就是View,小明想改变自己的显示状态,从上学状态变成请假状态)
于是小明口头向班主任请假(请假就是Actions,小明通过请假这一个方法达到请假的目的)
班主任批准,小明请假成功(班主任就是State的提供者,小明通过请假方法使班主任改变小明的State状态)
着也就解释了为什么要有这个流程,有了这个流程就可以统一管理各个view的各个状态

vuex多个组件共享状态

先贴个流程图,懵逼是没啥关系的


vuex多个组件共享状态

可以看到这一张图比前面一张复杂了许多,其实里面的实线框就是上图的升级版

情况是这样,原来小明学校里这段时间许多同学得了流感,于是同学们一窝蜂的要求请假,
学校里因为人太多,又没有一个记录,人数清点不过来了,于是班主任要求请假必须提交请假条

好的,来解释下上图内的实线部分,之前的View在这里改名成了Vue Components,代表了多个组件(这里即是指多个同学)
包括小明在内的多个同学Vue Components都得了流感,一起想要请假Actions(他们即将共享一个请假状态),小明代表多个同学写了一张请假条交给班主任(State提供者)签字同意(签字同意这个动作就是Mutations,触发了State的改变),班主任同意后统一给他们改变了State(请假成功)

这里的多了一个同步与异步的区别,其中Mutations只受理同步处理,而Actions就是执行异步操作的函数,作为代价,Actions不再能直接触发改变State状态,而是需通过Mutations来触发State的改变

情况是这样,因为不只是一个班的学生得了流感,请假的人比较多,学校Backend API需要做一个统计,于是请假需要得到学校专门的请假条的并通过学校签字才能生效,这里就有了虚线部分。
请假Actions改变State的方法不再是仅仅班主任签字就可以了,而是需要通过学校这个前提,于是Actions就变成了一个异步请求,需要得到学校Backend API的专门的请假条和签字同意后,才能向班主任提交改变State的申请

这里想要表达的意思就是,Vue Components改变自身状态需要通过Actions(有需要的话要向后端接口Backend API发送请求)来操作Mutations改变State从而改变自身状态。
至于图中没有说到的Devtools是一个开发者工具,是一个便于查看和管理vue应用以及vuex状态的浏览器插件。
你可以在里面看到你vue对象和vuex每一次的commit,commit后面会说到。还有你当前的应用状态

devtools

附上一个devtools库地址

架构vuex

项目结构:

├── main.js
├── App.vue
├── components
│   ├── Home.vue
│   └── ...
└── store
    ├── index.js          # 组装模块并导出 store 的地方
    ├── actions.js        # 根级别的 action
    ├── mutations.js      # 根级别的 mutation
    ├── types.js          # mutation命名空间
    └── modules
        ├── demo.js       # demo模块
        └── status.js     # 全局应用状态模块

结构可以根据个人需要进行调整

** 下面开始构建store/index.js **
当然在这之前,如果没有安装vuex的需要先安装

npm i vuex -S

由于vuex的内容太多,这里先说基础用法
首先为store/index.js编写内容

import Vue from 'vue'
// 导入vue
import Vuex from 'vuex'
// 导入vuex

import status from './modules/status'
// 导入status模块(这是我管理全局应用状态的模块)
import demo from './modules/demo'
// 导入demo模块(这个的部分演示可以在http://vue2.leenty.com/demo/vuex_state/里看到)

Vue.use(Vuex)
// 告诉vue将要使用vuex

const debug = process.env.NODE_ENV !== 'production'
// env里去获取当前的环境是否需要开启严格模式
// 在发布环境开启严格模式会造成性能上不必要的损失

export default new Vuex.Store({
// 默认导出vuex模块
  modules: {
  // 导入模块
    status,
    demo
  },
  strict: debug
  // 是否开启严格模式
})

** 构建state模块 **
这里以demo.js为例

import * as types from '../types'
// 导入mutations的命名空间

const state = {
// 定义state
  demoFollow: false,
  // 这里模拟的是关注的状态,布尔值表示是否关注
  demoFollowPending: false
  // 是否在请求中(actions是否在执行异步操作)
}

const getters = {
// 定义getters, getters是对state的扩展,可以以state衍生出其他状态
  demoFollowStatus: state => state.demoFollow ? '已关注' : '未关注'
  // demoFollowStatus是demoFollow的衍生量,将原来的布尔值映射为'已关注' : '未关注'
}

const mutations = {
// 只有mutations才能操作改变state,mutations是同步执行的
// 所以有关异步的操作请放在actions里执行
  [types.DEMO__VUEX_FOLLOW] (state, status = NaN) {
  // 使用预定义好的名字来写mutations方法
    state.demoFollow = isNaN(status) ? !state.demoFollow : status
  },
  [types.DEMO__VUEX_FOLLOW_PENDING] (state, status = NaN) {
  // 这里对status传值做了审查,如没有传,则对要改变的布尔值进行取反操作
    state.demoFollowPending = isNaN(status) ? !state.demoFollowPending : status
  }
}

const actions = {
// actions是可以执行异步操作的,操作完毕后触发mutations里的方法去改变state的状态
  demoFollowAjax ({commit}, status) {
    commit(types.DEMO__VUEX_FOLLOW_PENDING)
    // 在异步操作前通过mutations告诉应用,现在正在进行异步操作
    setTimeout(() => {
      // 利用延时函数模拟异步的ajax操作
      commit(types.DEMO__VUEX_FOLLOW_PENDING)
      // commit 是在actions里用来触发mutations的方法
      // 告诉应用,异步操作结束
      commit(types.DEMO__VUEX_FOLLOW, status)
      // 为关注按钮赋予新的状态
    }, 2000)
  }
}

export default {
// 导出整个demo模块
  state,
  getters,
  actions,
  mutations
}

** 这里解释下mutations里的方法的奇怪写法,我知道如果对es6于法了解不多这里是会懵逼的 **

const mutations = {
  [types.DEMO__VUEX_FOLLOW] (state, status = NaN) {
    state.demoFollow = isNaN(status) ? !state.demoFollow : status
  }
}

这是对象内方法的简化写法,其中types.DEMO__VUEX_FOLLOW是在types.js里预定义的,内容如下

export const DEMO__VUEX_FOLLOW = 'DEMO__VUEX_FOLLOW'
export const DEMO__VUEX_FOLLOW_PENDING = 'DEMO__VUEX_FOLLOW_PENDING'
// 其实就是字符串集合,最后用 import * as types from '../types' 方法导入vuex模块里
// 就变成了一个types对象

上例中全部展开是这样的

const mutations = {
  [types.DEMO__VUEX_FOLLOW]: (state, status = NaN) => {
  // [types.DEMO__VUEX_FOLLOW]是提取types.DEMO__VUEX_FOLLOW的值的一种方式
  // 在这里[types.DEMO__VUEX_FOLLOW]提取出来就是types.js里预定义的'DEMO__VUEX_FOLLOW'
    if (isNaN(status){
      state.demoFollow = !state.demoFollow
    } else {
      state.demoFollow = status
    }
  }
}

好,到此为止,vuex就已经建立好了,下面就说如何使用了

应用状态的使用与改变

vuex提供了4个辅助函数

import { mapState, mapGetters, mapActions, mapMutations } from 'vuex'

是分别用来获取State, Getters, Actions, Mutations的map方法
在vue Components里面你可以以这样的方式来导入需要使用的方法

这4个方法拥有统一的参数格式以及一个统一的返回格式
可以传入一个数组

mapGetters(['demoFollowStatus'])
// 此方法导出的是一个Getters对象
mapGetters({
  demoFollow: 'demoFollowStatus'
})
// 可以通过传入对象的形式来改变得到的getters方法名

同理,不同的map方法会导出各自的方法
其中mapState, mapGetters将会导出适用于computed的方法
mapMutations, mapActions将会导出适用于methods的方法

这里以一个demo组件为例DemoVuexState.vue

import { mapState, mapGetters, mapMutations, mapActions } from 'vuex'
export default {
  data () {
    return {
    }
  },
  computed: {
  // vue的计算属性,计算属性内方法的私有变量变动会触发这个属性的重新计算
    ...mapState({
      mapStateFollow: ({demo}) => demo.demoFollow,
      mapStateFollowPending: ({demo}) => demo.demoFollowPending
    }),
    // mapState()直接读取State里的状态内容
    ...mapGetters(['demoFollowStatus'])
    // mapGetters()通过getters转化state从而得到你想要的内容
  },
  methods: {
  // vue的方法,可以是一个事件的方法,也可以是一个vuex的方法,也可以是一个普通函数
    ...mapMutations(['DEMO__VUEX_FOLLOW']),
    // 同步的改变状态
    ...mapActions(['demoFollowAjax'])
    // 异步的改变状态
  }
}

这段代码是一个demo里的片段,效果大家可以看这个呆萌,如果开心了可以在github库里加个星,如果有问题可以一起在下方评论里讨论讨论😀

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,390评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,821评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,632评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,170评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,033评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,098评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,511评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,204评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,479评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,572评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,341评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,893评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,171评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,486评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,676评论 2 335

推荐阅读更多精彩内容

  • 就在今年的10月份,Vue2.0发布啦,来懵逼的海洋里一起下沉吧! 前段阵子都没有发随笔,一方面要准备一场考试,另...
    leenty阅读 1,576评论 4 22
  • vuex 场景重现:一个用户在注册页面注册了手机号码,跳转到登录页面也想拿到这个手机号码,你可以通过vue的组件化...
    sunny519111阅读 7,999评论 4 111
  • 承接上文vue2.0一起在懵逼的海洋里越陷越深(二)前面写了vue-router组件的初步用法,原来这次想写vue...
    leenty阅读 1,564评论 4 9
  • 参考书目:《人生定位:特劳特教你营销自己》[美] 阿尔·里斯、杰克·特劳特 学会“靠”别人 一看到这个说法,我的第...
    仲夏夜之梦123阅读 198评论 2 7
  • 爱是什么 爱是怦然的心跳 爱是掌心的细汗 爱是眺望、是念想, 是源源不断的思绪; 爱是欢腾、是跳跃, 是上天又入地...
    LotusLi阅读 653评论 0 51