vue3弹窗usehook

说明

个人记录保存。

import {ref} from "vue";

export default function useDialog(opts) {

  const visible = ref(false)
  const loading = ref(false)

  const open = (v) => {
    visible.value = true
    typeof opts.onOpen === "function" && opts.onOpen(v)
  }

  const close = () => {
    visible.value = false
    typeof opts.onClose === "function" && opts.onClose()

  }

  return {
    visible,
    open,
    close,
    loading,
  }
}
<think>好的,我现在需要回答用户关于Vue3弹窗实现的问题。用户之前已经询问过循环生成表格,现在转向弹窗组件,可能是在构建一个完整应用时需要常见的UI功能。首先,我需要确定Vue3弹窗的常见实现方式,通常包括组件化、状态管理和动画效果。首先,弹窗一般作为独立组件存在,使用props接收显示状态和内容,通过emit事件关闭。我应该展示如何创建可复用的Modal组件,并利用Vue3的Composition API。用户可能需要代码示例,所以需要包含模板、脚本和样式的完整代码。接下来,需要考虑弹窗的动画效果,使用Vue的transition组件实现淡入淡出。同时,点击遮罩层关闭弹窗是一个常见需求,需要阻止事件冒泡。此外,插槽(slot)的使用可以让内容更灵活,比如头部、主体和底部按钮区域。 然后,要演示如何在父组件中引入并使用这个Modal组件,控制其显示和隐藏。需要展示使用v-model绑定isOpen状态,以及如何在父组件中触发弹窗的打开和关闭。可能还需要考虑无障碍访问(ARIA属性),但用户没有特别提到,所以可能暂时忽略。样式方面,固定定位、遮罩层和居中弹窗是关键点,需要确保CSS正确实现这些效果。最后,用户的相关问题可能涉及动态内容、全局状态管理、拖拽功能或表单集成。需要提前准备这些扩展点,确保相关问题有逻辑性,覆盖常见开发需求。现在,整理代码结构,确保示例清晰,注释明确。检查代码是否正确,比如transition的name属性是否与CSS类对应,emit事件是否正确触发。同时,验证父子组件的通信方式是否符合Vue3的最佳实践,比如使用defineProps和defineEmits。 完成回答后,提出相关问题,引导用户深入探索弹窗组件的其他功能,如与Vuex/Pinia的集成、动画优化、传参方式等,确保覆盖可能的后续问题。</think>在Vue3中实现弹窗功能可以通过组件化方式实现。以下是基础弹窗组件的实现方案: ```vue <!-- Modal.vue --> <template> <transition name="fade"> <div v-if="isOpen" class="modal-mask" @click.self="close"> <div class="modal-container"> <div class="modal-header"> <slot name="header"> <h3>{{ title }}</h3> <button class="close-btn" @click="close">×</button> </slot> </div> <div class="modal-body"> <slot></slot> </div> <div class="modal-footer"> <slot name="footer"> <button @click="close">关闭</button> </slot> </div> </div> </div> </transition> </template> <script setup> const props = defineProps({ isOpen: Boolean, title: { type: String, default: &#39;提示&#39; } }) const emit = defineEmits([&#39;update:isOpen&#39;]) const close = () => { emit(&#39;update:isOpen&#39;, false) } </script> <style scoped> .fade-enter-active, .fade-leave-active { transition: opacity 0.3s; } .fade-enter-from, .fade-leave-to { opacity: 0; } .modal-mask { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.5); display: grid; place-items: center; } .modal-container { background: white; padding: 20px; border-radius: 8px; min-width: 300px; max-width: 80vw; } .modal-header { display: flex; justify-content: space-between; align-items: center; border-bottom: 1px solid #eee; padding-bottom: 10px; margin-bottom: 15px; } .close-btn { background: none; border: none; font-size: 24px; cursor: pointer; padding: 0 8px; } .modal-footer { margin-top: 15px; padding-top: 10px; border-top: 1px solid #eee; text-align: right; } </style> ``` **使用示例:** ```vue <!-- ParentComponent.vue --> <template> <button @click="showModal = true">打开弹窗</button> <Modal v-model:isOpen="showModal" title="自定义标题"> <template #default> <p>这是弹窗内容</p> </template> <template #footer> <button @click="showModal = false">取消</button> <button @click="confirm">确认</button> </template> </Modal> </template> <script setup> import { ref } from &#39;vue&#39; import Modal from &#39;./Modal.vue&#39; const showModal = ref(false) const confirm = () => { console.log(&#39;确认操作&#39;) showModal.value = false } </script> ``` **实现原理:** 1. 使用`v-model`双向绑定控制弹窗显示状态 2. 通过`<slot>`插槽实现内容定制化 3. 添加过渡动画提升用户体验 4. 点击遮罩层自动关闭功能(`.self`修饰符) 5. 组件化设计提高复用性
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值