简述vue状态管理模式之vuex

2023-01-24 0 583

介绍vuex核心理念基本概念请点选

https://vuex.vuejs.org/zh/

一、如上所述vuex

1.1 vuex是甚么

所以先来看看这两个问题:

甚么是vuex?非官方网站说:Vuex 是两个专为 Vue.js

甚么情况下用到vuex?非官方网站说:假如您不急于合作开发小型白眉林应用领域,采用 Vuex 可能是繁杂输入输出的。的确是如此——假如您的应用领域够单纯,您最合适不要采用 Vuex。两个单纯的 global event bus 就足够多您所需了。但是,假如您须要构筑是两个中小型白眉林应用领域,您很可能会考虑如何更快地在模块内部管理工作状况,Vuex Sonbhadra成为顺理成章的优先选择。

好,所以那时我就当你是合作开发两个比较小型的工程项目,那些地方会加进vuex呢? 随着应用领域的维数增加,模块之间SRAM或模块的状况会愈来愈多,举个范例:当A模块步入B模块(A网页步入B网页)的这时,经常须要带许多模块往后,所以这时你可能会优先选择放到url前面当作模块传递往后,假如你不该轻而易举曝露模块,你有可能暂放到session中或是localstorage中,接着步入到第三个网页的这时再抽出来。极好,这的确是一种解决方式,而且用的不少。但这并非两个好的方式,这这时,你就须要vuex来协助你了。另外,当你基本介绍vuex的许多毛皮之后,你会发现vuex管理工作是如前所述模组化的思想,所以这就对工程项目中后期管理工作保护很亲善了。

so,那时你就狂蛛属深入细致哥们vuex的核心理念基本概念了。上面是个人理解的基本概念,首先在此之后建议最合适先把非官方文件格式Vuex2.0基本概念过两遍。

vuex 就是把须要共享资源的表达式全部储存在两个第一类里头,接着将这个第一类放到第二层模块中供其他模块采用

兄弟二人模块通讯时,我们通常会采用 props + emit 这种方式。但当通讯两方并非兄弟二人模块甚至压根儿不存在相关联络,或是两个状况须要共享资源给数个模块时,就会非常麻烦事,数据也会十分难保护

1.2 vuex中有甚么

