2020-06-24 VueX

Vuex概述

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

  • vuex是vue的一个插件(vue-router也是一个插件)。它提供多组件之间共享数据的解决方案。

    Vue.use(vueRouter) // vue在使用它的插件时,都是Vue.use(插件)
    如果你要给Vue提供一个插件,则它的使用方式一定是Vue.use() 
    
  • vuex 也集成到 Vue 的官方调试工具 devtools extension,提供了诸如零配置的 time-travel 调试、状态快照导入导出等高级调试功能。

它是渐进式的重要支撑

渐进式:vue是一个渐进式的框架。

  • 它的核心很简单

  • 通过引入插件的方式,给它补充新的功能、使用它的新功能...

[图片上传失败...(image-4db6d8-1593994087161)]

上图中的大规模状态管理就是vuex。

应用场景:多组件共享状态

vuex的作用是解决多组件状态共享的问题。

  • 它是独立于组件而单独存在的,所有的组件都可以把它当作一座桥梁来进行通讯。

  • 与事件总线(EventBus)相比,它具备额外的特点:

    • 响应式

    • 操作更简洁

[图片上传失败...(image-43d72c-1593994087161)]

什么数据适合存储在vuex中

一般情况下,只有多个组件均需要共享的数据,才有必要存储在vuex中,对于某个组件中的私有数据,依旧存储在组件自身的data中。

例如:

  • 对于所有组件而言,当前登陆的用户名是需要在全体组件之间共享的,则它可以放在vuex中

  • 对于文章详情页组件来说,当前的用户浏览的文章数据则应该属于这个组件的私有数据,应该要放在这个组件的data中。

结论: 不要把全部的数据放在vuex中, 除非要在多个组件之间共享。

小结

是官方提供的插件,解决多组件之间状态(数据)共享

与eventBus的相同点:

  • 独立于组件体系

不同点

  • 具有数据响应式的特点

核心概念-state

State提供唯一的公共数据源,所有共享的数据都要统一放到Store中的State中存储。打开项目中的store.js文件,在state对象中可以添加我们要共享的数据。

在vuex中设置

// 引入Vue
import Vue from 'vue'
// 引入vuex插件
import Vuex from 
​
// 由于它一个vuex插件,所以,还要以插件的方式挂载在vue上。
// 1\. 插件的方式挂载在vue
Vue.use(Vuex)
​
// 2.创建Vuex.Store实例
// Vuex是一个对象,其中有一个属性名是Store,属性值是一个函数
// 这在这里充当一个构造器
const store = new Vuex.Store({
// 各种配置项
// (1)state。 就相当于vue组件中的data。它用来存放整个vue项目中公共的数据
//       这个数据,在所有的vue组件中都可以访问到
state: {
num: 101
}
})

它的设置方式类似于组件中data数据项的设置方式。

在组件内使用state

如何在组件中去使用state中定义的公共的数据项?

有两种方法:

  • 方法一:直接使用

    • 语法:this.$store.state.全局数据名称

    • 应用场景:获取数据,修改数据(不要直接去改)

  • 方法二:映射使用

    • 语法:mapState

    • 应用场景:获取数据,不能修改

直接使用

在任意组件的内部(无论嵌套级别),可以直接通过vue实例中的$store来访问。

格式:

this.$store.state.全局数据名称

示例:

# 获取:在代码中:
this.$store.state.count
​
# 获取:在视图中,可以省略this.
{{$store.state.count}}
​
# 修改:
# 不要直接去改
this.$store.state.count = "新值" 

映射使用

把Vuex中的公共数据引入到组件中,当作计算属性 来使用。

步骤:

  1. 按需导入mapState函数: import { mapState } from 'vuex'

  2. 数据映射为计算属性computed:{ ...mapState(['全局数据名称']) }

例如:

// 通过映射的方式来使用vuex.store中的数据
// 1\. 导入vuex中定义工具函数 mapState 
//    es6中的按需导入
import { mapState } from 'vuex'
// mapState是vuex中定义一个函数
// mapState(['count']) : 执行一个函数,并传入参数。
//      参数是一个数组,其中有一个元素,这个传参的格式是 mapState要求的。
//      它的返回值是:一个对象,格式是{count:function(){}}
​
//  在如下代码中,调用 mapState这个函数,把得到的对象合并到当前的外层对象中。
//  {
//      f: function(){ },
//      ...mapState(['count'])
//  }    
​
console.log(mapState(['count']))
​
export default {
 name: 'app',
 components: {
 AddItem,
 SubItem
 },
 // 下面的代码中有几个计算属性?
 // 2个。
 // 名字分别是: cA,count
 computed: {
 // 定义App.vue自已的计算属性
 cA () {
 return 100
 },
 // 调用 mapState这个函数,把得到的对象合并到当前的外层对象computed中
 ...mapState(['count'])
 }
}

注意:

  • mapState是vuex中的一个函数;

  • vuex是我们安装的包,它是一个对象,有很多的方法,第一句是引入Vuex中的mapState方法。相当于import Vuex from 'vuex'; const mapState = Vuex.mapState;

    [图片上传失败...(image-919280-1593994087159)]

  1. mapState(["count"]) 得到的是一个对象,其中有一个方法名是count,这个对象类似于{count:function(){}}

    [图片上传失败...(image-9737e-1593994087159)]

  2. ...obj 是es6新增的扩展运算符,这里用来把mapState(["count"]) 得到的对象合并到computed这个对象中。

整个过程的示意图如下:

[图片上传失败...(image-d90f2e-1593994087160)]

核心概念-mutation

