Skip to content

Dialog 弹窗

基本用法

基于 Element Plus 的 Dialog 组件增强,支持全屏、拖拽、滚动条等功能。

功能特性

  • ✨ 使用 Element Plus 自带的 fullscreen 属性
  • 🎯 支持键盘快捷键(ESC关闭、F11全屏)
  • 📱 响应式布局适配
  • 🎨 自定义主题样式
  • 📏 灵活的尺寸控制
  • 🔒 锁定页面滚动
  • 🎭 优雅的动画效果

全屏功能

弹窗组件使用 Element Plus 自带的 fullscreen 属性实现全屏功能:

vue
<template>
  <im-dialog 
    v-model="visible" 
    title="全屏弹窗"
    :fullscreen="true"
  >
    <!-- 弹窗内容 -->
  </im-dialog>
</template>

全屏控制方法

javascript
// 获取弹窗组件引用
const dialogRef = ref()

// 切换全屏状态
dialogRef.value.toggleFullscreen()

// 获取当前全屏状态
console.log(dialogRef.value.isFullscreen.value)

全屏样式特点

  • 使用 position: fixed100vw/100vh 实现真正的全屏
  • 自动调整内边距和布局以适应全屏显示
  • 保持滚动条功能在全屏模式下的正常工作
  • 响应式设计确保在不同设备上的最佳体验

键盘快捷键

  • F11: 切换全屏状态
  • ESC: 关闭弹窗
  • 双击标题: 切换全屏状态

API

Props

参数说明类型可选值默认值
modelValue是否显示弹窗booleanfalse
title弹窗标题string提示
width弹窗宽度string/number50%
fullscreen是否全屏显示booleanfalse
enableScrollbar是否启用滚动条booleanfalse
showFooter是否显示底部区域booleantrue
showCancelButton是否显示取消按钮booleantrue
showConfirmButton是否显示确认按钮booleantrue

Events

事件名说明回调参数
open弹窗打开时触发
opened弹窗打开动画结束时触发
close弹窗关闭时触发
closed弹窗关闭动画结束时触发
confirm点击确认按钮时触发
cancel点击取消按钮时触发
fullscreen-change全屏状态改变时触发isFullscreen

Methods

方法名说明参数
toggleFullscreen切换全屏状态

Slots

插槽名说明
default弹窗主体内容
footer自定义底部内容

组件特性

🎯 完全继承

继承 Element Plus Dialog 的所有功能

🖱️ 拖拽功能

支持拖拽移动和边界限制

📱 全屏模式

一键全屏显示,提升用户体验

🎨 滚动优化

内容滚动条优化和位置记忆

基础用法

基础的对话框用法,支持 Element Plus Dialog 的所有属性。

查看代码
vue
<template>
  <div>
    <ImButton @click="basicVisible = true">基础对话框</ImButton>
    
    <ImDialog 
      v-model="basicVisible" 
      title="基础对话框"
      width="500px"
    >
      <p>这是一个基础的对话框内容。</p>
      <p>支持 Element Plus Dialog 的所有功能。</p>
      
      <template #footer>
        <span class="dialog-footer">
          <ImButton @click="basicVisible = false">取消</ImButton>
          <ImButton type="primary" @click="basicVisible = false">确定</ImButton>
        </span>
      </template>
    </ImDialog>
  </div>
</template>

<script setup>
import { ref } from 'vue'

const basicVisible = ref(false)
</script>

拖拽对话框

启用拖拽功能,可以拖动对话框移动位置。

查看代码
vue
<template>
  <div>
    <ImButton @click="draggableVisible = true">可拖拽对话框</ImButton>
    
    <ImDialog 
      v-model="draggableVisible" 
      title="可拖拽对话框"
      width="600px"
      draggable
    >
      <div class="space-y-4">
        <p>这个对话框可以拖拽移动。</p>
        <p>拖拽功能特点:</p>
        <ul class="list-disc list-inside space-y-1 text-sm text-gray-600">
          <li>点击标题栏拖拽移动</li>
          <li>自动边界限制</li>
          <li>流畅的拖拽体验</li>
          <li>释放后位置保持</li>
        </ul>
      </div>
      
      <template #footer>
        <span class="dialog-footer">
          <ImButton @click="draggableVisible = false">关闭</ImButton>
        </span>
      </template>
    </ImDialog>
  </div>
</template>

<script setup>
import { ref } from 'vue'

const draggableVisible = ref(false)
</script>

全屏对话框

支持全屏显示,可以通过按钮或双击标题栏切换。

查看代码
vue
<template>
  <div>
    <ImButton @click="fullscreenVisible = true">全屏对话框</ImButton>
    
    <ImDialog 
      v-model="fullscreenVisible" 
      title="全屏对话框"
      width="800px"
      draggable
      show-fullscreen
    >
      <div class="space-y-4">
        <p>这个对话框支持全屏显示。</p>
        <p>全屏功能特点:</p>
        <ul class="list-disc list-inside space-y-1 text-sm text-gray-600">
          <li>标题栏全屏按钮</li>
          <li>双击标题栏切换全屏</li>
          <li>全屏时隐藏拖拽功能</li>
          <li>ESC键退出全屏</li>
        </ul>
        
        <div class="bg-gray-50 p-4 rounded">
          <h4 class="font-medium mb-2">内容区域</h4>
          <p class="text-sm text-gray-600">
            全屏模式下,内容区域会充分利用屏幕空间,
            为用户提供更好的阅读和操作体验。
          </p>
        </div>
      </div>
      
      <template #footer>
        <span class="dialog-footer">
          <ImButton @click="fullscreenVisible = false">关闭</ImButton>
        </span>
      </template>
    </ImDialog>
  </div>
