Vuex最全讲解

1. Vuex是什么

vuex是针对Vue.js应用程序开发的一套“状态管理模式”,其实也就是针对数据进行统一管理的模式

以前我们进行组件之间传值的时候,需要使用到父子组件之间的传值,是很麻烦的,也很容易出错,所以作为大型项目的时候,就需要使用到vuex来辅助进行数据的管理

  • state,驱动应用的数据源;
  • view,以声明方式将 state 映射到视图;
  • actions,响应在 view 上的用户输入导致的状态变化。

文字描述就是
state(数据)会影响view(视图)的显示

视图的变化会影响avtions(动作)

avtion的触发又会导致state的变更

动作图片

但是多个组件共享数据的时候,就会导致这个环形变换,所以就需要使用vuex


vuex的原理图片

使用vuex的场景:很多组件,并且组件之间需要共享数据的时候

2. 安装Vuex

npm install vuex --save

安装之后需要将vuex注册到main.js中,

import Vuex from 'vuex'

Vue.use(Vuex)

vuex依赖于Promise

npm install es6-promise --save
//需要将下面的这句话加在vuex引用之前
import 'es6-promise/auto'

3. 常规引用

一般我们引用vuex之后,会在src下创建一个store(仓库)的文件夹,这个文件夹中需要创建index.js文件

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

 Vue.use(Vuex)
 
 //创建一个数据仓库对象,将多组件需要使用的公共数据/方法放置到这个对象中
 export default new Vuex.Store({
     //这里就是多个组件共享的数据或者方法的地方
     //全局事件和数据
     state:{
        //放置数据  
        num:0
     },
     getters:{
         //计算属性使用,也就是将computed的信息提取公共的
     },
     mutations:{
        //放置方法
        addNum(state){//state是默认的参数(也就是上面那个state中的数据),可以使用state获取其中的传入参数信息
            state.num++
        }
     },
     actions:{
        //使用ajax的方法 
     },
     modules:{
        //模块
     }
 })

然后在更目录的main.js中需要注册这个store

import store from './store'
//实例化store对象
new Vue({
    router,
    store,
    render:h =>h(App)
}).$mount('#app')

4. 快速上手

对于如上的store配置信息,即放置了num数据和addNum方法的一个仓库,如何在其他组件中使用这个数据及方法呢?

在所有的创建的vue组件中,this下都可以获取到注册的store对象。

获取数据:{{$store.state.num}}

调用方法:在vue中调用方法中使用如下方式this.$store.commit('这个地方就是方法名')

同时可以获取到是哪个action(方法)修改的数据

5. 理解概念

5.1 State

数据

获取state的基础使用方法

  1. $store.state.xxx

  2. 使用computed来获取

    <script>
        export default{
            computed:{
                xxx:function(){
                    return this.$store.state.xxx
                }
            }
        }
    </script>
    //这样,对于<template></template>中就可以直接使用msg就获取到数据了
    
  3. computed的set/get方法

    <script>
        export default{
            computed:{
                xxx:{
                    get:function(){
                        return this.$store.state.xxx
                    },
                    set:function(){
                        //这里可以调用store中的方法来进行赋值信息
                        this.$store.commit('setNum',val)
                        //这里就是可以进行设置,同时传参,"setNum"就是使用的mutations中的方法,val就是实际参数
                    }
                }
            }
        }
    </script>
    //这样,对于<template></template>中就可以直接使用msg就获取到数据了
    同时,设置了一个参数computed的set和get方法,就可以使用v-model进行数据的绑定了
    
    

    在store的mutations中,可以使用两个参数来进行获取方法调用的参数

    mutations:{
        setNum(state,value){
            state.num=value;
        }
    }
    
    
  4. mapState 就是一次获取多个数据

    1. mapState:映射数据到computed
    1. 在需要使用到的组件中导入mapState
    import {mapState} from 'vuex'
    
    2. 在computed中使用mapState
        computed:mapState(['xxx','yyy','zzz'])其中名称就是store.state中的名称。直接使用即可
    
    1. 使用对象映射
    computed:mapState({
        x:'xxx',
        y:'yyy',
        z:(state)=>state.zzz
        //这个地方就相当于运算服了
    }) 
    
    1. 使用computed的其他属性
        computed:{
            xxx:function(){
                xxxxxxxx
            },
            ...mapState({//注意这个地方的...
                xxx,
                yyy,
                zzz:(state)=>state.zzz++
            })
        }
    

综上所述:

Get一个state,可以使用`this.$store.state.xxx`来获取

Set一个state,可以定义一个mutations的方法来触发
定义的时候,需要绑定两个参数,一个是state,一个是val。然后使用this.$store.commit('方法名',val)来进设置

如果state过多的话,还可以使用mapState进行调用

5.2 Getters

可以将计算属性提取出来作为公共信息

定义的时候如下

getters:{
    doneNumAdd:state=>{
        return state.num+1;
    }
}

调用的时候如下

store.getters.doneNumAdd

类似的getters也就辅助函数mapGetters具体使用方法可以见官方文档

5.3 Mutations

这个理解上还有点偏差,需要重新理解

更改state中的信息的唯一方法就是用Mutations进行信息的变更

定义方式

mutations:{
    addCount(state){
        state.count++
    }
}

调用方式

store.commit('addCount')

当然,也可以使用其他参数,addCount(state,val)this.$store.commit('addCount',val)

另外一种风格的调用

this.$store.commit({
    type:'addCount',//这个就是调用的方法名
    val:'10'//这个就是传入的实际参数
})

5.4 Actions

这个是定义<big >异步</big>回调的时候使用的。与mutations不同的是

  • actions调用的都是mutation
  • actions可以包含任意异步操作

按照之前的vuex操作上来看,这个是与后台交互使用的,也就是说,后台交互使用actions之后,actions去驱动mutation的发生从而导致state的变化。这样就完成了用户查看component的变更

注意点:异步的操作确实是可以在actions中做,但是对于state的修改,最好还是在mutations中进行修改

定义avtion,方式与mutations一样,只是在avtion标签中进行的操作

actions:{
    addCount:function(){
        //1. 请求后台接口,获取数据
        //2. 调用mutations中的方法来修改state
    }
}

调用actions

在js中的方法调用时使用

methods:{
    getCountAdd:function(){
        this.$store.dispatch('addCount')
        //addCount就是actions中的方法名
    }
}

5.5 Modules

模块

  1. 需要分割开state,getters,mutations,actions在各个文件中,这样方便管理
    只需要创建对应xxx.js的文件,然后再store/index.js中注册对应的js文件即可

    例:创建state

    export default{
        age:23,
        name:'小红'
    }
    

    index.sj导入state

    import stateObj from './state'
    
    export default new Vuex.Store{
        state:stateObj
        //也可以使用集合的方式写进去
    }
    
  2. 根据模块的方式来区分出来,即导入模块属性

    创建mudule,然后咋index.js中的mudules中导入即可

    1. 创建模块
    export default{
        state:{
            
        },
        getters:{
            
        },mutations:{
            
        }
    }
    
    2. 导入模块
    import xxxMudule from './xxx/xxx'
    mutuals:{
        xxxMudule
    }
    

就是进行上面四个的管理使用的

大型vuex的项目结构

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