vue3项目表单验证 input 添加高亮样式

在验证失败时,给 input 添加一个错误高亮样式(红色边框 + 抖动动画),比直接 focus 更合适,因为用户可能已经填过内容但格式不对。

实现思路

  1. 用 ref 获取 input 的 DOM 引用
  2. 验证失败时,添加一个错误 class,并调用 inputRef.value.focus() 聚焦
  3. 用 CSS 定义错误样式和抖动动画

完整代码

html 复制代码
<script setup>
import Editor from '@/components/Editor.vue'
import { ref } from 'vue'
import { posAddArticle } from '@/api/add_article'
import { toast } from '@/components/Toast'

const title = ref('')
const editrValue = ref('')
const titleError = ref(false)
const inputRef = ref(null)

const handleChange = (val) => {
  editrValue.value = val
}

const handleSubmit = async () => {
  // 重置错误状态
  titleError.value = false

  // 验证标题
  if (title.value === '') {
    titleError.value = true
    toast({ msg: '标题为空', type: 'error' })
    inputRef.value?.focus()
    return
  }

  // 验证编辑器内容
  if (editrValue.value === '<p><br></p>') {
    toast({ msg: '编辑器内容为空', type: 'error' })
    return
  }

  // 验证通过,提交
  try {
    const data = await posAddArticle({
      title: title.value,
      content: editrValue.value
    })
    toast({ msg: '提交成功', type: 'success' })
  } catch (err) {
    console.error('请求失败', err)
  }
}
</script>

<template>
  <form @submit.prevent="handleSubmit">
    <input
      ref="inputRef"
      v-model="title"
      placeholder="标题"
      :class="{ 'input-error': titleError }"
      @input="titleError = false"
    />
    <br /><br />
    <Editor @change-content="handleChange" />
    <br />
    <button type="submit">提交</button>
  </form>
</template>

<style scoped>
input {
  height: 35px;
  width: 400px;
  padding: 5px 15px;
  border: 1px solid #ccc;
  outline: none;
  transition: border-color 0.3s;
}

input:focus {
  border: 1px solid #1ec4a0;
}

/* 
错误状态样式 不会生效,因为样式权重低
.input-error {
  border: 1px solid #ff4d4f;
  animation: shake 0.4s ease-in-out;
}
*/

/* 错误状态样式 会生效,样式权重变高 */
form input.input-error {
  border: 1px solid #ff4d4f;
  animation: shake 0.4s ease-in-out;
}

/* 抖动动画 */
@keyframes shake {
  0%, 100% { transform: translateX(0); }
  20% { transform: translateX(-6px); }
  40% { transform: translateX(6px); }
  60% { transform: translateX(-4px); }
  80% { transform: translateX(4px); }
}

button {
  height: 40px;
  width: 250px;
  border: 0;
  cursor: pointer;
  background-color: #00bbc2;
  color: #fff;
  transition: background-color 0.5s;
  border-radius: 2px;
}

button:hover {
  background-color: #15e0e7;
}
</style>

关键点说明

  • ref="inputRef" :获取 input 的 DOM 引用
  • titleError:控制是否显示错误样式
  • :class="{ 'input-error': titleError }" :动态绑定错误 class
  • @input="titleError = false" :用户重新输入时自动清除错误状态
  • inputRef.value?.focus() :验证失败时聚焦到 input
  • shake 动画:验证失败时 input 抖动,提示用户注意

这样用户在提交时,如果标题为空,input 会变成红色边框并抖动,同时自动聚焦到该输入框。


提醒:编辑器内容校验用的是 <p><br></p>,这个字符串是固定的,但有些编辑器(比如wangEditor)在内容为空时可能输出 <p><br></p>、<p></p> 或空字符串,可以写一个更健壮的校验函数。

相关推荐
积流成海20 分钟前
用代码实现哈希计算器:Web Crypto API 实战
前端·算法·哈希算法·哈希函数·盘子工具站
data analyse 45627 分钟前
服务端访问日志聚合 PV 与 UV 怎么实现?日志采集与口径设计
大数据·前端·数据分析
JavaGuide32 分钟前
DeepSeek Harness 重磅更新,Codex、Claude Code 子智能体进官方插件列表了,还有 Git 工作树和思考翻译!
前端·后端
小羊没烦恼!1 小时前
OS X 上使用.NET开发应用程序
开发语言·前端·数据库·人工智能·c#·策略模式
Eiceblue2 小时前
使用 Python 实现 Excel 行列转置(保留单元格样式)
前端·python·excel
西西学代码2 小时前
像素和颜色之间的转换(Flutter)
前端·javascript·flutter
茶底世界之下2 小时前
羽毛颜色已经很鲜艳,还要继续加色吗?用 Awaking 试一次减饱和
前端·ios·运营
风早爽太2 小时前
Mac 搭建 Vue 开发环境
前端·vue.js
Lank_M2 小时前
Word图片裁剪转HTML失效,转换器各漏读了哪一层
前端
青烟小生2 小时前
前端架构设计实战:从组件思维到系统思维
前端