Vuex介绍01

安装和使用

import Vuex from 'Vuex'

Vuex

Vuex是一种状态管理模式,它集中式的管理应用所有组件的状态

  1. 一个简单的vuex实例包含了以下部分
  • state,驱动应用的数据源
  • view,以声明的方式将数据映射到视图
  • action,响应在view上的用户输入导致的状态变化

开始

  1. 和全局对象有以下两点不同
  • Vuex的状态存储响应式的
  • 不能直接改变store中的状态
  1. 该方式直接使用script标签引入vue和vuex
    const store = new Vuex.Store({
        state:{
            count: 0
        },
        mutations: {
            increment (state) {
                state.count++;
            }
        }
    });
    store.commit('increment');
    console.log(store.state.count);

计数实例

<div id="app">
  <p>{{ count }}</p>
  <p>
    <button @click="increment">+</button>
    <button @click="decrement">-</button>
  </p>
</div>
const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment: state => state.count++,
    decrement: state => state.count--
  }
})

new Vue({
  el: '#app',
  computed: {
    count () {
        return store.state.count
    }
  },
  methods: {
    increment () {
      store.commit('increment')
    },
    decrement () {
        store.commit('decrement')
    }
  }
})

State

  1. 有以下特征
  • 单一状态树
  1. 一般通过vue实例中的计算属性返回state中的数据
  2. 为了从根组件注入到每一个子组件,可以在vue实例中,使用store选项引入store。同时,在子组件中使用this.$store获取
// vue实例中
const app = new Vue({
  el: '#app',
  // 把 store 对象提供给 “store” 选项,这可以把 store 的实例注入所有的子组件
  store,
  components: { Counter },
  template: `
    <div class="app">
      <counter></counter>
    </div>
  `
})

// 子组件中
const Counter = {
  template: `<div>{{ count }}</div>`,
  computed: {
    count () {
      return this.$store.state.count
    }
  }
}

mapState

如果,每个state中数据都需要定义,太麻烦。可以使用mapState方法

// 一定要引入该方法
import { mapState } from 'vuex'
// 当state中数据不用改变的时候,使用字符串数组
export default {
    computed: mapState(['count','else']);
}

// 当state中数据需要改变的时候,使用对象
export default {
    computed: mapState({
        count: state => state.count,
        countAlias: 'count',
        allCount (state) {
            return this.localCount + state.count
        }
    });
}
// 项目中使用,组件中
export default {
    computed: {
        ...mapState({
            compComputedA: SET_AIR,
            compComputedB: SER_LAND
        }),
        compComputedC: SER_SKY
    }
}

对象展开运算符

通常情况下,vue组件不仅需要定义自己的计算属性,同时要用计算属性承接state中的各个数据。

export default {
    computed: {
        ...mapState({

        }),
        comp1 () {

        }
    }
}

组件依旧保留局部性

有些严格属于组件的数据,依旧应该保存为组件数据

getters

其实某个state数据中,在多个组件中被修改,但是被修改的逻辑是相同。可以通过下边的这种方式,进行复用

  1. 其实Vuex中的getters就像是computed,计算属性,使用方式也相同
  2. getters中方法的参数
  • 第一个参数是state
  • 第二个参数是getters,这样可以访问getters中其他方法
// Vuex
Vuex.Store({
    state: {
        count: 1
    },
    // 相当于根据state进行一定的修改,但不是直接修改!!!!
    getters: {
        allCompCount (state) {
            return state.count + 1;
        }
    }
});

// 子组件
Vue.component('my-comp',{
   template: '<p></p>',
   computed: {
       myComp () {
           return this.$store.getters.allCompCount
       }
   }
});

mapGetters 辅助函数

该函数的功能,是将store上的getters映射到子组件上

Mutations

只有Mutations能够改变state中的数据

  1. 提交荷载payload
  2. 整个参数使用含有type的对象
  3. Mutations需要遵守的响应式规则
  • 所有根级state数据,需要在Vuex中定义好
  • 使用Vue.set(obj,key,val)添加或者设置对象属性
  • 或者使用var newObject = {...oldObject,newPro:newVal}
  1. 使用常量代替Mutations代替事件类型,可以使linter工具发挥作用
  • 具体使用,参考Vuex,不是很了解
  1. Mutations 必须是同步函数
  2. 在组件中提交Mutations
  • 该方法的参数,可以是字符串数组
  • 可以是对象
// 这个是定义
mutations: {
   increment: function (state) {
       // 默认参数
   }
}


//  下面都是使用
// 单个荷载  
state.commit('increment',10);
// 多个荷载
state.commit('increment',{
    count: 10,
    all: 100
});
// 整个使用含有 type 的对象传递
state.commit({
    type: 'increment',
    count: 10,
    all: 100
});
// 在子组件中提交 Mutations
import { mapMutations } from 'vuex'

methods: {
    ...mapMutations({
        add: 'increment'
    }),
    elseMethods
}

Actions

