Vuex 模块化与项目实例 (2.0)

摘要:
Vuex强调使用单一状态树,即项目中只有一个存储。该存储集中管理项目中的所有数据和数据的操作。请参考上述Vuex核心知识(2.0)状态。在Vuex模块化中,state是唯一一个在组合时根据模块别名添加级别的模块。getter、mutation和action直接合并到存储中。constmoduleA={state:{maState:‘A‘}};constmoduleB={state:{mbState:'B'}};常量存储=newVuex。百货商店安慰日志;//Aconsole公司。日志;//B控制台。日志;//RootGetters和state的区别在于,不同模块的getter将直接合并到store下。getters constmoduleA={状态:{计数:1},getters:{maGetter{returnstate.count+rootState.b.count;}}}};constmoduleB={state:{count:2},getters:{mbGetter(){return‘HelloVuex‘;}};conststore={模块:{a:moduleA,b:moduleB}};安慰日志;//3控制台。日志;//HelloVuex介绍了上面getters回调函数接收的前两个参数。模块化之后,需要使用第三个参数rootState。突变与吸气相似。不同模块的突变可以通过存储直接触发。犯罪

Vuex 强调使用单一状态树,即在一个项目里只有一个 store,这个 store 集中管理了项目中所有的数据以及对数据的操作行为。但是这样带来的问题是 store 可能会非常臃肿庞大不易维护,所以就需要对状态树进行模块化的拆分。

首先贴出一个逻辑比较复杂的H5项目:DEMO & 源码

该项目主要包括 banner、feeds、profile 三个部分。其中 feeds 模块最复杂,需要对数据列表进行处理,如果单条数据中是图片:1张按照屏幕宽展示;2张各占50%;3张以上采用九宫格形式展示;如果单条数据是视频,则显示播放按钮,播放一条视频时,其他视频暂停。

由于该项目数据、交互较多,我们使用 Vuex 对数据进行托管,只在 Vue 组件中保留最基本的操作。

如果不使用 Vuex,许多数据流需要通过 props 的方便向下传递,十分不便,尤其是一些跨组件的操作更加困难。使用 Vuex 后就可以将数据与操作保留在 store 中,每个组件都能轻松调用。

本项目中除了根 store 以外,还通过 module 将各组件的 store 分开管理,还不了解的同学可以往下看。

Module

首先介绍下基本的组件化规则:你可以根据项目组件的划分来拆分 store,每个模块里管理着当前组件的状态以及行为,最后将这些模块在根 store 进行组合。

复制代码
const moduleA = {
    state: { ... },
    getters: { ... }
    mutations: { ... }
};

const moduleB = {
    state: { ... },
    getters: { ... },
    mutations: { ... },
    actions: { ... }
};

const store = new Vuex.Store({
    modules: {
        a: moduleA,
        b: moduleB
    }
});

console.log(store.state.a); // moduleA 的 state
复制代码

接下来看 Vuex 核心在模块化后的使用注意事项。

请参考上文 Vuex 核心知识 (2.0)

State

在 Vuex 模块化中,state 是唯一会根据组合时模块的别名来添加层级的,后面的 getters、mutations 以及 actions 都是直接合并在 store 下。

例如,访问模块 a 中的 state,要通过 store.state.a,访问根 store 上申明的 state,依然是通过 store.state.xxx 直接访问。

复制代码
const moduleA = {
    state: {
        maState: 'A'
    }
};

const moduleB = {
    state: {
        mbState: 'B'
    }
};

const store = new Vuex.Store({
    modules: {
        a: moduleA,
        b: moduleB
    },
    state: {
        rtState: 'Root'
    }
});

console.log(store.state.a.maState); // A
console.log(store.state.b.mbState); // B
console.log(store.state.rtState); // Root
复制代码

Getters

与 state 不同的是,不同模块的 getters 会直接合并在 store.getters 下

复制代码
const moduleA = {
    state: {
        count: 1
    },
    getters: {
        maGetter(state, getters, rootState) {
            return state.count + rootState.b.count;
        }
    }
};

const moduleB = {
    state: {
        count: 2
    },
    getters: {
        mbGetter() {
            return 'Hello Vuex';
        }
    }
};

const store = {
    modules: {
        a: moduleA,
        b: moduleB
    }
};

console.log(store.getters.maGetter); // 3
console.log(store.getters.mbGetter); // Hello Vuex
复制代码

在上文我们介绍过 getters 的回调函数所接收的前两个参数,模块化后需要用到第三个参数——rootState。参数: 1. state,模块中的 state 仅为模块自身中的 state;2. getters,等同于 store.getters;3. rootState,全局 state。

通过 rootState,模块中的 getters 就可以引用别的模块中的 state 了,十分方便。

注意:由于 getters 不区分模块,所以不同模块中的 getters 如果重名,Vuex 会报出 'duplicate getter key: [重复的getter名]' 错误。

