现实中的许多Web应用都有许多弹框,或者交互事件的开发需求。博主曾开发过较大型的Vue Web
应用,光控制这些弹框的显示隐藏都感受恶心:初始化isDialogShow=false
,点击按钮isDialogShow=true
,弹框显示后点击确认、取消和关闭按钮须要广播事件或者经过$parent将父组件的isDialogShow
置为false
。还有就是跨组件的事件广播也让人头大。如若弹框比较多或者跨组件事件较多,采用生硬的控制显得很不优雅。javascript
福音来了,如若你的Vue
应用已经自带vuex
或者应用交互过多须要引入vuex
,那么下面的方案将是个不错的解决方案。先说一下用vuex
统一管理弹框和事件优势:统一控制,一目了然、控制简单。其相关概念可查看vuex,这里就不赘述了。vue
state: {
// 弹框信息显示控制标识统必定义于此,统一管理
BooleanFlag: {
//小驼峰:is 名词 动词
isDemoDialogShow: false, // demo 弹框显示
},
// 事件直通车, 相关事件能够统一管理
EventBus: {
Page1ToPage2: {}, // 采用对象是为了传递数据
}
}
复制代码
mutations: {
// 自动取反
BooleanFlag(state, flagKeys) {
if (!Array.isArray(flagKeys)) return
const BooleanFlag = state.BooleanFlag
flagKeys.forEach(flagKey => BooleanFlag[flagKey] = !BooleanFlag[flagKey])
},
// EventBus
EventBus(state, eventWithData={}) {
const EventBus = state.EventBus
Object.keys(eventWithData).forEach(eventKey=>{
if(EventBus[eventKey] !== undefined){
EventBus[eventKey] = eventWithData[eventKey]
}
})
}
}
复制代码
<template>
<div>
<div class="button-bar">
<el-button @click="onDialogShow" type="primary">打开弹框</el-button>
<el-button @click="onEmitData" type="primary">广播数据</el-button>
</div>
<div>
<demo-dialog v-if="BooleanFlag.isDemoDialogShow"></demo-dialog>
</div>
</div>
</template>
<script>
import { mapState } from "vuex";
import DemoDialog from "@/dialogs/DemoDialog";
export default {
components: {
DemoDialog
},
computed: mapState(["BooleanFlag"]),
methods: {
// 弹框Demo
onDialogShow() {
this.$store.commit("BooleanFlag", ["isDemoDialogShow"]);
},
// 广播事件
onEmitData() {
const messageObj = {
message: "from page1"
};
this.$store.commit("EventBus", {
Page1ToPage2: messageObj
});
}
}
};
复制代码
<template>
<div>
<el-dialog :title="title" :visible.sync="isShow" :width="width" custom-class="ht-dialog" :before-close="onCancle">
<div class="dialog-container">
弹框内容
</div>
<div class="bottom-buttons">
<el-button @click="onCancle">{{$t('Common.cancel')}}</el-button>
<el-button type="primary" @click="onSure">{{$t('Common.sure')}}</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
export default {
name: "DemoDialog",
data() {
return {
title: "弹框标题",
width: "500px",
isShow: true
};
},
methods: {
onSure() {
// 业务代码
this.onCancle()
},
onCancle() { // 关闭弹框
this.$store.commit("BooleanFlag", ["isDemoDialogShow"]);
}
}
};
</script>
复制代码
注意这里要配合 来使用,采用监听数据变化的方式来响应事件。java
<template>
<div>
page2下的内容
</div>
</template>
<script>
import { mapState } from "vuex";
export default {
computed: mapState(["EventBus"]),
watch: {
"EventBus.Page1ToPage2": function(message) {
console.log("Page1ToPage2", message);
}
}
};
</script>
复制代码