作用

在vue中,不推荐直接在组件内部通过this.$store.state.全局数据名称=新值来修改vuex数据,而推荐使用mutation来修改。

定义格式

mutation具体在代码中表现为创建Vuex.Store实例时,所传入的参数对象中的mutations项,具体格式如下:

new Vuex.Store({
 state:{},
 mutations:{
 // 函数名可以是任意合法的函数名
 // 参数1:表示当前state
 // 参数2:可选。它表示调用函数1时,传入的参数。
 函数名1(参数1,参数2){
 // 在函数内部,修改state中的数据
 }
 }
})

说明:

  • mutations是固定写法(有一个s)

  • mutations定义完成之后,就等待被调用。它的作用是用来修改vuex中的数据。

添加mutaions

在定义vuex时,我们在Vuex.Store()中配置一下mutaions属性。把你要修改state数据的代码提前写好!

它有带参数和不参数两种情况,具体如下。

import Vue from 'vue';
import Vuex from 'vuex';
​
Vue.use(Vuex);
​
export default new Vuex.Store({
 // 各种配置项
 // state 就相当于vue组件中的data。它用来存放整个vue项目中公共的数据
 //       这个数据,在所有的vue组件中都可以访问到
 state: {
 num: 101,
 count: 21.5,
 person: {
 name: '张三'
 }
 },
 mutations: {
 // 下面定义mutation。本质就是一个函数
 // 特殊之处:在定义函数时,第一个参数就表示当前vuex中的state
 //          直接在此函数内部去修改state.
 //          在调用这个函数时,第一个参数不要传入。
 // 1.不带参数的mutation
 mAdd1(state){
 // 这个mutation的作用就是让state中的num加1
 state.num++
 },
 // 2\. 带参数的mutation
 mAddN(state, n){
 // 这个mutation的作用就是让state中的num加 n
 // 这个n是需要额外传入的
 state.num = state.num + n
 }
 }
});
  • mutations对象中的成员均是函数,并且有自己特定的格式。

  • 如上所示的mAdd1函数,它的第一个参数固定表示当前的state的引用,在调用这个mAdd1函数时,你也不需要去设置第一个实参。

  • mAddN的第一个参数不用传入,第二个参数需要传入。

使用mutations

在组件内部我们要想调用mutations中定义的方法来改变state中的值, 有两种方法:

方式一:直接使用

this.$store.commit("mutaions的名字",参数)</pre>

方式二:映射使用

  • 映射成组件的methods

直接使用

在组件内部,可以通过如下方式来直接调用指定mutations

格式

this.$store.commit(mutations函数名,参数)
// mutations函数名,就是在定义Vuex.store时,设置的mutations中的方法名;
// 第二个参数是可选的,它表示调用mutations时传入的额外的参数,它可以是任意数据类型。</pre>

mapMutations

在组件内部使用vuex中的mutaion的第二种方法,就是把mutations中的属性映射到组件的methods上成为当前组件的方法来使用。

<script>
// 在组件中通过映射的方式来使用vuex中的mutations
// 1\. 引入工具函数
import { mapMutations } from 'vuex'
// mapMutations 是一个函数,在vuex中定义的。
// mapMutations(['mAdd1', 'mAddN'])的返回值是一个对象
//       这个对象类似于{mAdd1:function(){}, mAddN:function(){}}
// 2\. 在methods中 插入 映射函数的结果
​
export default {
 name: 'SubItem',
 // 下面的代码中,相当于methods中定义了 4个方法 
 // sub,mAdd1,mAddN, test
 methods: {
 sub () {
 this.$store.state.num--
 },
 ...mapMutations(['mAdd1', 'mAddN']),
 test () {
 // 由于上面的mAdd1并映射成方法,所以这里可以直接加this.来访问。
 // this.mAdd1()
 this.mAddN(100)
 }
 }
}
</script>

vuex小结

  • 作用:当你需要管理组件之间的公共数据时,就可以使用vuex。

  • 是:vue官方提供的插件,类似于vue-router,专门用来进行公共状态管理。

  • 步骤:

      1. 安装。 它是一个独立的npm包,要去下载安装。
          npm i vuex
          或者:在通过脚手架工具创建项目就去选中vuex。
      
      1. 创建Vuex.Store的实例,导出。
      1. 初始化vue 实例时,设置store。
  • 核心概念:

    • state : 所有的公共数据放在state中。

      • 获取

        • 直接使用。 this.$store.state.XXX

        • 映射使用。映射成组件内部的计算属性. computed: { ...mapState(['XXXX'])}

      • 设置

        • this.$store.state.XXX = 新值。(不推荐....)
    • mutations: 更新数据

        new Vuex.Store({
         state: {},
         mutations: {
         f1(state) {}, 
         f2(state,p) {}
         }
        })

定义数据

作用:定义全局数据。类似data。

定义方式:

new Vuex.Store({
 state:{
 name:'小王',
 age:30
 }
})

获取数据

state

  • 在template中用插值的方式{{$store.state.age}}

  • 在js代码中直接使用: this.$store.state.num

  • map使用: computed:{ ...mapState(['num']) }

修改数据

不推荐直接使用: this.$store.state.num = 新值

通过mutations,有两种方式去激活mutation:

  • 直接使用: this.$store.commit('mutation名-字符串',实参);

  • map使用:methods:{ ...mapMutations(['mutation名'])}

两个特点

  • 独立性

    • 数据与项目中的所有组件无关

    • 任意组件中均可以操作数据

  • 响应式

    • 数据变化了,视图也会变化

其它内容:

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