前端交互规范(Web 端)

前端交互规范(Web 端)

适用于基于 Vue + Element Plus 的中后台管理系统,共 20 条交互规范。


一、布局与展示

1. Table 列表页一屏显示

列表页不允许出现页面级竖向滚动条,筛选区 + 表格必须在一屏内完整展示。

scss 复制代码
const filterFormRef = ref<HTMLElement>()
const tableHeight = ref(0)
​
function calcTableHeight() {
  const filterH = filterFormRef.value?.offsetHeight ?? 0
  // 根据实际布局减去 header、padding 等固定高度
  tableHeight.value = window.innerHeight - filterH - OTHER_FIXED_HEIGHT
}
​
onMounted(() => {
  calcTableHeight()
  window.addEventListener('resize', calcTableHeight)
})
​
onUnmounted(() => {
  window.removeEventListener('resize', calcTableHeight)
})
xml 复制代码
<el-table :data="tableData" :height="tableHeight">
  <!-- columns -->
</el-table>

18. 表格操作列固定右侧

操作列使用 fixed="right",横向滚动时操作按钮始终可见。

bash 复制代码
<el-table-column label="操作" fixed="right" width="200">
  <template #default="{ row }">
    <el-button link type="primary" @click="handleEdit(row)">编辑</el-button>
    <el-button link type="danger" @click="handleDelete(row)">删除</el-button>
  </template>
</el-table-column>

19. 长文本省略 + Tooltip

表格单元格长文本使用 show-overflow-tooltip,保持列宽整齐,悬浮可查看完整内容。

sql 复制代码
<el-table-column prop="remark" label="备注" show-overflow-tooltip />

二、弹窗与表单

2. 弹窗禁止点击遮罩层关闭

所有弹窗必须设置 close-on-click-modal="false",防止用户误触遮罩层导致数据丢失。

xml 复制代码
<el-dialog
  v-model="dialogVisible"
  title="新增数据"
  :close-on-click-modal="false"
  width="600px"
>
  <!-- form content -->
</el-dialog>

9. 弹窗表单提交前必须校验

提交前调用 formRef.validate(),校验不通过不发起请求。

csharp 复制代码
async function handleSubmit() {
  const valid = await formRef.value?.validate().catch(() => false)
  if (!valid) return
  // 发起请求
}

15. 弹窗打开时重置表单

弹窗每次打开必须重置表单数据和校验状态,避免上次数据残留。

scss 复制代码
function openDialog(row?: RowType) {
  nextTick(() => {
    formRef.value?.resetFields()
    if (row) {
      Object.assign(formData, row)
    }
  })
  dialogVisible.value = true
}

11. 弹窗关闭前变更确认

弹窗内表单有修改时,关闭前弹出二次确认"是否放弃修改?"。

javascript 复制代码
function handleDialogClose(done: () => void) {
  if (isFormDirty.value) {
    ElMessageBox.confirm('表单已修改,确定放弃当前编辑内容吗?', '提示', {
      type: 'warning',
    }).then(() => done()).catch(() => {})
  } else {
    done()
  }
}
ruby 复制代码
<el-dialog :before-close="handleDialogClose">

三、防重复提交

3. 流程操作函数节流 + 确认弹窗拦截

新增、完成等流程操作使用 throttle 防止多次点击生成重复数据。

方式一:throttle 节流

javascript 复制代码
import { throttle } from 'lodash'

const handleSubmit = throttle(() => {
  // 业务逻辑
}, 1000, { trailing: false })

方式二:$confirm + beforeClose 模式(推荐用于关键流程操作)

javascript 复制代码
function handleConfirm() {
  ElMessageBox.confirm(
    '确认执行此操作?一旦确认将不可撤回',
    '提示',
    {
      type: 'warning',
      beforeClose: (action, instance, done) => {
        if (action === 'confirm') {
          instance.confirmButtonLoading = true
          instance.confirmButtonText = '执行中...'
          submitApi().finally(() => {
            setTimeout(() => {
              instance.confirmButtonLoading = false
              done()
            }, 300)
          })
        } else {
          done()
        }
      },
    }
  ).then(() => {
    getList()
    ElMessage.success('操作成功')
  }).catch(() => {})
}

10. 提交按钮 Loading 状态

提交/保存按钮在请求期间设为 loading,请求完成后恢复,给用户明确的视觉反馈。

bash 复制代码
<el-button type="primary" :loading="submitLoading" @click="handleSubmit">
  确 定
</el-button>
csharp 复制代码
const submitLoading = ref(false)

async function handleSubmit() {
  submitLoading.value = true
  try {
    await submitApi(formData)
    ElMessage.success('提交成功')
    dialogVisible.value = false
    getList()
  } finally {
    submitLoading.value = false
  }
}

四、输入与筛选

4. 下拉框必须支持搜索过滤

所有 el-select 加上 filterable 属性,当选项较多时允许用户键入关键字快速定位。

ini 复制代码
<el-select v-model="formData.type" filterable placeholder="请选择" clearable>
  <el-option
    v-for="item in options"
    :key="item.value"
    :label="item.label"
    :value="item.value"
  />
</el-select>

5. 输入框过滤空格

输入框使用 .trim 修饰符或手动 trim(),避免空格导致查询/提交异常。

xml 复制代码
<!-- 方式一:v-model.trim -->
<el-input v-model.trim="queryParams.keyword" placeholder="请输入关键字" />

<!-- 方式二:@blur 时手动 trim -->
<el-input v-model="formData.name" @blur="formData.name = formData.name.trim()" />

6. 支持回车触发查询

筛选表单支持按 Enter 键直接触发查询,减少鼠标操作。

