vuex学习笔记

前言

我们需要解决多个组件间的数据通信和状态管理就显得难以维护的问题,在vue中用的是vuex,在react中用的是redux.通过本篇教程将基本熟悉它的所有常用用法以及注意事项。

用于解决什么问题?

用于解决组件之间数据共享,数据的集中处理。

什么是vuex ?单项数据流

image

基本使用

#安装
npm install --save vuex
#引入 一般我们会在src根目录下创建一个store的文件夹,
#下面写index.js来实现相关的存储方法(组件共用数据)
import Vuex from 'vuex'
import Vue from 'vue'
Vue.use(Vuex)

vuex的组成部分(应用结构)

image

State

State负责存储整个应用的状态数据,一般需要在使用的时候在跟节点注入store对象,后期就可以使用this.$store.state直接获取状态。一般是在main.js文件中引入store的文件,从而使用。(vue spa应用中)

//store为实例化生成的
import store from './store'

new Vue({
  el: '#app',
  store,
  render: h => h(App)
})

这个store可以理解为一个容器,包含着应用中的state等。实例化生成store的过程是:

const mutations = {...};
const actions = {...};
const state = {...};

Vuex.Store({
  state,
  actions,
  mutation
});

后续在组件中使用的过程中,如果想要获取对应的状态你就可以直接使用this.$store.state获取,当然,也可以利用vuex提供的mapState辅助函数将state映射到计算属性中去,如

// 我是组件

let name=this.$store.state.name

import {mapState} from 'vuex'

export default {
  computed: mapState({
    count: state => state.count
  })
}

Mutations

Mutations的中文意思是“变化”,利用它可以更改状态,本质就是用来处理数据的函数,其接收唯一参数值state。store.commit(mutationName)是用来触发一个mutation的方法。需要记住的是,定义的mutation必须是同步函数,否则devtool中的数据将可能出现问题,使状态改变变得难以跟踪。

const mutations = {
  mutationName(state) {
    //在这里改变state中的数据
  }
}
在组件中触发:

//我是一个组件
export default {
  methods: {
    handleClick() {
      this.$store.commit('mutationName')
    }
  }
}

或者使用辅助函数mapMutations直接将触发函数映射到methods上,这样就能在元素事件绑定上直接使用了。如:

import {mapMutations} from 'vuex'

//我是一个组件
export default {
  methods: mapMutations([
    'mutationName'
  ])
}

Actions

Actions也可以用于改变状态,不过是通过触发mutation实现的,重要的是可以包含异步操作。其辅助函数是mapActions与mapMutations类似,也是绑定在组件的methods上的。如果选择直接触发的话,使用this.$store.dispatch(actionName)方法。action内部支持异步方法,这是很重要的一点区别。

//定义Actions,以下方法用了es5的解构
const actions = {
  actionName({ commit }) {
    //dosomething
    commit('mutationName')
  }
}
//等同于下面的代码
const actions = {
  actionName({context ) {
    //dosomething
    context.commit('mutationName')
  }
}

在组件中使用

import {mapActions} from 'vuex'

//我是一个组件
export default {
  methods: mapActions([
    'actionName',
  ])
}
//分发action
store.dispatch('actionname')

Getters

有些状态需要做二次处理,就可以使用getters。通过this.$store.getters.valueName对派生出来的状态进行访问。或者直接使用辅助函数mapGetters将其映射到本地计算属性中去。这个属性相当于vuex的计算属性。

const getters = {
  strLength: state => state.aString.length
}
//上面的代码根据aString状态派生出了一个strLength状态
在组件中使用

import {mapGetters} from 'vuex'

//我是一个组件 ,可以利用mapGetters
export default {
  computed: mapGetters([
    'strLength'
  ])
}
//直接使用getters
  computed:{namelen(){
      return this.$store.getters.namelen
    }
  }

Plugins

插件就是一个钩子函数,在初始化store的时候引入即可。比较常用的是内置的logger插件,用于作为调试使用。

import createLogger from 'vuex/dist/logger'
const store = Vuex.Store({
  ...
  plugins: [createLogger()]
})

模块化

随着项目的复杂性增加,我们共享的状态越来越多,这时候我们就需要把我们状态的各种操作进行一个分组,分组后再进行按组编写。

// 一般我们用常量申明模块组:
const moduleA={
    state,mutations,getters,actions
}

export default new Vuex.Store({
    modules:{a:moduleA}
})
// 基本使用 ,加上state.a的命名空间即可
computed:{
    count(){
        return this.$store.state.a.count;
    }
},

注意事项

vuex与持久存储localStorage的关系

场景 :发现部分开发在引入持久存储之后,mutation的时候没有改变state,而是直接修改的localStorage,这样会导致没有页面刷新时,拿到的state都是不对的。因为state不会实时监听localStorage的更改。

解决方案
1 更改state的时候,除了更改localStorage,也要更改state,而且更改state才是必须要做的,而更改localStorage只是为了解决刷新页面后数据丢失的问题。(推荐方式,毕竟使用vuex的全套才是正宗)

2 如果你觉得上面的方案每次都写很麻烦,也可以尝试增加locastorage的监听机制,当发生变化的时候,寻找更改对应的state.

拓展符写法

在mapState,mapActions,mapMutations使用的时候,为了不影响正常方法的使用,我们可以使用对象以及数组的拓展方法进行拓展。

methods:{
    ...mapMutations([  
        'add','reduce'
    ]),
    ...mapActions(['addAction','reduceAction'])
},
// 获取state属性,你也可以采用这种写法
import {mapState} from 'vuex';
computed:mapState({
        count:state=>state.count
 })

单页中直接定义使用(特别说明)

// 如果在模块化构建系统中,请确保在开头调用了 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,需要掌握以下的几点。

1 组件数据共享,跨页面数据共享,可以统一管理数据的存储,操作,分发。比如用户数据,比如固定的某些数据是固定某些api获取的且不止用于一个组件或者一个场景。

2 不要形式主义,每个页面都用vuex;每个模块都写getters,actions,常量方法,当你的工程量、数据量达到使用某技术场景的时候,采用某方案会觉得恰如其分

3 处理基于数据的业务逻辑,一般是跨页面跨组件的,比如购买流程对用户余额,购物车,订单的联动影响

4 vuex核心的index做一些模块公用的存储工具,可以配置一些需要的插件或者工具类

5 拓展:数据通讯不止vuex,简单的也可以用event bus,甚至页面内的已经能符合你的需求了

其他

最后,还有一些高级用法,如严格模式,测试等可能使用频率不会特别高。有需要的时候查官方文档就可以了。总的来说,Vuex还是相对比较简单的,特别是如果之前有学过Flux,Redux之类的话,上手起来更加容易。

参考文档

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

推荐阅读更多精彩内容

  • Vuex 是什么? ** 官方解释:Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式**。它采用集中...
    Rz______阅读 2,306评论 1 10
  • vuex学习笔记 vuex是什么? Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存...
    EL_PSY_CONGROO阅读 770评论 0 0
  • 学习目的 了解和熟练使用 VueX,能够在实际项目中运用。 VueX介绍 Vuex 是一个专为 Vue.js ...
    _1633_阅读 2,794评论 0 7
  • 概要 官方解释Vuex是一个专为Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态...
    许小花花阅读 449评论 0 0
  • vuex 状态管理器 作为应用中所有组件的中央储存 只能以预定的方式去操作状态 把所有组件共享的状态抽取出来作为全...
    一只大椰子阅读 790评论 0 1