Actions解决了Mutations不能执行异步函数的问题

  1. Actions有以下特性
  • Actions提交的是Mutations,不是直接改变state
  • Actions可以执行任何异步操作
  1. Actions中没每个方法都可以接受一个参数context,该参数不是store,但是通过它可以访问store的属性和方法。该参数通常使用对象解构的方式接受
  • context.state
  • context.getters
  • context.commit
  • context.dispatch
  1. 分发Actions
  • store.dispatch('increment')
  • 支持对象和荷载的方式分发
  1. 组件中分发Actions
  • 和Mutations在组件中分发的方式相同
// 对象参数分发
store.dispatch({
    type: 'increment',
    count: 10
});
// 荷载方式分发
store.dispatch('increment',{
    count: 10
});

组合Actions

如何知道Actions的异步执行完毕?如何在其他Actions中使用?

  1. 异步执行的Actions,需要返回一个Promise对象
  2. 在其他地方调用
  3. 结合async/await,暂时不知道
// 异步执行的Actions应该的定义方式
// 返回的Promise对象,记得要在完成的时候将状态标记为resolve
Actions: {
    actionA ({ commit }) {
        return new Promise(function(resolve,reject){
            setTimeOut(()=>{
                commit('increment');
                resolve();
            },100);
        });
    }
}
// 在其他地方调用
store.dispatch('actionA').then(()=>{

});
// 在其他Actions中使用
Actions: {
    actionA ({ dispatch }) {
       dispatch('actionA').then(()=>}{

       });
    }
}

Modules

由于store可能过于庞大,因此,允许使用模块的方式来定义

Modules 的基础使用

var moduleA = {
    state: {},
    mutations: {},
    actions: {}
}
var moduleB = {
    state: {},
    mutation: {},
    actions: {}
}
var store = new Vuex.Store({
    modules: {
        moduleA,
        moduleB
    }
});
//  !!!! 注意,使用的时候模块名称是在后边的
store.state.moduleA

Modules 的局部状态

由于局部性,在模块中的参数,有所增加。从此,可以看出context不是store

// 模块中的各个方法的参数
getters: {
    g (state,getters,rootState) {}
}
mutations: {
    m (state,payload) {}
}
actions: {
    a ({state,rootState,commit,getters,dispatch}) {}
}

命名空间

通过namespace:true定义该模块使用命名空间

  1. 使用命名空间的模块,在外部访问的时候需要添加上命名空间
// 定义
modules: {
    moduleA: {
        accout: {
            namespace: true,
            state: {},
            mutations: {},
            getters: {},
            actions: {} 
        }

    }
}
store.commit('account/m');
store.dispatch('account/a');
// 选用getters的方式不同
store.getters['account/g'];  // 使用的是中括号

// 项目中,有命名空间,但是没有用`spacename:true`,反而将 路径 赋值给一个常量
// 
export default {
    methods: {
        ...mapMutations({
            m01: 'CAMERA/SET_CAMERA',
            m02: SET_CAMERA
        })
    }
}

在命名空间中访问全局内容更

modules: {
    moduleA: {
        namespace: true,
        state: {},
        mutations: {},
        getters: {
            g (state,getters,rootState,rootGetters) {
                getters.someOtherGetter // -> 'moduleA/someOtherGetter'
                rootGetters.someOtherGetter // -> 'someOtherGetter'
            }
        },
        actions: {
            a ({ dispatch, commit, getters, rootGetters }) {
                getters.someGetter // -> 'foo/someGetter'
                rootGetters.someGetter // -> 'someGetter'
                dispatch('someOtherAction') // -> 'foo/someOtherAction'
                dispatch('someOtherAction', null, { root: true }) // -> 'someOtherAction'
                commit('someMutation') // -> 'foo/someMutation'
                commit('someMutation', null, { root: true }) // -> 'someMutation'
            }
        }
    }
}

带命名空间的绑定函数

参数使用对象的方式,比较麻烦,可以使用负载的方式

computed: {
  ...mapState('some/nested/module', {
    a: state => state.a,
    b: state => state.b
  })
},
methods: {
  ...mapActions('some/nested/module', [
    'foo',
    'bar'
  ])
}

总结

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

推荐阅读更多精彩内容

  • 安装 npm npm install vuex --save 在一个模块化的打包系统中,您必须显式地通过Vue.u...
    萧玄辞阅读 2,924评论 0 7
  • vuex 场景重现:一个用户在注册页面注册了手机号码,跳转到登录页面也想拿到这个手机号码,你可以通过vue的组件化...
    sunny519111阅读 8,006评论 4 111
  • Vuex是什么? Vuex 是一个专为 Vue.js应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件...
    萧玄辞阅读 3,102评论 0 6
  • Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应...
    白水螺丝阅读 4,652评论 7 61
  • Vuex 的学习记录 资料参考网址Vuex中文官网Vuex项目结构示例 -- 购物车Vuex 通俗版教程Nuxt....
    流云012阅读 1,448评论 0 7