const store = new Vuex.Store({ state: { name: weish, age: 22 }, getters: { personInfo(state) { return `My name is ${state.name}, I am ${state.age}`; } } mutations: { SET_AGE(state, age) { commit(age, age); } }, actions: { nameAsyn({commit}) { setTimeout(() => { commit(SET_AGE, 18); }, 1000); } }, modules: { a: modulesA } }

个就是最基本也是完整的 vuex 代码; vuex 包含有五个基本的第一类

state :储存状况。也就是表达式;getters :派生状况。也就是 set 、 get 中的 get ,有computed 差不多;mutations :提交状况修改。也就是 set 、 get 中的 set ,这是 vuex 中唯一修改 state 的方式,但不支持异步操作。第两个模块默认是 state 。内部调用方式: store.commit(SET_AGE, 18) 。和 vue 中的 methods 类似。actions :和 mutations 类似。不过 actions 支持异步操作。第两个模块默认是和 store 具有相同模块属性的第一类。内部调用方式: store.dispatch(nameAsyn) 。modules : store 的子模块,内容就十分于是 store 的两个实例。调用方式和前面介绍的相似,只是要加上当前子模块名,如: store.a.getters.xxx()

1.3 vue-cli中采用vuex的方式

目录结构

├── index.html ├── main.js ├── components └── store ├── index.js # 我们组装模块并导出 store 的地方 ├── state.js # 跟级别的 state ├── getters.js # 跟级别的 getter ├── mutation-types.js # 根级别的mutations名称(非官方推荐mutions方式名采用大写) ├── mutations.js # 根级别的 mutation ├── actions.js # 根级别的 action └── modules ├── m1.js # 模块1 └── m2.js # 模块2

state示例

const state = { name: weish, age: 22 }; export default state;

getter示例

getters.js 示

export const name = (state) => { return state.name; } export const age = (state) => { return state.age } export const other = (state) => { return `My name is ${state.name}, I am ${state.age}.`; }

mutation-type示例

将所有 mutations 的函数名放到这个文件里

export const SET_NAME = SET_NAME; export const SET_AGE = SET_AGE;

mutations示例

import * as types from ./mutation-type.js; export default { [types.SET_NAME](state, name) { state.name = name; }, [types.SET_AGE](state, age) { state.age = age; } };

actions示例

异步操作、数个 commit 时

import * as types from ./mutation-type.js; export default { nameAsyn({commit}, {age, name}) { commit(types.SET_NAME, name); commit(types.SET_AGE, age); } }

modules–m1.js示例

假如并非很复杂的应用领域,一般来讲是不会分模块的

export default { state: {}, getters: {}, mutations: {}, actions: {} }

index.js示例(组装vuex)

import vue from vue; import vuex from vuex; import state from ./state.js; import * as getters from ./getters.js; import mutations from ./mutations.js; import actions from ./actions.js; import m1 from ./modules/m1.js; import m2 from ./modules/m2.js; import createLogger from vuex/dist/logger; // 修改日志 vue.use(vuex); const debug = process.env.NODE_ENV !== production; // 合作开发环境中为true,否则为false export default new vuex.Store({ state, getters, mutations, actions, modules: { m1, m2 }, plugins: debug ? [createLogger()] : [] // 合作开发环境下显示vuex的状况修改 });

最后将 store 实例挂载到 main.js 里头的 vue 上去就行了

import store from ./store/index.js; new Vue({ el: #app, store, render: h => h(App) });

在 vue 模块中采用时,我们通常会采用 mapGetters 、 mapActions 、 mapMutations ,接着就可以按照 vue 调用 methods 和 computed 的方式去调用这些表达式或函数,示例如

import {mapGetters, mapMutations, mapActions} from vuex; /* 只写模块中的script部分 */ export default { computed: { …mapGetters([ name, age ]) }, methods: { …mapMutations({ setName: SET_NAME, setAge: SET_AGE }), …mapActions([ nameAsyn ]) } };

二、modules

在 src 目录下 , 新建两个 store 文件夹 , 接着在里头新建两个 index.js

import Vue from vue import vuex from vuex Vue.use(vuex); export default new vuex.Store({ state:{ show:false } })

在 main.js 里的代码应该改成,在实例化 Vue 第一类时加入 store 第一类

//vuex import store from ./store new Vue({ el: #app, router, store,//采用store template: <App/>, components: { App } })

这样就把 store 分离出去了 , 所以还有两个问题是 : 这里 $store.state.show 无论哪个模块都可以采用 , 那模块多了之后 , 状况也多了 , 这么多状况都堆在 store 文件夹下的 index.js 不好保护怎么办 ?

我们可以采用 vuex 的 modules , 把 store 文件夹下的 index.js 改成

import Vue from vue import vuex from vuex Vue.use(vuex); import dialog_store from ../components/dialog_store.js;//引入某个store第一类 export default new vuex.Store({ modules: { dialog: dialog_store } })

这里我们引用了两个 dialog_store.js , 在这个 js 文件里我们就可以单独写 dialog 模块的状况了

export default { state:{ show:false } }

做出这样的修改之后 , 我们将之前我们采用的$store.state.show 统统改为 $store.state.dialog.show即可

假如还有其他的模块须要采用 vuex , 就新建两个对应的状况文件 , 接着将他们加入 store 文件夹下的 index.js 文件中的 modules 中

modules: { dialog: dialog_store, other: other,//其他模块 }

三、mutations

对 vuex 的依赖仅仅只有两个 $store.state.dialog.show 两个状况 , 但是假如我们要进行两个操作 , 须要依赖很多很数个状况 , 那管理工作起来又麻烦事了

mutations 里的操作必须是同步的

export default { state:{//state show:false }, mutations:{ switch_dialog(state){//这里的state对应着上面这个state state.show = state.show?false:true; //你还可以在这里执行其他的操作改变state } } }

采用 mutations 后 , 原先我们的父模块可以改为

<template> <div id=”app”> <a href=”javascript:;” rel=”external nofollow” rel=”external nofollow” @click=”$store.commit(switch_dialog)”>点击</a> <t-dialog></t-dialog> </div> </template> <script> import dialog from ./components/dialog.vue export default { components:{ “t-dialog”:dialog } } </script>

采用 $store.commit(switch_dialog) 来触发 mutations 中的 switch_dialog 方式

四、actions

数个 state 的操作 , 采用 mutations 会来触发会比较好保护 , 所以须要执行数个 mutations 就须要用 action 了

export default { state:{//state show:false }, mutations:{ switch_dialog(state){//这里的state对应着上面这个state state.show = state.show?false:true; //你还可以在这里执行其他的操作改变state } }, actions:{ switch_dialog(context){//这里的context和我们采用的$store拥有相同的第一类和方式 context.commit(switch_dialog); //你还可以在这里触发其他的mutations方式 }, } }

所以 , 在之前的父模块中 , 我们须要做修改 , 来触发 action 里的 switch_dialog 方式

<template> <div id=”app”> <a href=”javascript:;” rel=”external nofollow” rel=”external nofollow” @click=”$store.dispatch(switch_dialog)”>点击</a> <t-dialog></t-dialog> </div> </template> <script> import dialog from ./components/dialog.vue export default { components:{ “t-dialog”:dialog } } </script>

采用 $store.dispatch(switch_dialog) 来触发 action 中的 switch_dialog 方式。

非官方推荐 , 将异步操作放到 action 中

五、getters

getters 和 vue 中的 computed 类似 , 都是用来计算 state 接着生成新的数据 ( 状况 ) 的

假如我们须要两个与状况 show 刚好相反的状况 , 采用 vue 中的 computed 可以这样算出来

computed(){ not_show(){ return !this.$store.state.dialog.show; } }

所以 , 假如很多很数个模块中都须要加进这个与 show 刚好相反的状况 , 所以我们须要写很多很数个 not_show , 采用 getters 就可以解决这种问题

export default { state:{//state show:false }, getters:{ not_show(state){//这里的state对应着上面这个state return !state.show; } }, mutations:{ switch_dialog(state){//这里的state对应着上面这个state state.show = state.show?false:true; //你还可以在这里执行其他的操作改变state } }, actions:{ switch_dialog(context){//这里的context和我们采用的$store拥有相同的第一类和方式 context.commit(switch_dialog); //你还可以在这里触发其他的mutations方式 }, } }

我们在模块中采用 $store.state.dialog.show来获得状况 show , 类似的 , 我们可以采用 $store.getters.not_show来获得状况 not_show

注意 : $store.getters.not_show 的值是不能直接修改的 , 须要对应的 state 发生变化才能修改

六、mapState、mapGetters、mapActions

很多这时 , $store.state.dialog.show、$store.dispatch(switch_dialog) 这种写法很不方便

采用 mapState 、 mapGetters 、 mapActions 就不会这么复杂了

<template> <el-dialog :visible.sync=”show”></el-dialog> </template> <script> import {mapState} from vuex; export default { computed:{ //这里的三点叫做 : 扩展运算符 …mapState({ show:state=>state.dialog.show }), } } </script>

十分于

<template> <el-dialog :visible.sync=”show”></el-dialog> </template> <script> import {mapState} from vuex; export default { computed:{ show(){ return this.$store.state.dialog.show; } } } </script>

mapGetters 、 mapActions 和 mapState 类似 , mapGetters 一般也写在 computed 中 , mapActions 一般写在 methods 中

知识体系

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务