文章目录
前言
如果你是前端新手,想快速学会用DevUI组件库构建漂亮的表单,这篇文章就是为你准备的。
不需要复杂的理论,只需5分钟,你就能拥有一个完整可用的注册表单。

第一步:创建项目
打开命令行,运行这个命令:
bash
npm create vite my-devui-form -- --template vue
这个命令做的是:
npm create vite- 使用Vite工具创建一个新项目my-devui-form- 项目名称(你可以改成其他名字)--template vue- 使用Vue模板
它会问你几个问题:
Use rolldown-vite?→ 选 No(不用实验性功能)Install with npm?→ 选 Yes(自动安装依赖)
等待安装完成,你会看到:
→ Local: http://localhost:5173/

这说明开发服务器已经启动了!

第二步:安装DevUI
打开新的命令行窗口,进入项目文件夹,输入:
bash
cd my-devui-form
npm i vue-devui @devui-design/icons devui-theme
这个命令安装的是:
vue-devui- DevUI组件库本体,包含所有UI组件@devui-design/icons- DevUI官方提供的图标库devui-theme- 主题系统,支持主题切换和定制
等待安装完成,看到 added XXX packages 就说明成功了。

第三步:配置DevUI
用编辑器(VS Code)打开 my-devui-form 文件夹。
找到 src/main.js 文件,把全部内容替换为如下内容,并保存。
javascript
import { createApp } from 'vue'
import App from './App.vue'
import DevUI from 'vue-devui'
import 'vue-devui/style.css'
import '@devui-design/icons/icomoon/devui-icon.css'
import { ThemeServiceInit, infinityTheme } from 'devui-theme'
// 初始化DevUI主题系统
ThemeServiceInit({ infinityTheme }, 'infinityTheme')
const app = createApp(App)
app.use(DevUI) // 注册DevUI插件,这样就能在模板中使用d-button、d-input等组件了
app.mount('#app') // 挂载到index.html的#app元素