</template>

<script setup>
import { ref } from 'vue'

const fullscreenVisible = ref(false)
</script>

滚动内容对话框

当内容较多时,自动显示滚动条并优化滚动体验。

查看代码
vue
<template>
  <div>
    <ImButton @click="scrollVisible = true">滚动内容对话框</ImButton>
    
    <ImDialog 
      v-model="scrollVisible" 
      title="滚动内容对话框"
      width="600px"
      max-height="400px"
      draggable
      show-fullscreen
    >
      <div class="space-y-4">
        <p>当内容超出最大高度时,会自动显示滚动条。</p>
        
        <div v-for="i in 20" :key="i" class="bg-gray-50 p-3 rounded">
          <h4 class="font-medium">内容块 {{ i }}</h4>
          <p class="text-sm text-gray-600 mt-1">
            这是第 {{ i }} 个内容块。滚动条会根据内容自动显示,
            并且在滚动时提供流畅的用户体验。
          </p>
        </div>
      </div>
      
      <template #footer>
        <span class="dialog-footer">
          <ImButton @click="scrollVisible = false">关闭</ImButton>
        </span>
      </template>
    </ImDialog>
  </div>
</template>

<script setup>
import { ref } from 'vue'

const scrollVisible = ref(false)
</script>

表单对话框

在对话框中使用表单,支持拖拽和全屏。

查看代码
vue
<template>
  <div>
    <ImButton @click="formVisible = true">表单对话框</ImButton>
    
    <ImDialog 
      v-model="formVisible" 
      title="编辑用户信息"
      width="600px"
      draggable
      show-fullscreen
      @close="resetForm"
    >
      <ImForm
        v-model="formData"
        :form-config="formConfig"
        ref="formRef"
      />
      
      <template #footer>
        <span class="dialog-footer">
          <ImButton @click="formVisible = false">取消</ImButton>
          <ImButton type="primary" @click="handleSubmit">保存</ImButton>
        </span>
      </template>
    </ImDialog>
  </div>
</template>

<script setup>
import { ref, reactive } from 'vue'
import { ImMessage } from 'imtes-ui'

const formVisible = ref(false)
const formRef = ref()

const formData = reactive({
  name: '',
  email: '',
  phone: '',
  department: '',
  description: ''
})

const formConfig = {
  formItems: [
    {
      prop: 'name',
      label: '姓名',
      type: 'input',
      rules: [{ required: true, message: '请输入姓名' }]
    },
    {
      prop: 'email',
      label: '邮箱',
      type: 'input',
      rules: [
        { required: true, message: '请输入邮箱' },
        { type: 'email', message: '请输入正确的邮箱格式' }
      ]
    },
    {
      prop: 'phone',
      label: '手机号',
      type: 'input'
    },
    {
      prop: 'department',
      label: '部门',
      type: 'select',
      options: [
        { label: '技术部', value: 'tech' },
        { label: '产品部', value: 'product' },
        { label: '设计部', value: 'design' }
      ]
    },
    {
      prop: 'description',
      label: '描述',
      type: 'textarea',
      props: { rows: 3 }
    }
  ]
}

const handleSubmit = async () => {
  try {
    await formRef.value.validate()
    console.log('表单数据:', formData)
    ImMessage.success('保存成功!')
    formVisible.value = false
  } catch (error) {
    ImMessage.error('请检查表单输入')
  }
}

const resetForm = () => {
  Object.assign(formData, {
    name: '',
    email: '',
    phone: '',
    department: '',
    description: ''
  })
  formRef.value?.clearValidate()
}
</script>

API

Dialog Props

除了继承 Element Plus Dialog 的所有属性外,还扩展了以下属性:

属性说明类型可选值默认值
draggable是否可拖拽booleanfalse
show-fullscreen是否显示全屏按钮booleanfalse
max-height最大高度string
fullscreen是否全屏显示booleanfalse

Dialog Events

继承 Element Plus Dialog 的所有事件,并扩展了以下事件:

事件名说明回调参数
fullscreen-change全屏状态改变时触发(fullscreen: boolean)
drag-start开始拖拽时触发(event: MouseEvent)
drag-end拖拽结束时触发(event: MouseEvent)

Dialog Methods

方法名说明参数
toggleFullscreen切换全屏状态
resetPosition重置对话框位置

功能特点

拖拽功能

  • 点击标题栏拖拽移动
  • 自动边界检测和限制
  • 流畅的拖拽动画效果
  • 全屏时自动禁用拖拽

全屏功能

  • 标题栏全屏切换按钮
  • 双击标题栏快速切换
  • ESC键退出全屏
  • 全屏状态记忆

滚动优化

  • 内容超出时自动显示滚动条
  • 优化的滚动条样式
  • 滚动位置记忆
  • 响应式内容高度

基于 MIT 许可发布