vuex导入_vuex深入理解 modules

一、什么是module?

背景:在Vue中State使用是单一状态树结构,应该的所有的状态都放在state里面,如果项目比较复杂,那state是一个很大的对象,store对象也将对变得非常大,难于管理。

module:可以让每一个模块拥有自己的state、mutation、action、getters,使得结构非常清晰,方便管理。

二、怎么用module?

一般结构

const moduleA = {

state: { ... },

mutations: { ... },

actions: { ... },

getters: { ... }

}

const moduleB = {

state: { ... },

mutations: { ... },

actions: { ... }

}

const store = new Vuex.Store({

modules: {

a: moduleA,

b: moduleB})

模块内部的数据:①内部state,模块内部的state是局部的,也就是模块私有的,比如是car.js模块state中的list数据,我们要通过this.

math?formula=store.state.car.list%E8%8E%B7%E5%8F%96%EF%BC%9B%E2%91%A1%E5%86%85%E9%83%A8getter%E3%80%81mutation%E5%92%8Caction%EF%BC%8C%E4%BB%8D%E7%84%B6%E6%B3%A8%E5%86%8C%E5%9C%A8%E5%85%A8%E5%B1%80%E5%91%BD%E5%90%8D%E7%A9%BA%E9%97%B4%E5%86%85%EF%BC%8C%E8%BF%99%E6%98%AF%E4%B8%BA%E4%BA%86%E5%A4%9A%E6%A8%A1%E5%9D%97%E5%8F%AF%E4%BB%A5%E5%90%8C%E6%97%B6%E5%93%8D%E5%BA%94%E5%90%8C%E4%B8%80mutation%EF%BC%9Bthis.store.state.car.carGetter的结结果是undefined,而通过this.$store.state.carGetter则可以拿到。

传参:getters====({state(局部状态),getters(全局getters对象),roosState(根状态)});actions====({state(局部状态),commit,roosState(根状态)}).

三、新建一个项目体验一下,通过vue –cli新建一个项目, 不要忘记安装vuex,cnpm install vuex --save

不了解的童鞋可以看我的 ----深入理解vue脚手架vue-cli文章这里详细介绍了新建vue-cli项目

ps: 想了解更多vuex相关知识请点击vuex官网

1, 在src 目录下新一个login文件夹,在里面新建index.js 用于存放login 模块的状态。 为了简单起见,我把模块下的state, actions,mutations, getters 全放在index.js文件中。

先简单给它增加一个状态,userName: “sam”

const state = {

useName: "sam"

};

const mutations = {

};

const actions = {

};

const getters = {

};

// 不要忘记把state, mutations等暴露出去。

export default {

state,

mutations,

actions,

getters

}

2,在src 目录下,再新建一个 store.js 这是根store, 它通过modules 属性引入 login模块。

import Vue from "vue";

import Vuex from "vuex";

Vue.use(Vuex);

// 引入login 模块

import login from "./login"

export default new Vuex.Store({

// 通过modules属性引入login 模块。

modules: {

login: login

}

})

3, 在main.js中引入store, 并注入到vue 根实例中。

import Vue from 'vue'

import App from './App.vue'

// 引入store

import store from "./store"

new Vue({

el: '#app',

store, // 注入到根实例中。

render: h => h(App)

})

4,在 app.vue 中通过computed属性获取到login下的state. 这里要注意,在没有modules 的情况下,组件中通过 this.

math?formula=store.state.%E5%B1%9E%E6%80%A7%E5%90%8D%20%E5%8F%AF%E4%BB%A5%E8%8E%B7%E5%8F%96%E5%88%B0%EF%BC%8C%E4%BD%86%E6%98%AF%E6%9C%89modules%20%E4%B9%8B%E5%90%8E%EF%BC%8Cstate%20%E8%A2%AB%E9%99%90%E5%88%B6%E5%88%B0login%20%E7%9A%84%E5%91%BD%E5%90%8D%E7%A9%BA%E9%97%B4%EF%BC%88%E6%A8%A1%E5%9D%97%EF%BC%89%E4%B8%8B%EF%BC%8C%E6%89%80%E4%BB%A5%E5%B1%9E%E6%80%A7%E5%90%8D%E5%89%8D%E9%9D%A2%E5%BF%85%E9%A1%BB%E5%8A%A0%E6%A8%A1%E5%9D%97%E5%90%8D%EF%BC%88%E5%91%BD%E5%90%8D%E7%A9%BA%E9%97%B4%EF%BC%89%EF%BC%8C%E7%BB%84%E4%BB%B6%E4%B8%AD%E9%80%9A%E8%BF%87%20this.store.state.模块名.属性名,在这里是 this.$store.state.login.userName

logo.png

{{useName}}

export default {

// computed属性,从store 中获取状态state,不要忘记login命名空间。

computed: {

useName: function() {

return this.$store.state.login.useName

}

}

}

组件中成功获取到状态。项目目录和展示如下

a0c11ae01991

5,通过actions, mutations 改变名字, 这就涉及到dispatch action, commit mutations, mutations 改变state.

先在login 文件夹 index.js中添加changeName action 和 change_name mutations.

const mutations = {

change_name (state, anotherName) {

state.useName = anotherName;

}

};

const actions = {

changeName ({commit},anotherName) {

commit("change_name", anotherName)

}

};

在app.vue 中添加一个按钮: change to json, 点击时,dispatch 一个 action. 那在组件中怎么dispatch actions 呢?

在模块中,state 是被限制到模块的命名空间下,需要命名空间才能访问。 但actions 和mutations, 其实还有 getters 却没有被限制,在默认情况下,它们是注册到全局命名空间下的,所谓的注册到全局命名空间下,其实就是我们访问它们的方式和原来没有module 的时候是一样的。比如没有module 的时候,this.

math?formula=store.dispatch(%E2%80%9Cactions%E2%80%9D)%2C%20%E7%8E%B0%E5%9C%A8%E6%9C%89%E4%BA%86modules%2C%20actions%20%E4%B9%9F%E5%86%99%E5%9C%A8%E4%BA%86module%20%E4%B8%8B%E9%9D%A2%EF%BC%88changeName%20%E5%86%99%E5%88%B0%E4%BA%86login%E7%9B%AE%E5%BD%95%E4%B8%8B%E7%9A%84index.js%E4%B8%AD%EF%BC%89%EF%BC%8C%E6%88%91%E4%BB%AC%E4%BB%8D%E7%84%B6%E5%8F%AF%E4%BB%A5%E8%BF%99%E4%B9%88%E5%86%99%EF%BC%8Cthis.store.dispatch(“changeName”), 组件中的getters, 也是通过 this.$store.getters.module中getters 来获取。

logo.png

{{useName}}

change to json

export default {

// computed属性,从store 中获取状态state,不要忘记login命名空间。

computed: {

useName: function() {

return this.$store.state.login.useName

}

},

methods: {

// 和没有modules的时候一样,同样的方式dispatch action

changeName() {

this.$store.dispatch("changeName", "Jason")

}

}

}

6, 局部参数

虽然dispatch action和 commit mutations 可以全局使用,但是写在module 中的actions, mutations 和getters, 它们获得的默认参数却不是全局的,都是局部的,被限定在它们所在的模块中的。比如mutations和getters 会获得state 作为第一个默认参数,这个state参数,就是限定在mutations 和getters 所在模块的state对象,login 文件夹下的mutations 和getters 只会获取到当前index.js 中的 state 作为参数 。 actions 会获得一个context 对象作为参数,这个context 对象就是当前module 的实例,module 相当于一个小store.

那么怎样才能获取到根store 中的state 和 getters 呢? Vuex 提供了 rootState, rootGetters 作为module 中 getters 中默认参数, actions中context 对象,也会多了两个属性,context.getters, context. rootState, 这些全局的默认参数,都排在局部参数的后面。

我们在store.js中添加 state, getters:

export default new Vuex.Store({

// 通过modules属性引入login 模块。

modules: {

login: login

},

// 新增state, getters

state: {

job: "web"

},

getters: {

jobTitle (state){

return state.job + "developer"

}

}

})

login 目录下的 index.js

const actions = {

// actions 中的context参数对象多了 rootState 参数

changeName ({commit, rootState},anotherName) {

if(rootState.job =="web") {

commit("change_name", anotherName)

}

}

};

const getters = {

// getters 获取到 rootState, rootGetters 作为参数。

// rootState和 rootGetter参数顺序不要写反,一定是state在前,getter在后面,这是vuex的默认参数传递顺序, 可以打印出来看一下。

localJobTitle (state,getters,rootState,rootGetters) {

console.log(rootState);

console.log(rootGetters);

return rootGetters.jobTitle + " aka " + rootState.job

}

};

app.vue 增加h2 展示 loacaJobTitle, 这个同时证明了getters 也是被注册到全局中的。

logo.png

{{useName}}

{{localJobTitle}}

change to json

import {mapActions, mapState,mapGetters} from "vuex";

export default {

// computed属性,从store 中获取状态state,不要忘记login命名空间。

computed: {

...mapState({

useName: state => state.login.useName

}),

// mapGeter 直接获得全局注册的getters

...mapGetters(["localJobTitle"])

},

methods: {

changeName() {

this.$store.dispatch("changeName", "Jason")

}

}

}

7, 其实actions, mutations, getters, 也可以限定在当前模块的命名空间中。只要给我们的模块加一个namespaced 属性:

const state = {

useName: "sam"

};

const mutations = {

change_name (state, anotherName) {

state.useName = anotherName;

}

};

const actions = {

changeName ({commit, rootState},anotherName) {

if(rootState.job =="web") {

commit("change_name", anotherName)

}

},

alertName({state}) {

alert(state.useName)

}

};

const getters = {

localJobTitle (state,getters,rootState,rootGetters) {

return rootGetters.jobTitle + " aka " + rootState.job

}

};

// namespaced 属性,限定命名空间

export default {

namespaced:true,

state,

mutations,

actions,

getters

}

当所有的actions, mutations, getters 都被限定到模块的命名空间下,我们dispatch actions, commit mutations 都需要用到命名空间。如 dispacth("changeName"), 就要变成 dispatch("login/changeName"); getters.localJobTitle 就要变成 getters["login/localJobTitle"]

app.vue 如下:

logo.png

{{useName}}

{{localJobTitle}}

change to json

import {mapActions, mapState,mapGetters} from "vuex";

export default {

// computed属性,从store 中获取状态state,不要忘记login命名空间。

computed: {

...mapState("login",{

useName: state => state.useName

}),

localJobTitle() {

return this.$store.getters["login/localJobTitle"]

}

},

methods: {

changeName() {

this.$store.dispatch("login/changeName", "Jason")

},

alertName() {

this.$store.dispatch("login/alertName")

}

}

}

有了命名空间之后,mapState, mapGetters, mapActions 函数也都有了一个参数,用于限定命名空间,每二个参数对象或数组中的属性,都映射到了当前命名空间中。

import {mapActions, mapState,mapGetters} from "vuex";

export default {

computed: {

// 对象中的state 和数组中的localJobTitle 都是和login中的参数一一对应。

...mapState("login",{

useName: state => state.useName

}),

...mapGetters("login", ["localJobTitle"])

},

methods: {

changeName() {

this.$store.dispatch("login/changeName", "Jason")

},

...mapActions('login', ['alertName'])

}

}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值