Mutations

mutations 与 getters 类似,不同模块的 mutation 均可以通过 store.commit 直接触发。

复制代码
const moduleA = {
    state: {
        count: 1
    },
    mutations: {
        sayCountA(state) {
            console.log('Module A count: ', state.count);
        }
    }
};

const moduleB = {
    state: {
        count: 2
    },
    mutations: {
        sayCountB(state) {
            console.log('Module B count: ', state.count);
        }
    }
};

const store = {
    modules: {
        a: moduleA,
        b: moduleB
    }
};

store.commit('sayCountA'); // Module A count: 1
store.commit('sayCountB'); // Module B count: 2 
复制代码

mutation 的回调函数中只接收唯一的参数——当前模块的 state。如果不同模块中有同名的 mutation,Vuex 不会报错,通过 store.commit 调用,会依次触发所有同名 mutation。

Actions

与 mutations 类似,不同模块的 actions 均可以通过 store.dispatch 直接触发。

复制代码
const moduleA = {
    state: {
        count: 1
    },
    mutations: {
        sayCountA(state) {
            console.log('Module A count: ', state.count);
        }
    },
    actions: {
        maAction(context) {
            context.dispatch('mbAction');
        }
    }
};

const moduleB = {
    state: {
        count: 2
    },
    mutations: {
        sayCountB(state, num) {
            console.log('Module B count: ', state.count+num);
        }
    },
    action: {
        mbAction({ commit, rootState }) {
            commit('sayCountA');
            commit('sayCountB', rootState.a.count);
        }
    }
};

const store = {
    modules: {
        a: moduleA,
        b: moduleB
    }
};

store.dispatch('maAction'); // Module A count: 1、Module B count: 3
复制代码

从上例可以看出,action 的回调函数接收一个 context 上下文参数,context 包含:1. state、2. rootState、3. getters、4. mutations、5. actions 五个属性,为了简便可以在参数中解构。

在 action 中可以通过 context.commit 跨模块调用 mutation,同时一个模块的 action 也可以调用其他模块的 action。

同样的,当不同模块中有同名 action 时,通过 store.dispatch 调用,会依次触发所有同名 actions。

最后有一点要注意的是,将 store 中的 state 绑定到 Vue 组件中的 computed 计算属性后,对 state 进行更改需要通过 mutation 或者 action,在 Vue 组件中直接进行赋值 (this.myState = 'ABC') 是不会生效的。

感谢你的浏览,希望能有所帮助。

免责声明:文章转载自《Vuex 模块化与项目实例 (2.0)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇利用Nginxcp为cPanel/WHM服务器开启nginx支持Python机器学习(十四)Logistic回归算法原理与代码实现下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

使用 ESlint+stylelint+prettier 对前端项目代码进行规范

使用 ESlint+stylelint+prettier 对前端项目代码进行规范 说明:该规范主要针对的是使用的是 react+typescript+tsx 框架的代码进行相关规范   目录 项目初始化 添加eslint相关配置及规范约束 添加prettiter 项目配置及约束 添加stylelint相关配置及约束 设置git 代码提交检查及eslint...

eldialog添加拖拽功能

import Vue from 'vue' Vue.directive('dialogDrag', { bind(el, binding, vnode, oldVnode) { const dialogHeaderEl = el.querySelector('.el-dialog__header') const dragDom = e...

图片在 canvas 中的 选中/平移/缩放/旋转,包含了所有canvas的2D变化,让你认识到数学的重要性

1、介绍   canvas 已经出来好久了,相信大家多少都有接触。   如果你是前端页面开发/移动开发,那么你肯定会有做过图片上传处理,图片优化,以及图片合成,这些都是可以用 canvas 实现的。   如果你是做前端游戏开发的,可能会非常熟悉,或者说对几何和各种图形变化非常了解。   这里我介绍的是简单的、基本的,但是非常完全的一个 2d 的 canva...

vue 数组去重

test() { const arr =[ { name: '张三', age: 22}, { name: '李四', age: 22}, { name: '张三', age:...

delphi常用函数过程

数据类型转化 1.1.         数值和字符串转化 Procedure Str(X [: Width [ : Decimals ]]; var S); 将数值X按照一定格式转化成字符串S。Width指定S的总长度,Decimals指定小数点后的位数。 EX: Str(12.2 : 6 : 2 , S); //S=’  12.20’; Procedur...

前端上传数据-图片和视频格式校验

上一篇用 promise 嵌套实现了按 excel 行顺序上传数据,这篇要解决的问题是图片和视频格式校验,图片主要有 jpg png gif 视频 mp4 由于用户选择的资源可能并不是真正的多媒体文件,使用 js 的 file.type 方法获取的文件类型可能不准确,比如将 .xlsx 改为 .jpg, file.type 得到的类型是image/jpeg...