Dialog 对话框
对话框用于在保留当前页面状态的情况下承载临时任务。VISTA B 直接使用 Element Plus 的 el-dialog,在此基础上统一标题栏、内容区、底部操作、圆角、阴影和业务内容布局。
设计稿入口:
基础用法
使用 v-model 控制弹窗显示隐藏。标题使用 title,底部按钮放在 footer 插槽中。右上角关闭按钮保留 Element Plus 默认能力,业务确认按钮需要自行处理校验、提交和关闭。
<el-dialog v-model="visible" title="编辑案例" width="640px">
<div class="dialog-content">
弹窗内容可以放表单、表格、图片列表、说明信息或多步骤业务流程。
</div>
<template #footer>
<el-button @click="visible = false">取消</el-button>
<el-button type="primary" @click="submit">保存</el-button>
</template>
</el-dialog>通用结构
弹窗由标题栏、内容区和底部操作栏组成。标题栏高 40px,左右内边距 20px;底部操作栏高 56px,上方有 1px 分割线;弹窗圆角为 16px,输入框和按钮高度统一为 32px。
底部操作默认右对齐,顺序为“取消 / 主操作”。当存在上传、翻译、重置等辅助动作时,辅助按钮放在左侧,主操作仍保持右侧。
<el-dialog v-model="visible" title="一键导入眺望" width="960px">
<template #default>
<div class="dialog-content">内容区</div>
</template>
<template #footer>
<div class="dialog-footer dialog-footer--split">
<el-button plain>
<el-icon><Plus /></el-icon>
<span>上传图片</span>
</el-button>
<div>
<el-button @click="visible = false">取消</el-button>
<el-button type="primary" @click="startAi">开始AI识图</el-button>
</div>
</div>
</template>
</el-dialog>弹窗尺寸
弹窗宽度按内容复杂度选择。小弹窗用于单行文本、列展示等轻任务;中弹窗用于普通表单;大弹窗用于图片列表、表格+表单、JSON 编辑等复合内容;超宽弹窗用于一键导入、批量识别等多步骤流程。
| 尺寸 | 建议宽度 | 典型场景 |
|---|---|---|
| 小 | 360px / 420px | 单行国际化、列展示、轻量配置 |
| 中 | 640px / 680px | 表单编辑、信息确认、普通配置 |
| 大 | 960px | 图片弹窗、JSON 双栏、表格+表单 |
| 超宽 | 1200px | AI 识别流程、批量图片确认、复杂表格 |
<el-dialog v-model="visible" title="列展示" width="360px" />
<el-dialog v-model="visible" title="编辑案例" width="640px" />
<el-dialog v-model="visible" title="一键导入眺望" width="960px" />
<el-dialog v-model="visible" title="建筑【A栋】一键导入户型" width="1200px" />表单弹窗
表单弹窗用于新增、编辑和配置。表单项左侧展示必填星号和标签,右侧放输入框、选择器、单选、多选、开关、上传、富文本等控件。错误信息显示在控件下方,字数统计放在输入框或文本域右下角。
<el-dialog v-model="visible" title="表单弹窗" width="640px">
<el-form :model="form" label-width="88px">
<el-form-item label="名称" required prop="name">
<el-input v-model="form.name" maxlength="20" show-word-limit />
</el-form-item>
<el-form-item label="类型" required prop="type">
<el-select v-model="form.type" placeholder="请选择" />
</el-form-item>
<el-form-item label="图片" required prop="image">
<el-upload list-type="picture-card" />
</el-form-item>
</el-form>
<template #footer>
<el-button @click="visible = false">取消</el-button>
<el-button type="primary" @click="submit">保存</el-button>
</template>
</el-dialog>上传状态
图片上传区域使用虚线框和加号。上传中、上传成功、上传失败、hover、已上传等状态都在同一位置切换。文件列表上传时展示进度条;成功显示成功图标;失败显示错误文案,并保留重试或删除入口。
<el-upload
v-model:file-list="files"
list-type="picture-card"
:limit="10"
:before-upload="beforeUpload"
>
<el-icon><Plus /></el-icon>
</el-upload>国际化弹窗
国际化弹窗全局通用,根据文本长度选择多行或单行。多行文本在页面不直接展示文案,点击编辑后打开大弹窗;左侧用语言 tab 切换,已翻译语言显示绿色勾,右侧展示正文编辑区。底部左侧放紫色翻译按钮,右侧保留取消和保存。
<el-dialog v-model="i18nVisible" title="国际化" width="760px">
<div class="i18n-dialog">
<nav class="i18n-dialog__tabs">
<button v-for="lang in languages" :key="lang.key">
<span>{{ lang.label }}</span>
<el-icon v-if="lang.done"><CircleCheckFilled /></el-icon>
</button>
</nav>
<el-input v-model="currentText" type="textarea" :rows="12" />
</div>
<template #footer>
<div class="dialog-footer dialog-footer--split">
<el-button class="translate-button" @click="translate">
<el-icon><Refresh /></el-icon>
<span>翻译</span>
</el-button>
<div>
<el-button @click="i18nVisible = false">取消</el-button>
<el-button type="primary" @click="save">保存</el-button>
</div>
</div>
</template>
</el-dialog>单行国际化
单行国际化用于标题、名称等短文本。页面文字可直接编辑,点击翻译入口后打开小弹窗;每种语言一行输入框,翻译按钮只显示图标,取消和保存位置与多行弹窗一致。
<el-dialog v-model="singleI18nVisible" title="国际化配置" width="360px">
<el-form label-width="72px">
<el-form-item label="English">
<el-input v-model="name.en" />
</el-form-item>
<el-form-item label="日本語">
<el-input v-model="name.ja" />
</el-form-item>
<el-form-item label="한국어">
<el-input v-model="name.ko" />
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer dialog-footer--split">
<el-button class="translate-button" circle>
<el-icon><Refresh /></el-icon>
</el-button>
<div>
<el-button @click="singleI18nVisible = false">取消</el-button>
<el-button type="primary" @click="save">保存</el-button>
</div>
</div>
</template>
</el-dialog>图片弹窗
图片弹窗用于封面图、案例图、眺望图和批量图片管理。内容区使用图片网格,第一项可为上传入口;图片右下角显示查看、替换、删除等图标按钮。图片名称可展示、截断、hover 提示,也可进入行内编辑状态。
<el-dialog v-model="imageVisible" title="一键导入眺望" width="960px">
<div class="image-grid">
<button class="image-upload-card">
<el-icon><Plus /></el-icon>
</button>
<article v-for="image in images" :key="image.id" class="image-card">
<img :src="image.url" :alt="image.name" />
<div class="image-card__actions">
<el-button circle><el-icon><View /></el-icon></el-button>
<el-button circle><el-icon><Delete /></el-icon></el-button>
</div>
<strong>{{ image.name }}</strong>
</article>
</div>
<template #footer>
<div class="dialog-footer dialog-footer--split">
<el-button plain>
<el-icon><Plus /></el-icon>
<span>上传图片</span>
</el-button>
<div>
<el-button @click="imageVisible = false">取消</el-button>
<el-button type="primary" @click="startAi">开始AI识图</el-button>
</div>
</div>
</template>
</el-dialog>AI 导入流程
一键导入使用同一个大弹窗承载多步骤流程:拖拽导入、确认图片、AI 识别、识别完成。识别中显示空状态和进度提示;完成后展示可编辑表格,支持修改户型、户型编号、户型结构、面积等字段。过程状态通过消息提示反馈。
<el-dialog v-model="aiVisible" title="建筑【A栋】一键导入户型" width="1200px">
<UploadStep v-if="step === 'upload'" />
<ConfirmImagesStep v-if="step === 'confirm'" />
<RecognizingStep v-if="step === 'recognizing'" />
<RecognitionResultStep v-if="step === 'result'" />
<template #footer>
<el-button @click="aiVisible = false">取消</el-button>
<el-button v-if="step === 'confirm'" type="primary" @click="startRecognize">
开始AI识图
</el-button>
<el-button v-if="step === 'result'" type="primary" @click="saveResult">
保存
</el-button>
</template>
</el-dialog>复合内容弹窗
复合弹窗用于 JSON 读取、表格+表单、信息展示+按钮等场景。内容可以分栏、分区或上下组合;只要底部操作栏保持一致,内容区可以按业务自由组织。
<el-dialog v-model="jsonVisible" title="西明石GIS大楼" width="960px">
<div class="json-dialog">
<FileTree :files="files" />
<CodeEditor v-model="json" />
</div>
<template #footer>
<el-button @click="jsonVisible = false">取消</el-button>
<el-button type="primary" @click="save">保存</el-button>
</template>
</el-dialog>选择弹窗
选择弹窗用于表格勾选、权限树、列展示和首页模块设置。表格勾选类弹窗需要保留表头全选;权限类弹窗可左侧显示一级模块,右侧显示树形权限;列展示和模块设置可以使用小弹窗或右侧配置面板,底部固定全选、重置、取消和保存。
<el-dialog v-model="permissionVisible" title="子项目权限设置" width="900px">
<div class="permission-dialog">
<aside class="permission-dialog__group-list">
<button v-for="group in groups" :key="group.id">{{ group.name }}</button>
</aside>
<el-tree
ref="treeRef"
:data="permissions"
show-checkbox
node-key="id"
default-expand-all
/>
</div>
<template #footer>
<el-button @click="permissionVisible = false">取消</el-button>
<el-button type="primary" @click="savePermission">保存</el-button>
</template>
</el-dialog>表格弹窗
表格弹窗用于眺望选择、权限模板新建、任务选择等列表型任务。表格默认铺满弹窗内容宽度,底部保留固定操作栏。需要选择时在首列放复选框;需要管理时在末列放图标按钮。
<el-dialog v-model="tableVisible" title="眺望" width="900px">
<el-table :data="rows" height="520">
<el-table-column type="selection" width="48" />
<el-table-column prop="thumbnail" label="缩略图" />
<el-table-column prop="area" label="面积/m²" />
<el-table-column prop="type" label="类型" />
<el-table-column prop="status" label="状态" sortable />
<el-table-column label="管理" />
</el-table>
<template #footer>
<el-button @click="tableVisible = false">取消</el-button>
<el-button type="primary" @click="save">保存</el-button>
</template>
</el-dialog>信息与操作弹窗
信息展示类弹窗先展示基础信息和任务信息,再在操作区域放按钮、日期选择、负责人选择等控件。信息区只展示事实,操作区才允许修改。高风险操作使用红色线框按钮,普通流程按钮使用品牌色线框或主按钮。
<el-dialog v-model="taskVisible" title="任务处理" width="900px">
<section class="task-info">
<h3>项目基础信息</h3>
<dl>
<dt>项目名称</dt>
<dd>京王多摩川ハモンズ</dd>
<dt>VISTA ID</dt>
<dd>1988782582468317184</dd>
</dl>
</section>
<section class="task-actions">
<el-button type="danger" plain>提前结束</el-button>
<el-button type="primary" plain>延期</el-button>
<el-button type="primary" plain>替换负责人</el-button>
</section>
</el-dialog>嵌套与关闭
需要在弹窗中再打开弹窗时,内层弹窗必须设置 append-to-body。需要在关闭前二次确认、校验未保存内容或拦截关闭时,使用 before-close;如果是底部按钮触发关闭,需要在按钮点击事件中执行同样逻辑。
<el-dialog v-model="outerVisible" title="外层弹窗">
<el-button @click="innerVisible = true">打开内层弹窗</el-button>
<el-dialog
v-model="innerVisible"
title="内层弹窗"
append-to-body
:before-close="handleBeforeClose"
/>
</el-dialog>API
Dialog 属性
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
v-model / model-value | 是否显示 Dialog | boolean | false |
title | Dialog 标题 | string | 空 |
width | Dialog 宽度 | string / number | 50% |
fullscreen | 是否全屏显示 | boolean | false |
modal | 是否显示遮罩层 | boolean | true |
append-to-body | Dialog 是否插入到 body | boolean | false |
lock-scroll | 是否在打开时锁定页面滚动 | boolean | true |
close-on-click-modal | 是否可点击遮罩关闭 | boolean | true |
close-on-press-escape | 是否可按 Esc 关闭 | boolean | true |
show-close | 是否显示右上角关闭按钮 | boolean | true |
before-close | 关闭前回调 | function | 空 |
destroy-on-close | 关闭后是否销毁内容 | boolean | false |
center | 标题和底部是否居中 | boolean | false |
align-center | 是否水平垂直居中 | boolean | false |
draggable | 是否可拖拽 | boolean | false |
overflow | 拖拽时是否允许超出可视区域 | boolean | false |
Dialog 插槽
| 插槽 | 说明 |
|---|---|
default | Dialog 内容区 |
header | 自定义标题栏 |
footer | 自定义底部操作栏 |
Dialog 事件
| 事件 | 说明 |
|---|---|
open | Dialog 打开时触发 |
opened | Dialog 打开动画结束时触发 |
close | Dialog 关闭时触发 |
closed | Dialog 关闭动画结束时触发 |
open-auto-focus | 内容获得焦点时触发 |
close-auto-focus | 焦点返回触发元素时触发 |
VISTA B 规范
| 项目 | 规范 |
|---|---|
| 圆角 | 弹窗圆角统一为 16px |
| 标题栏 | 高 40px,左右内边距 20px,右侧保留关闭按钮 |
| 内容区 | 按业务复杂度选择表单、表格、图片网格、分栏或流程内容 |
| 底栏 | 高 56px,顶部 1px 分割线 |
| 底部按钮 | 右侧为取消和主操作,左侧可放上传、翻译、重置等辅助操作 |
| 控件高度 | 输入框、选择器、按钮默认 32px |
| 主按钮 | 使用 HOME VISTA 品牌渐变 |
| 高风险操作 | 使用红色线框按钮 |
| 国际化 | 多行文本用大弹窗,单行文本用小弹窗,翻译按钮放底部左侧 |
| 复杂流程 | AI 导入等多步骤流程在同一大弹窗内切换内容状态 |