ini 复制代码
<el-form @submit.prevent="handleQuery">
  <el-input
    v-model.trim="queryParams.keyword"
    placeholder="请输入关键字"
    @keyup.enter="handleQuery"
    clearable
  />
</el-form>

16. 数字输入框限制

数字输入框限制输入类型,禁止输入非法字符。

xml 复制代码
<el-input
  v-model="formData.amount"
  placeholder="请输入金额"
  @input="formData.amount = formData.amount.replace(/[^\d.]/g, '')"
/>

<!-- 或使用 el-input-number -->
<el-input-number v-model="formData.quantity" :min="0" :max="99999" :precision="0" />

17. 日期选择范围限制

日期选择器通过 disabled-date 限制可选范围,避免选择无效日期。

ini 复制代码
<el-date-picker
  v-model="formData.date"
  type="date"
  placeholder="请选择日期"
  :disabled-date="disabledDate"
/>
javascript 复制代码
function disabledDate(time: Date) {
  return time.getTime() > Date.now()
}

五、加载与状态反馈

7. Table 加载 Loading 状态

数据加载时必须显示 loading,避免空白页面让用户困惑。

xml 复制代码
<el-table :data="tableData" :height="tableHeight" v-loading="tableLoading">
  <!-- columns -->
</el-table>
ini 复制代码
const tableLoading = ref(false)

async function getList() {
  tableLoading.value = true
  try {
    const res = await fetchListApi(queryParams)
    tableData.value = res.data.rows
    total.value = res.data.total
  } finally {
    tableLoading.value = false
  }
}

8. 列表空状态提示

列表无数据时显示空状态组件,区分"加载中"与"确实没有数据"。

xml 复制代码
<el-table :data="tableData" :height="tableHeight" v-loading="tableLoading">
  <!-- columns -->
  <template #empty>
    <el-empty description="暂无数据" />
  </template>
</el-table>

12. 操作成功消息反馈

增删改操作成功后统一使用 ElMessage.success 提示,让用户明确知道操作已完成。

arduino 复制代码
ElMessage.success('新增成功')
ElMessage.success('修改成功')
ElMessage.success('删除成功')

六、危险操作保护

13. 删除等危险操作二次确认

删除、重置等不可逆操作必须使用 ElMessageBox.confirm 二次确认。

javascript 复制代码
async function handleDelete(row: RowType) {
  await ElMessageBox.confirm(
    `确认删除「${row.name}」吗?删除后将无法恢复`,
    '警告',
    { type: 'warning' }
  )
  await deleteApi(row.id)
  ElMessage.success('删除成功')
  getList()
}

七、分页与批量操作

14. 分页状态保持

编辑/删除后保持当前页码;新增后跳转第一页;删除当前页最后一条时自动回退上一页。

scss 复制代码
function afterEdit() {
  getList() // 保持当前 queryParams.pageNum
}

function afterAdd() {
  queryParams.pageNum = 1
  getList()
}

function afterDelete() {
  if (tableData.value.length === 1 && queryParams.pageNum > 1) {
    queryParams.pageNum--
  }
  getList()
}

20. 批量操作前校验选中状态

批量操作前必须校验是否已选中数据,未选中时给出提示。

javascript 复制代码
function handleBatchDelete() {
  if (selectedRows.value.length === 0) {
    ElMessage.warning('请至少选择一条数据')
    return
  }
  ElMessageBox.confirm(
    `确认删除选中的 ${selectedRows.value.length} 条数据吗?`,
    '警告',
    { type: 'warning' }
  ).then(async () => {
    const ids = selectedRows.value.map(row => row.id)
    await batchDeleteApi(ids)
    ElMessage.success('批量删除成功')
    getList()
  }).catch(() => {})
}

速查清单

# 规范 关键配置 / API
1 列表一屏显示 :height="tableHeight" 动态计算
2 弹窗禁止遮罩关闭 :close-on-click-modal="false"
3 流程操作防重复 throttle / beforeClose 模式
4 下拉框可搜索 filterable
5 输入框去空格 v-model.trim
6 回车查询 @keyup.enter
7 表格 Loading v-loading
8 空状态提示 <el-empty>
9 提交前校验 formRef.validate()
10 按钮 Loading :loading="submitLoading"
11 关闭前确认 :before-close
12 成功消息 ElMessage.success()
13 删除二次确认 ElMessageBox.confirm()
14 分页保持 条件判断 pageNum
15 表单重置 formRef.resetFields()
16 数字输入限制 replace / el-input-number
17 日期范围限制 :disabled-date
18 操作列固定 fixed="right"
19 长文本省略 show-overflow-tooltip
20 批量操作校验 选中数量判断
相关推荐
candyTong6 小时前
一觉醒来,大模型就帮我排查完页面性能问题
前端·javascript·架构
魔术师Grace6 小时前
我给 AI 做了场入职培训
前端·程序员
玩嵌入式的菜鸡6 小时前
网页访问单片机设备---基于mqtt
前端·javascript·css
前端一小卒7 小时前
我用 Claude Code 的 Superpowers 技能链写了个服务,部署前差点把服务器搞炸
前端·javascript·后端
滑雪的企鹅.8 小时前
HTML头部元信息避坑指南大纲
前端·html
一拳不是超人8 小时前
老婆天天吵吵要买塔罗牌,我直接用 AI 2 小时写了个在线塔罗牌
前端·ai编程
excel10 小时前
如何解决 Nuxt DevTools 中关于 unstorage 包的报错
前端
Rust研习社10 小时前
使用 Axum 构建高性能异步 Web 服务
开发语言·前端·网络·后端·http·rust
C澒10 小时前
AI 生码 - API2Code:接口智能匹配与 API 自动化生码全链路设计
前端·低代码·ai编程
浔川python社10 小时前
HTML头部元信息避坑指南技术文章大纲
前端·html