当前位置: 首页 > news >正文

记录前端vue3封装一个modal弹框

一、基本步骤

  • 1、最终运行效果
    在这里插入图片描述

  • 2、具体代码实现

    <template><Teleport to="body"><Transition name="modal-fade"><div class="modal" ref="modalRef" v-show="visible" tabindex="-1" @keyup.esc="onEsc()"><div class="mask" @click="onClickMask()"></div><Transition name="modal-zoom" @afterLeave="contentVisible = false" @before-enter="contentVisible = true"><div class="modal-content" v-show="visible" :style="contentStyle"><div class="modal-header"><template v-if="isHeader"><slot name="title"></slot></template><template v-else>{{ title }}</template><span class="close-btn" v-if="closeButton" @click="close()">x</span></div><div class="modal-body"><slot v-if="contentVisible"></slot></div><div class="modal-footer" v-if="isFooter"><slot name="footer"></slot></div></div></Transition></div></Transition></Teleport>
    </template><script lang="js" setup>
    import { computed, defineProps, nextTick, ref, watch ,useSlots} from 'vue';const isHeader = !!useSlots().title;
    const isFooter = !!useSlots().footer;
    const props = defineProps({title: {type: String,default: '',},visible: {type: Boolean,required: true,},width: {type: Number,default: 480,},closeButton: {type: Boolean,default: true,},closeOnClickMask: {type: Boolean,default: true,},closeOnEsc: {type: Boolean,default: true,},contentStyle: {type: Object,default: () => ({}),},
    });const modalRef = ref();const emit = defineEmits(['update:visible', 'closed']);const contentVisible = ref(false);const contentStyle = computed(() => {return {width: props.width + 'px',...(props.contentStyle || {}),};
    });watch(() => props.visible,() => {if (props.visible) {nextTick(() => modalRef.value.focus());}}
    );const close = () => {emit('update:visible', false);emit('closed');
    };const onEsc = () => {if (props.visible && props.closeOnEsc) close();
    };const onClickMask = () => {if (props.closeOnClickMask) close();
    };
    </script><style lang="scss" scoped>
    .modal,
    .mask {top: 0;left: 0;width: 100%;height: 100%;z-index: 5000;
    }.modal {position: fixed;display: flex;justify-content: center;align-items: center;outline: 0;border: 0;
    }.mask {position: absolute;background: rgba(0, 0, 0, 0.25);
    }.modal-content {z-index: 5001;background: #fff;border-radius: 2px;overflow: hidden;box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);.modal-header {width: 100%;height: 48px;padding: 0 20px;box-sizing: border-box;font-size: 16px;font-weight: 500;color: #1d2129;line-height: 48px;border-bottom: 1px solid #e5e6eb;position: relative;display: flex;flex-direction: row;align-items: center;.close-btn {width: 20px;height: 20px;display: flex;justify-content: center;align-items: center;position: absolute;top: 16px;right: 16px;cursor: pointer;}}.modal-body {padding: 20px;box-sizing: border-box;}.modal-footer {border-top: 1px solid #e5e6eb;padding: 16px 20px;display: flex;flex-direction: row;justify-content: flex-end;align-items: center;}
    }.modal-fade-enter-active {animation: modal-fade-enter 0.25s both ease-in;
    }
    .modal-fade-leave-active {animation: modal-fade-leave 0.25s both ease-out;
    }
    .modal-zoom-enter-active {animation: modal-zoom-enter 0.25s both cubic-bezier(0.4, 0, 0, 1.5);
    }
    .modal-zoom-leave-active {animation: modal-zoom-leave 0.25s both;
    }@keyframes modal-fade-enter {from {opacity: 0;}
    }
    @keyframes modal-fade-leave {to {opacity: 0;}
    }
    @keyframes modal-zoom-enter {from {transform: scale3d(0.3, 0.3, 0.3);}
    }
    @keyframes modal-zoom-leave {to {transform: scale3d(0.3, 0.3, 0.3);}
    }
    </style>
    
  • 3、使用组件的时候

<Modal title="导出" :visible="!!dialogForExport" @closed="closeExportDialog()"><template #title>你好</template><h1>你好</h1><template #footer><button @click="dialogForExport = false">关闭</button></template></Modal>

相关文章:

  • swagger快速入门
  • css word
  • 微信小程序 - 获取当前地址经纬度
  • 解释PyTorch中的广播机制
  • 使用命令关闭Redis服务端
  • 微信小程序核心技术栈
  • 【前后端分离项目】Vue+Springboot+MySQL
  • k8s中资源的介绍及标准资源namespaces实践
  • P1036-法1.dfs组合 法2.combinations( )
  • springboot入门-service层构造器注入原理
  • 数据库设置外键的作用
  • CMCC RAX3000M CH EC 算力版刷机(中国移动 RAX3000M 算力版)刷机
  • 汉诺塔用python编写
  • leetcode刷题日记——基本计算器
  • QML Date:日期处理示例
  • MIL、SIL、HIL与Back-to-Back测试详解:从模型到硬件的完整验证链
  • python怎么查看函数原型及变量是什么类型
  • [SystemVerilog] Clocking
  • 2软考系统架构设计师:第一章系统架构概述 - 练习题附答案及超详细解析
  • 基于libdxfrw库读取样条曲线并离散为点
  • “冲刺万亿城市”首季表现如何?温州领跑,大连GDP超徐州
  • 甘肃张掖至重庆航线开通,串起西北与西南文旅“黄金走廊”
  • 建投读书会·东西汇流|全球物品:跨文化交流视域下的明清外销瓷
  • 人民日报任仲平:为什么中国意味着确定性、未来性、机遇性
  • 交警不在就闯红灯?上海公安用科技手段查处非机动车违法
  • 谭秀洪任广西梧州市人大常委会党组书记,此前任北海市委常委