在验证失败时,给 input 添加一个错误高亮样式(红色边框 + 抖动动画),比直接 focus 更合适,因为用户可能已经填过内容但格式不对。
实现思路
- 用
ref获取 input 的 DOM 引用 - 验证失败时,添加一个错误 class,并调用
inputRef.value.focus()聚焦 - 用 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():验证失败时聚焦到 inputshake动画:验证失败时 input 抖动,提示用户注意
这样用户在提交时,如果标题为空,input 会变成红色边框并抖动,同时自动聚焦到该输入框。
提醒:编辑器内容校验用的是 <p><br></p>,这个字符串是固定的,但有些编辑器(比如wangEditor)在内容为空时可能输出 <p><br></p>、<p></p> 或空字符串,可以写一个更健壮的校验函数。