第四步:DevUI表单实现
整体流程图
在开始之前,先看一下表单从创建到提交的完整流程:
┌─────────────────────────────────────────────┐
│ 用户打开表单页面 │
└────────────┬────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────┐
│ 初始化表单数据(ref创建响应式变量) │
│ username: '' │
│ email: '' │
│ gender: 'male' │
│ skills: [] │
└────────────┬────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────┐
│ 页面渲染表单组件 │
│ d-input、d-select、d-radio等 │
│ 通过v-model绑定到数据 │
└────────────┬────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────┐
│ 用户填写表单 │
│ 输入框失焦 → 触发@blur事件 │
│ → 执行验证函数 → 更新errors数据 │
│ → 页面自动显示错误提示 │
└────────────┬────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────┐
│ 用户点击提交按钮 │
│ → 执行submitForm函数 │
│ → 再次验证所有字段 │
│ → 如果都通过,发送数据 │
│ → 显示成功提示 │
└────────────┬────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────┐
│ 表单重置或继续交互 │
└─────────────────────────────────────────────┘
数据流向详解
数据的三个阶段如下图。
┌──────────────────────────────────────────────────┐
│ 第一阶段:数据定义 │
├──────────────────────────────────────────────────┤
│ │
│ const username = ref('') │
│ const email = ref('') │
│ const errors = ref({ │
│ username: '', │
│ email: '' │
│ }) │
│ │
│ 在这个阶段,所有数据都初始化为空状态 │
│ │
└──────────────────────────────────────────────────┘
▼
┌──────────────────────────────────────────────────┐
│ 第二阶段:数据绑定 │
├──────────────────────────────────────────────────┤
│ │
│ <d-input v-model="username" /> │
│ <d-input v-model="email" /> │
│ │
│ 用户在输入框输入 ──────→ username自动更新 │
│ 程序改变username ─────→ 输入框内容自动更新 │
│ │
│ 这就是"双向数据绑定" │
│ │
└──────────────────────────────────────────────────┘
▼
┌──────────────────────────────────────────────────┐
│ 第三阶段:数据验证和处理 │
├──────────────────────────────────────────────────┤
│ │
│ 用户失焦 → validateUsername() 执行 │
│ ↓ │
│ 检查 username 是否为空 │
│ ↓ │
│ 检查长度是否 >= 3 │
│ ↓ │
│ 如果验证失败 → 更新 errors.username │
│ 如果验证成功 → 清空 errors.username │
│ ↓ │
│ 页面自动更新显示错误或清除错误 │
│ │
└──────────────────────────────────────────────────┘
表单验证的核心逻辑
验证规则的设计如下:
javascript
const validateUsername = () => {
// 规则1:必填项
if (!username.value) {
errors.value.username = '用户名不能为空'
return false
}
// 规则2:长度限制
if (username.value.length < 3) {
errors.value.username = '用户名至少3个字符'
return false
}
// 如果通过所有规则
errors.value.username = ''
return true
}
验证规则的执行流程:
输入值 → 检查规则1 → 检查规则2 → 检查规则3... → 返回结果
具体例子:
─────────────────────────────────────────
输入值:''(空)
▼
规则1:if (!username.value) → true(空值判断成立)
▼
立即停止,返回false
错误信息:'用户名不能为空'
不再检查后续规则
─────────────────────────────────────────
输入值:'ab'
▼
规则1:if (!username.value) → false(不为空)
▼
规则2:if (username.value.length < 3) → true(长度为2)
▼
立即停止,返回false
错误信息:'用户名至少3个字符'
不再检查后续规则
─────────────────────────────────────────
输入值:'abc'
▼
规则1:if (!username.value) → false(不为空)
▼
规则2:if (username.value.length < 3) → false(长度为3)
▼
所有规则都通过
▼
返回true
清空错误信息
完整代码如下:
javascript
<template>
<div class="container">
<div class="form-box">
<h1>用户注册表单</h1>
<d-form layout="vertical">
<!-- 用户名 -->
<d-form-item label="用户名">
<d-input
v-model="username"
placeholder="请输入用户名"
/>
<span v-if="errors.username" class="error">{{ errors.username }}</span>
</d-form-item>
<!-- 邮箱 -->
<d-form-item label="邮箱">
<d-input
v-model="email"
placeholder="请输入邮箱"
type="email"
/>
<span v-if="errors.email" class="error">{{ errors.email }}</span>
</d-form-item>
<!-- 密码 -->
<d-form-item label="密码">
<d-input
v-model="password"
placeholder="请输入密码"
type="password"
/>
</d-form-item>
<!-- 部门选择 -->
<d-form-item label="部门">
<d-select
v-model="department"
placeholder="选择部门"
:options="departments"
/>
</d-form-item>
<!-- 性别单选 -->
<d-form-item label="性别">
<d-radio-group v-model="gender" direction="row">
<d-radio value="male">男</d-radio>
<d-radio value="female">女</d-radio>
</d-radio-group>
</d-form-item>
<!-- 技能复选 -->
<d-form-item label="技能">
<d-checkbox-group v-model="skills" direction="row">
<d-checkbox value="Vue">Vue</d-checkbox>
<d-checkbox value="React">React</d-checkbox>
<d-checkbox value="Angular">Angular</d-checkbox>
</d-checkbox-group>
</d-form-item>
<!-- 个人简介 -->
<d-form-item label="个人简介">
<d-textarea
v-model="bio"
placeholder="请输入个人简介"
rows="4"
/>
</d-form-item>
<!-- 按钮 -->
<d-form-item class="button-group">
<d-button
bsStyle="primary"
@click="submitForm"
:loading="isLoading"
>
{{ isLoading ? '提交中...' : '提交' }}
</d-button>
<d-button @click="resetForm">重置</d-button>
</d-form-item>
</d-form>
<!-- 成功提示 -->
<div v-if="showSuccess" class="success">
✅ 提交成功!用户名:{{ username }}
</div>
</div>
</div>
</template>
<script setup>
import { ref, reactive } from 'vue'
// 表单数据
const username = ref('')
const email = ref('')
const password = ref('')
const department = ref('')
const gender = ref('male')
const skills = ref([])
const bio = ref('')
// 部门选项
const departments = [
{ label: '前端部', value: 'frontend' },
{ label: '后端部', value: 'backend' },
{ label: '测试部', value: 'testing' }
]
// 错误信息
const errors = reactive({
username: '',
email: ''
})
// 提交状态
const isLoading = ref(false)
const showSuccess = ref(false)
// 验证用户名
const validateUsername = () => {
if (!username.value) {
errors.username = '用户名不能为空'
return false
}
if (username.value.length < 3) {
errors.username = '用户名至少3个字符'
return false
}
errors.username = ''
return true
}
// 验证邮箱
const validateEmail = () => {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
if (!email.value) {
errors.email = '邮箱不能为空'
return false
}
if (!emailRegex.test(email.value)) {
errors.email = '邮箱格式不正确'
return false
}
errors.email = ''
return true
}
// 提交表单
const submitForm = async () => {
if (!validateUsername() || !validateEmail()) {
return
}
isLoading.value = true
try {
// 模拟提交延迟
await new Promise(resolve => setTimeout(resolve, 1500))
showSuccess.value = true
console.log('表单数据:', {
username: username.value,
email: email.value,
password: password.value,
department: department.value,
gender: gender.value,
skills: skills.value,
bio: bio.value
})
// 2秒后隐藏成功提示
setTimeout(() => {
showSuccess.value = false
}, 2000)
} finally {
isLoading.value = false
}
}
// 重置表单
const resetForm = () => {
username.value = ''
email.value = ''
password.value = ''
department.value = ''
gender.value = 'male'
skills.value = []
bio.value = ''
errors.username = ''
errors.email = ''
showSuccess.value = false
}
</script>
<style scoped>
.container {
min-height: 100vh;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
display: flex;
align-items: center;
justify-content: center;
padding: 20px;
}
.form-box {
background: white;
border-radius: 12px;
padding: 40px;
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
max-width: 500px;
width: 100%;
}
h1 {
text-align: center;
margin: 0 0 30px 0;
color: #333;
font-size: 1.8rem;
}
.error {
display: block;
color: #f56c6c;
font-size: 0.85rem;
margin-top: 5px;
}
.button-group {
display: flex;
gap: 10px;
margin-top: 20px;
}
.button-group :deep(.d-btn) {
flex: 1;
}
.success {
margin-top: 20px;
padding: 16px;
background: #f0f9ff;
border-left: 4px solid #4caf50;
border-radius: 4px;
color: #333;
font-weight: 600;
text-align: center;
}
:deep(.d-form-item) {
margin-bottom: 20px;
}
</style>
在浏览器中访问 http://localhost:5173,你会看到一个完整的注册表单!

