<aside> 📖 toc

</aside>

一个Hook让你体验极致舒适的Dialog使用方式!

https://github.com/JessYan0913/vue-aide

Dialog 地狱

为啥是地狱?

因为凡是有Dialog出现的页面,其代码绝对优雅不起来!因为一旦你在也个组件中引入Dialog,就最少需要额外维护一个visible变量。如果只是额外维护一个变量这也不是不能接受,可是当同样的Dialog组件,即需要在父组件控制它的展示与隐藏,又需要在子组件中控制。

为了演示我们先实现一个MyDialog组件,代码来自 ElementPlus 的 Dialog 示例

<script setup lang="ts"> import { computed } from 'vue';
import { ElDialog } from 'element-plus';

const props = defineProps<{
  visible: boolean;
  title?: string;
}>();

const emits = defineEmits<{
  (event: 'update:visible', visible: boolean): void;
  (event: 'close'): void;
}>();

const dialogVisible = computed<boolean>({
  get() {
    return props.visible;
  },
  set(visible) {
    emits('update:visible', visible);
    if (!visible) {
      emits('close');
    }
  },
}); 
</script>

<template>
  <ElDialog v-model="dialogVisible" :title="title" width="30%">
    <span>This is a message</span>
    <template #footer>
      <span>
        <el-button @click="dialogVisible = false">Cancel</el-button>
        <el-button type="primary" @click="dialogVisible = false"> Confirm </el-button>
      </span>
    </template>
  </ElDialog>
</template>

演示场景

就像下面这样:

示例代码如下:

<script setup lang="ts"> import { ref } from 'vue';
import { ElButton } from 'element-plus';

import Comp from './components/Comp.vue';
import MyDialog from './components/MyDialog.vue';

const dialogVisible = ref<boolean>(false);
const dialogTitle = ref<string>('');

const handleOpenDialog = () => {
  dialogVisible.value = true;
  dialogTitle.value = '父组件弹窗';
};

const handleComp1Dialog = () => {
  dialogVisible.value = true;
  dialogTitle.value = '子组件1弹窗';
};

const handleComp2Dialog = () => {
  dialogVisible.value = true;
  dialogTitle.value = '子组件2弹窗';
}; 
</script>

<template>
  <div>
    <ElButton @click="handleOpenDialog"> 打开弹窗 </ElButton>
    <Comp text="子组件1" @submit="handleComp1Dialog"></Comp>
    <Comp text="子组件2" @submit="handleComp2Dialog"></Comp>
    <MyDialog v-model:visible="dialogVisible" :title="dialogTitle"></MyDialog>
  </div>
</template>

这里的MyDialog会被父组件和两个Comp组件都会触发,如果父组件并不关心子组件的onSubmit事件,那么这里的submit在父组件里唯一的作用就是处理Dialog的展示!!!🧐这样真的好吗?不好!

来分析一下,到底哪里不好!

MyDialog本来是submit动作的后续动作,所以理论上应该将MyDialog写在Comp组件中。但是这里为了管理方便,将MyDialog挂在父组件上,子组件通过事件来控制MyDialog

再者,这里的handleComp1DialoghandleComp2Dialog函数除了处理MyDialog外,对于父组件完全没有意义却写在父组件里。

如果这里的Dialog多的情况下,简直就是Dialog地狱啊!🤯

理想的父组件代码应该是这样: