Vue3 生态工具实战宝典:UI 组件库 + 表单验证全解析(Element Plus/Ant Design Vue/VeeValidate)
本文系统介绍了Vue3生态中两大主流UI组件库(ElementPlus和AntDesignVue)的安装配置、核心组件使用与性能优化技巧,以及两种表单验证方案(ElementPlus内置验证和VeeValidate高级验证)的实现方式。通过对比分析组件库特性、验证方案适用场景,提供技术选型建议,并给出包含自定义验证规则、多语言支持的综合实战案例。文章强调按需引入优化性能,推荐结合TypeScrip

前言
Vue3 作为当前前端主流框架,其生态完善度直接决定开发效率和项目质量。在实际开发中,UI 组件库 是页面搭建的基础,表单验证 是交互逻辑的核心,这两个模块也是新手最易踩坑、进阶开发者需优化的关键环节。
本文从实战落地角度,系统讲解 Vue3 生态中最主流的两款 UI 组件库(Element Plus、Ant Design Vue)的安装、使用与性能优化,以及两种表单验证方案(Element Plus 内置验证、VeeValidate 高级验证)的核心用法与场景选型。内容覆盖基础配置、进阶技巧、踩坑解决方案,既适合 Vue3 新手快速上手,也能为中大型项目提供技术选型参考。
一、Vue3 主流 UI 组件库实战(Element Plus & Ant Design Vue)
1.1 为什么选择这两款 UI 组件库?
在 Vue3 生态中,Element Plus 和 Ant Design Vue 是使用率最高的两款企业级 UI 组件库,核心优势对比如下:

注:两款组件库均基于 Vue3+TS 开发,支持按需引入、自定义主题,是生产环境的首选,而非小众组件库(如 Naive UI、Vuetify)的「尝鲜式」选择。
1.2 Element Plus:安装与核心使用技巧
1.2.1 环境准备与安装
前置条件:已初始化 Vue3 项目(推荐 Vite+TS),Node 版本≥14.18.0。
安装命令(支持 npm/yarn/pnpm,推荐 pnpm):
# npm
npm install element-plus --save
# yarn
yarn add element-plus
# pnpm(推荐,体积更小、速度更快)
pnpm add element-plus
1.2.2 全局引入 vs 按需引入(性能优化关键)
全局引入(适合快速开发 / 小型项目):优点:配置简单,无需逐个引入组件;缺点:打包体积大,首屏加载慢。
在main.ts中配置:
import { createApp } from 'vue'
import App from './App.vue'
// 全局引入Element Plus
import ElementPlus from 'element-plus'
// 引入全部样式
import 'element-plus/dist/index.css'
const app = createApp(App)
// 挂载到Vue实例
app.use(ElementPlus)
app.mount('#app')
按需引入(生产环境首选):优点:只打包使用的组件,体积减少 60%+;缺点:需额外配置插件。
步骤 1:安装按需引入插件
pnpm add unplugin-vue-components unplugin-auto-import -D
步骤 2:修改vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
// 引入Element Plus按需引入插件
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
export default defineConfig({
plugins: [
vue(),
// 自动导入Element Plus的API
AutoImport({
resolvers: [ElementPlusResolver()],
}),
// 自动导入Element Plus组件
Components({
resolvers: [ElementPlusResolver()],
}),
],
})
踩坑提示:按需引入后若样式丢失,需检查
vite.config.ts是否配置正确,或手动引入单个组件的样式(如import 'element-plus/es/components/button/style/css')。
1.2.3 基础组件实战(按钮 / 表格 / 表单容器)
1)按钮组件(最基础,演示属性配置):
<template>
<div class="button-demo">
<!-- 基础按钮 -->
<el-button>默认按钮</el-button>
<!-- 类型按钮 -->
<el-button type="primary">主要按钮</el-button>
<el-button type="success">成功按钮</el-button>
<!-- 禁用状态 -->
<el-button type="danger" disabled>禁用按钮</el-button>
<!-- 图标按钮 -->
<el-button type="warning" icon="el-icon-search">搜索</el-button>
</div>
</template>
<style scoped>
.button-demo {
gap: 10px;
display: flex;
}
</style>
2)表格组件(中后台核心,演示数据绑定 / 列配置):
<template>
<el-table :data="tableData" border style="width: 100%">
<!-- 普通列 -->
<el-table-column prop="name" label="姓名" width="180" />
<!-- 自定义列(如状态标签) -->
<el-table-column prop="status" label="状态">
<template #default="scope">
<el-tag :type="scope.row.status === 'active' ? 'success' : 'danger'">
{{ scope.row.status === 'active' ? '活跃' : '禁用' }}
</el-tag>
</template>
</el-table-column>
<!-- 操作列 -->
<el-table-column label="操作">
<template #default="scope">
<el-button size="small" type="primary" @click="handleEdit(scope.row)">编辑</el-button>
<el-button size="small" type="danger" @click="handleDelete(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
</template>
<script setup lang="ts">
// 定义表格数据类型
interface TableRow {
name: string;
status: string;
id: number;
}
// 模拟表格数据
const tableData: TableRow[] = [
{ id: 1, name: '张三', status: 'active' },
{ id: 2, name: '李四', status: 'disabled' },
{ id: 3, name: '王五', status: 'active' },
];
// 编辑事件
const handleEdit = (row: TableRow) => {
console.log('编辑:', row);
};
// 删除事件
const handleDelete = (row: TableRow) => {
console.log('删除:', row);
};
</script>
3)表单容器(为后续表单验证做铺垫):
<template>
<el-form :model="formData" label-width="120px" class="form-demo">
<el-form-item label="用户名">
<el-input v-model="formData.username" placeholder="请输入用户名" />
</el-form-item>
<el-form-item label="密码">
<el-input v-model="formData.password" type="password" placeholder="请输入密码" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleSubmit">提交</el-button>
</el-form-item>
</el-form>
</template>
<script setup lang="ts">
interface FormData {
username: string;
password: string;
}
const formData: FormData = {
username: '',
password: '',
};
const handleSubmit = () => {
console.log('表单数据:', formData);
};
</script>
<style scoped>
.form-demo {
width: 400px;
margin: 20px;
}
</style>
1.2.4 实战踩坑:样式丢失 / 组件不生效解决方案
- 样式丢失:检查是否引入样式文件(全局引入需
import 'element-plus/dist/index.css',按需引入若仍丢失,可手动引入组件样式); - 组件不生效:确认
vite.config.ts中ElementPlusResolver配置正确,或重启 Vite 服务; - TS 类型报错:安装
@types/element-plus(pnpm add @types/element-plus -D)。
1.3 Ant Design Vue:安装与核心使用技巧
1.3.1 环境准备与安装
前置条件与 Element Plus 一致,安装命令:
# npm
npm install ant-design-vue --save
# pnpm
pnpm add ant-design-vue
1.3.2 全局引入 vs 按需引入
全局引入:
import { createApp } from 'vue'
import App from './App.vue'
import Antd from 'ant-design-vue';
import 'ant-design-vue/dist/reset.css'; // 注意:AntD Vue的样式文件名称与Element Plus不同
const app = createApp(App);
app.use(Antd);
app.mount('#app');
按需引入(生产环境首选):步骤 1:安装插件
pnpm add unplugin-vue-components unplugin-auto-import -D
步骤 2:修改vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { AntDesignVueResolver } from 'unplugin-vue-components/resolvers'
export default defineConfig({
plugins: [
vue(),
AutoImport({
resolvers: [AntDesignVueResolver()],
}),
Components({
resolvers: [AntDesignVueResolver()],
}),
],
})
1.3.3 基础组件实战(卡片 / 下拉菜单 / 表单)
1)卡片组件:
<template>
<a-card title="用户信息卡片" style="width: 300px">
<a-descriptions :column="1" bordered>
<a-descriptions-item label="姓名">张三</a-descriptions-item>
<a-descriptions-item label="年龄">25</a-descriptions-item>
<a-descriptions-item label="手机号">13800138000</a-descriptions-item>
</a-descriptions>
</a-card>
</template>
2)下拉菜单组件:
<template>
<a-dropdown>
<a-button type="primary">
操作菜单 <a-icon type="down" />
</a-button>
<template #overlay>
<a-menu>
<a-menu-item key="1">
<a-icon type="edit" /> 编辑
</a-menu-item>
<a-menu-item key="2">
<a-icon type="delete" /> 删除
</a-menu-item>
<a-menu-item key="3">
<a-icon type="copy" /> 复制
</a-menu-item>
</a-menu>
</template>
</a-dropdown>
</template>
3)表单容器:
<template>
<a-form
:model="formData"
layout="vertical"
style="width: 400px; margin: 20px"
>
<a-form-item label="用户名" name="username">
<a-input v-model:value="formData.username" placeholder="请输入用户名" />
</a-form-item>
<a-form-item label="密码" name="password">
<a-input-password v-model:value="formData.password" placeholder="请输入密码" />
</a-form-item>
<a-form-item>
<a-button type="primary" @click="handleSubmit">提交</a-button>
</a-form-item>
</a-form>
</template>
<script setup lang="ts">
interface FormData {
username: string;
password: string;
}
const formData: FormData = {
username: '',
password: '',
};
const handleSubmit = () => {
console.log('表单数据:', formData);
};
</script>
1.4 Element Plus vs Ant Design Vue:选型决策指南
| 维度 | Element Plus | Ant Design Vue |
|---|---|---|
| 学习成本 | 低(文档更贴合 Vue 开发者习惯) | 中(设计理念偏阿里系,部分概念需适应) |
| 组件丰富度 | 中(覆盖基础场景,特殊组件需扩展) | 高(企业级组件齐全,如流程图、日历) |
| 自定义主题 | 简单(提供在线主题编辑器) | 中等(需配置 less 变量) |
| 性能 | 优(Vue3 重写,体积小) | 中(组件多,按需引入后性能可接受) |
| 适用场景 | 中小型中后台、快速迭代项目 | 大型中台、设计规范严格的企业项目 |
二、Vue3 表单验证:从基础到高级(Element Plus Form & VeeValidate)
2.1 表单验证的本质:为什么不能少?
表单验证是「前端数据校验的第一道防线」,核心价值:
- 提升用户体验:实时提示错误,避免提交后才反馈;
- 降低服务端压力:过滤无效数据,减少无效请求;
- 保证数据合法性:防止恶意数据提交,保障业务逻辑正确。
2.2 Element Plus Form 内置验证:快速上手
Element Plus Form 组件内置了验证规则,基于async-validator实现,无需额外安装依赖,适合快速开发。
2.2.1 核心验证规则详解
| 规则 | 说明 | 示例 |
|---|---|---|
| required | 是否必填 | { required: true } |
| message | 错误提示文案 | {message: ' 必填 '} |
| min/max | 字符串长度 / 数字范围 | { min: 6, max: 18 } |
| pattern | 正则表达式验证 | { pattern: /^1[3-9]\d{9}$/ } |
| validator | 自定义验证函数 | { validator: validatePhone } |
| trigger | 触发验证的事件 | { trigger: 'blur' } |
2.2.2 自定义验证规则(同步 / 异步)
同步验证(如验证两次密码一致):
// 自定义验证函数
const validateConfirmPassword = (rule: any, value: string, callback: Function) => {
if (value === '') {
callback(new Error('请再次输入密码'));
} else if (value !== formData.password) {
callback(new Error('两次输入密码不一致!'));
} else {
callback();
}
};
异步验证(如验证用户名是否已存在):
// 模拟接口请求
const checkUsernameExist = (username: string) => {
return new Promise((resolve) => {
setTimeout(() => {
// 模拟用户名已存在
resolve(username === 'admin');
}, 500);
});
};
// 异步验证函数
const validateUsername = async (rule: any, value: string, callback: Function) => {
if (value === '') {
callback(new Error('请输入用户名'));
} else {
const isExist = await checkUsernameExist(value);
if (isExist) {
callback(new Error('用户名已存在'));
} else {
callback();
}
}
};
2.2.3 完整实战示例:用户注册表单
<template>
<el-form
:model="formData"
:rules="formRules"
ref="formRef"
label-width="120px"
class="register-form"
>
<el-form-item label="用户名" prop="username">
<el-input v-model="formData.username" placeholder="请输入用户名" />
</el-form-item>
<el-form-item label="手机号" prop="phone">
<el-input v-model="formData.phone" placeholder="请输入手机号" />
</el-form-item>
<el-form-item label="密码" prop="password">
<el-input v-model="formData.password" type="password" placeholder="请输入密码" />
</el-form-item>
<el-form-item label="确认密码" prop="confirmPassword">
<el-input v-model="formData.confirmPassword" type="password" placeholder="请再次输入密码" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleSubmit">注册</el-button>
<el-button @click="handleReset">重置</el-button>
</el-form-item>
</el-form>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import type { FormInstance, FormRules } from 'element-plus';
// 表单数据
interface FormData {
username: string;
phone: string;
password: string;
confirmPassword: string;
}
const formData = ref<FormData>({
username: '',
phone: '',
password: '',
confirmPassword: '',
});
// 表单Ref
const formRef = ref<FormInstance>();
// 模拟用户名校验接口
const checkUsernameExist = (username: string) => {
return new Promise((resolve) => {
setTimeout(() => {
resolve(username === 'admin');
}, 500);
});
};
// 自定义验证规则
const validateUsername = async (rule: any, value: string, callback: Function) => {
if (!value) {
callback(new Error('请输入用户名'));
} else {
const isExist = await checkUsernameExist(value);
isExist ? callback(new Error('用户名已存在')) : callback();
}
};
const validateConfirmPassword = (rule: any, value: string, callback: Function) => {
if (!value) {
callback(new Error('请再次输入密码'));
} else if (value !== formData.value.password) {
callback(new Error('两次输入密码不一致'));
} else {
callback();
}
};
// 表单验证规则
const formRules = ref<FormRules>({
username: [
{ validator: validateUsername, trigger: 'blur' },
],
phone: [
{ required: true, message: '请输入手机号', trigger: 'blur' },
{ pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号格式', trigger: 'blur' },
],
password: [
{ required: true, message: '请输入密码', trigger: 'blur' },
{ min: 6, max: 18, message: '密码长度需在6-18位之间', trigger: 'blur' },
],
confirmPassword: [
{ validator: validateConfirmPassword, trigger: 'blur' },
],
});
// 提交表单
const handleSubmit = async () => {
if (!formRef.value) return;
try {
// 触发表单验证
await formRef.value.validate();
// 验证通过,提交数据
console.log('表单验证通过,提交数据:', formData.value);
// 这里可调用接口提交数据
} catch (error) {
console.log('表单验证失败:', error);
}
};
// 重置表单
const handleReset = () => {
if (!formRef.value) return;
formRef.value.resetFields();
};
</script>
<style scoped>
.register-form {
width: 400px;
margin: 20px;
}
</style>
2.3 VeeValidate:更灵活的表单验证方案
VeeValidate 是 Vue3 生态中专门的表单验证库,相比 Element Plus 内置验证,它更灵活、可复用性更高,支持复杂场景(如动态表单、多语言、跨字段验证)。
2.3.1 VeeValidate 核心设计理念
VeeValidate 采用「组件化」设计,核心组件:
Form:表单容器,负责管理整个表单的验证状态;Field:表单字段,绑定验证规则,替代原生 input / 组件;ErrorMessage:错误提示组件,自动显示字段验证错误;useForm:组合式 API,用于手动控制表单验证。
2.3.2 安装与全局配置
安装命令:
# 核心库
pnpm add vee-validate@4
# 内置验证规则(可选,推荐安装)
pnpm add @vee-validate/rules
# 多语言支持(可选)
pnpm add @vee-validate/i18n
全局配置(在main.ts中):
import { createApp } from 'vue'
import App from './App.vue'
// 引入VeeValidate核心组件
import { Form, Field, ErrorMessage, defineRule } from 'vee-validate';
// 引入内置验证规则
import { required, min, max, regex, confirmed } from '@vee-validate/rules';
// 注册内置验证规则
defineRule('required', required);
defineRule('min', min);
defineRule('max', max);
defineRule('regex', regex);
defineRule('confirmed', confirmed);
const app = createApp(App);
// 全局注册组件
app.component('Form', Form);
app.component('Field', Field);
app.component('ErrorMessage', ErrorMessage);
app.mount('#app');
2.3.3 内置规则快速使用
直接在Field组件中通过rules属性绑定规则:
<template>
<Form @submit="handleSubmit">
<div class="form-item">
<label>用户名:</label>
<Field
name="username"
v-model="formData.username"
rules="required|min:3|max:10"
as="el-input"
placeholder="请输入用户名"
/>
<ErrorMessage name="username" class="error" />
</div>
<div class="form-item">
<label>密码:</label>
<Field
name="password"
v-model="formData.password"
rules="required|min:6|max:18"
as="el-input"
type="password"
placeholder="请输入密码"
/>
<ErrorMessage name="password" class="error" />
</div>
<button type="submit">提交</button>
</Form>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const formData = ref({
username: '',
password: '',
});
const handleSubmit = (values: any) => {
console.log('表单数据:', values);
};
</script>
<style scoped>
.form-item {
margin: 10px 0;
display: flex;
flex-direction: column;
width: 300px;
}
.error {
color: #f56c6c;
font-size: 12px;
margin-top: 5px;
}
</style>
2.3.4 自定义验证规则(实战场景)
1)同步自定义规则(验证手机号格式):
import { defineRule } from 'vee-validate';
// 自定义手机号验证规则
defineRule('phone', (value: string) => {
if (!value) {
return '请输入手机号';
}
const reg = /^1[3-9]\d{9}$/;
if (!reg.test(value)) {
return '请输入正确的手机号格式';
}
return true;
});
2)异步自定义规则(验证用户名是否存在):
// 模拟接口请求
const checkUsername = (username: string) => {
return new Promise((resolve) => {
setTimeout(() => {
resolve(username !== 'admin');
}, 500);
});
};
// 自定义异步验证规则
defineRule('usernameUnique', async (value: string) => {
if (!value) {
return '请输入用户名';
}
const isUnique = await checkUsername(value);
if (!isUnique) {
return '用户名已存在';
}
return true;
});
2.3.5 多语言适配:让验证提示更友好
步骤 1:配置多语言
// main.ts
import { createApp } from 'vue'
import App from './App.vue'
import { Form, Field, ErrorMessage, defineRule } from 'vee-validate';
import { required, min, max } from '@vee-validate/rules';
// 引入多语言相关
import { localize, setLocale } from '@vee-validate/i18n';
import zhCN from '@vee-validate/i18n/dist/locale/zh_CN.json';
// 注册规则
defineRule('required', required);
defineRule('min', min);
defineRule('max', max);
// 配置中文
localize({
zh_CN: zhCN,
});
setLocale('zh_CN');
// 注册组件
app.component('Form', Form);
app.component('Field', Field);
app.component('ErrorMessage', ErrorMessage);
app.mount('#app');
步骤 2:使用多语言规则(无需手动写提示文案):
<Field
name="password"
v-model="formData.password"
rules="required|min:6|max:18"
as="el-input"
type="password"
placeholder="请输入密码"
/>
<ErrorMessage name="password" class="error" />
此时错误提示会自动显示中文:「此字段为必填项」「此字段至少包含 6 个字符」等。
2.3.6 完整实战示例:复杂订单表单验证
<template>
<Form @submit="handleSubmit" class="order-form">
<!-- 收货地址 -->
<div class="form-group">
<h4>收货信息</h4>
<div class="form-item">
<label>收货人:</label>
<Field
name="receiver"
v-model="formData.receiver"
rules="required|min:2|max:10"
as="el-input"
placeholder="请输入收货人姓名"
/>
<ErrorMessage name="receiver" class="error" />
</div>
<div class="form-item">
<label>手机号:</label>
<Field
name="phone"
v-model="formData.phone"
rules="required|phone"
as="el-input"
placeholder="请输入手机号"
/>
<ErrorMessage name="phone" class="error" />
</div>
<div class="form-item">
<label>地址:</label>
<Field
name="address"
v-model="formData.address"
rules="required|min:10"
as="el-input"
type="textarea"
placeholder="请输入详细地址"
/>
<ErrorMessage name="address" class="error" />
</div>
</div>
<!-- 支付方式 -->
<div class="form-group">
<h4>支付方式</h4>
<div class="form-item">
<Field
name="payType"
v-model="formData.payType"
rules="required"
as="el-radio-group"
>
<el-radio label="wechat">微信支付</el-radio>
<el-radio label="alipay">支付宝</el-radio>
</Field>
<ErrorMessage name="payType" class="error" />
</div>
</div>
<!-- 备注 -->
<div class="form-item">
<label>备注:</label>
<Field
name="remark"
v-model="formData.remark"
rules="max:100"
as="el-input"
type="textarea"
placeholder="请输入备注(最多100字)"
/>
<ErrorMessage name="remark" class="error" />
</div>
<el-button type="primary" type="submit">提交订单</el-button>
</Form>
</template>
<script setup lang="ts">
import { ref, defineProps } from 'vue';
import { defineRule } from 'vee-validate';
// 自定义手机号规则
defineRule('phone', (value: string) => {
if (!value) return '请输入手机号';
const reg = /^1[3-9]\d{9}$/;
if (!reg.test(value)) return '请输入正确的手机号格式';
return true;
});
// 表单数据
interface FormData {
receiver: string;
phone: string;
address: string;
payType: string;
remark: string;
}
const formData = ref<FormData>({
receiver: '',
phone: '',
address: '',
payType: '',
remark: '',
});
// 提交表单
const handleSubmit = (values: FormData) => {
console.log('订单提交成功:', values);
// 调用接口提交订单
};
</script>
<style scoped>
.order-form {
width: 500px;
margin: 20px;
}
.form-group {
margin: 20px 0;
padding: 10px;
border: 1px solid #e6e6e6;
border-radius: 4px;
}
.form-item {
margin: 10px 0;
display: flex;
flex-direction: column;
}
.error {
color: #f56c6c;
font-size: 12px;
margin-top: 5px;
}
</style>
2.4 两种验证方案对比:什么时候用哪个?
| 维度 | Element Plus Form 内置验证 | VeeValidate |
|---|---|---|
| 依赖 | 无(内置) | 需额外安装 |
| 学习成本 | 低(贴合 Element 组件使用) | 中(需学习专属 API) |
| 灵活性 | 中(适合简单表单) | 高(支持动态表单、跨字段验证) |
| 可复用性 | 低(规则与组件强绑定) | 高(规则可全局注册、复用) |
| 多语言 | 需手动配置 | 内置多语言支持 |
| 适用场景 | 简单表单、快速开发 | 复杂表单、动态表单、企业级项目 |
三、综合实战:UI 组件库 + 表单验证全流程
3.1 需求:搭建带严格验证的用户信息采集表单
- 技术选型:Element Plus(UI) + VeeValidate(验证)
- 核心需求:用户名唯一验证、手机号格式验证、密码强度验证、跨字段验证(两次密码一致)
3.2 完整代码实现与解析
<template>
<div class="container">
<h2>用户信息采集表单</h2>
<Form @submit="onSubmit" class="form">
<!-- 用户名 -->
<el-form-item label="用户名">
<Field
name="username"
v-model="formData.username"
rules="required|min:3|max:10|usernameUnique"
as="el-input"
placeholder="请输入3-10位用户名"
/>
<ErrorMessage name="username" class="error" />
</el-form-item>
<!-- 手机号 -->
<el-form-item label="手机号">
<Field
name="phone"
v-model="formData.phone"
rules="required|phone"
as="el-input"
placeholder="请输入手机号"
/>
<ErrorMessage name="phone" class="error" />
</el-form-item>
<!-- 密码 -->
<el-form-item label="密码">
<Field
name="password"
v-model="formData.password"
rules="required|passwordStrength"
as="el-input"
type="password"
placeholder="请输入密码(含字母+数字,6-18位)"
/>
<ErrorMessage name="password" class="error" />
</el-form-item>
<!-- 确认密码 -->
<el-form-item label="确认密码">
<Field
name="confirmPassword"
v-model="formData.confirmPassword"
rules="required|confirmed:password"
as="el-input"
type="password"
placeholder="请再次输入密码"
/>
<ErrorMessage name="confirmPassword" class="error" />
</el-form-item>
<el-form-item>
<el-button type="primary" type="submit">提交</el-button>
<el-button @click="onReset">重置</el-button>
</el-form-item>
</Form>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { defineRule, useForm } from 'vee-validate';
// 1. 定义自定义验证规则
// 1.1 用户名唯一性验证(异步)
const checkUsernameUnique = async (username: string) => {
// 模拟接口请求
return new Promise((resolve) => {
setTimeout(() => {
// 模拟admin、test用户名已存在
const existUsernames = ['admin', 'test'];
resolve(!existUsernames.includes(username));
}, 500);
});
};
defineRule('usernameUnique', async (value) => {
if (!value) return '请输入用户名';
const isUnique = await checkUsernameUnique(value);
return isUnique ? true : '用户名已存在';
});
// 1.2 手机号验证
defineRule('phone', (value) => {
if (!value) return '请输入手机号';
const reg = /^1[3-9]\d{9}$/;
return reg.test(value) ? true : '请输入正确的手机号格式';
});
// 1.3 密码强度验证
defineRule('passwordStrength', (value) => {
if (!value) return '请输入密码';
if (value.length < 6 || value.length > 18) return '密码长度需在6-18位之间';
const reg = /^(?=.*[a-zA-Z])(?=.*\d).+$/;
return reg.test(value) ? true : '密码需包含字母和数字';
});
// 2. 表单数据
interface FormData {
username: string;
phone: string;
password: string;
confirmPassword: string;
}
const formData = ref<FormData>({
username: '',
phone: '',
password: '',
confirmPassword: '',
});
// 3. 表单方法
const { resetForm } = useForm();
// 提交表单
const onSubmit = (values: FormData) => {
console.log('表单提交成功:', values);
// 实际项目中调用接口提交数据
};
// 重置表单
const onReset = () => {
resetForm();
formData.value = {
username: '',
phone: '',
password: '',
confirmPassword: '',
};
};
</script>
<style scoped>
.container {
width: 600px;
margin: 50px auto;
}
.form {
margin-top: 20px;
}
.error {
color: #f56c6c;
font-size: 12px;
margin-top: 5px;
display: block;
}
</style>
四、总结与进阶建议
4.1 核心总结
- UI 组件库选型:Element Plus 适合快速开发、中小项目;Ant Design Vue 适合大型企业级项目,需平衡学习成本与组件丰富度;
- 表单验证选型:简单表单用 Element Plus 内置验证,复杂表单 / 多语言场景用 VeeValidate;
- 性能优化:UI 组件库务必按需引入,减少打包体积;表单验证规则按需注册,避免全局冗余。
4.2 进阶建议
- 自定义 UI 组件库主题:基于 Element Plus/Ant Design Vue 的主题配置,适配项目品牌风格;
- 封装通用验证规则:将项目中常用的验证规则(如手机号、身份证、邮箱)封装成独立文件,全局引入;
- 结合 TypeScript:为表单数据、验证规则添加完整类型定义,提升代码可维护性;
- 表单状态管理:复杂表单可结合 Pinia 管理表单数据,实现跨组件数据共享。
最后
本文从实战角度讲解了 Vue3 生态中最核心的 UI 组件库和表单验证工具,覆盖安装、使用、优化、选型全流程。如果对你有帮助,欢迎点赞 + 收藏 + 关注,后续会持续更新 Vue3 生态实战内容(如状态管理、路由、打包优化)。
如果有任何问题或不同见解,欢迎在评论区交流哈~

更多推荐

所有评论(0)