常见问题
页面不显示?
检查浏览器控制台(按F12)是否有错误。最常见原因是:
- 没有安装DevUI依赖
bash
npm i vue-devui @devui-design/icons devui-theme
-
main.js配置有误 - 检查是否正确导入并使用了DevUI
-
打字错误 - 确保组件名称正确,比如
d-input不要写成d-Input
验证不工作?
确保:
- 函数名称正确
javascript
const validateUsername = () => {
// 验证逻辑
}
- 正确绑定了事件
vue
<d-input @blur="validateUsername" /> <!-- 不要忘记括号 -->
- 错误信息对象存在
javascript
const errors = ref({
username: '', // 必须有这个字段
email: ''
})
想修改样式?
在 <style scoped> 中修改CSS:
css
/* 改背景色 */
.form-box {
background: #f5f5f5;
}
/* 改内边距 */
.form-box {
padding: 50px;
}
/* 改标题颜色 */
h1 {
color: #667eea;
}
想添加新字段?
只需3步:
第1步: 在 <script setup> 中定义数据
javascript
const phone = ref('') // 添加手机号字段
第2步: 在表单中添加输入框
vue
<d-form-item label="手机号">
<d-input v-model="phone" placeholder="请输入手机号" />
</d-form-item>
第3步: 在提交时使用这个数据
javascript
console.log('手机号:', phone.value)
如何连接真实后端?
修改提交函数,使用 fetch 或 axios 调用后端API:
javascript
const submitForm = async () => {
// 验证代码...
isLoading.value = true
try {
// 调用后端接口
const response = await fetch('/api/register', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
username: username.value,
email: email.value,
password: password.value,
department: department.value,
gender: gender.value,
skills: skills.value,
bio: bio.value
})
})
const data = await response.json()
if (response.ok) {
showSuccess.value = true
console.log('注册成功!', data)
} else {
alert('注册失败:' + data.message)
}
} catch (error) {
alert('出错了:' + error.message)
} finally {
isLoading.value = false
}
}
总结
通过本文,可以快速掌握DevUI表单的完整实现逻辑:数据响应化 --- 用ref()创建响应式数据自动更新页面;事件驱动验证 --- 通过@blur、@click触发验证逻辑;UI动态反馈 --- 根据验证结果显示错误或成功提示。这三层工作流不仅适用于简单表单,也是构建复杂管理系统的基础。接下来,跟着小编开始实践吧!
MateChat:https://gitcode.com/DevCloudFE/MateChat
MateChat官网:https://matechat.gitcode.com
DevUI官网:https://devui.design/home
