Files
YGChatCS/components/FormCard/README.md
2025-08-03 18:06:06 +08:00

461 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# FormCard 表单卡片组件
一个功能完整的表单卡片组件,支持姓名和手机号输入,具备数据验证和双向绑定功能。
## 功能特性
- 📝 **双向绑定**:支持 v-model 双向数据绑定
-**数据验证**:内置手机号格式验证
- 🎨 **自定义标题**:可配置游客标题文本
- 🗑️ **删除功能**:支持删除操作,可配置显示/隐藏
- 💫 **交互反馈**:输入框聚焦效果和错误状态提示
- 📱 **响应式设计**:适配不同屏幕尺寸
- 🎯 **事件支持**:完整的事件系统
-**性能优化**:使用计算属性优化渲染
## 基础用法
### 默认使用
```vue
<template>
<FormCard
:form="form"
@update:name="form.name = $event"
@update:phone="form.phone = $event"
@delete="handleDelete"
/>
</template>
<script setup>
import { reactive } from 'vue'
import FormCard from '@/components/FormCard/index.vue'
const form = reactive({
name: '',
phone: ''
})
const handleDelete = () => {
console.log('删除表单')
}
</script>
```
### 自定义标题
```vue
<template>
<FormCard
:form="form"
title="成人票"
@update:name="form.name = $event"
@update:phone="form.phone = $event"
@delete="handleDelete"
/>
</template>
```
### 隐藏删除图标
```vue
<template>
<FormCard
:form="form"
title="联系人信息"
:show-delete-icon="false"
@update:name="form.name = $event"
@update:phone="form.phone = $event"
/>
</template>
```
### 多个表单卡片
```vue
<template>
<view>
<FormCard
v-for="(item, index) in formList"
:key="index"
:form="item"
:title="`游客${index + 1}`"
@update:name="item.name = $event"
@update:phone="item.phone = $event"
@delete="handleDeleteForm(index)"
/>
<button @click="addForm">添加游客</button>
</view>
</template>
<script setup>
import { ref } from 'vue'
const formList = ref([
{ name: '', phone: '' },
{ name: '', phone: '' }
])
const handleDeleteForm = (index) => {
formList.value.splice(index, 1)
}
const addForm = () => {
formList.value.push({ name: '', phone: '' })
}
</script>
```
### 表单验证
```vue
<template>
<FormCard
ref="formCardRef"
:form="form"
title="验证示例"
@update:name="form.name = $event"
@update:phone="form.phone = $event"
/>
<button @click="validateForm">验证表单</button>
</template>
<script setup>
import { ref, reactive } from 'vue'
const formCardRef = ref()
const form = reactive({
name: '',
phone: ''
})
const validateForm = () => {
// 手动触发验证
formCardRef.value.validateName()
formCardRef.value.validatePhone()
// 或者使用工具函数检查
const nameError = formCardRef.value.getNameError(form.name)
const phoneError = formCardRef.value.getPhoneError(form.phone)
if (!nameError && !phoneError) {
console.log('表单验证通过')
}
}
</script>
```
## API 文档
### Props
| 参数 | 类型 | 默认值 | 说明 |
|------|------|--------|---------|
| title | String | "游客1" | 表单卡片标题 |
| form | Object | `{ name: '', phone: '' }` | 表单数据对象,包含 name 和 phone 字段 |
| form.name | String | "" | 姓名值 |
| form.phone | String | "" | 手机号值 |
| showDeleteIcon | Boolean | true | 是否显示删除图标 |
### Events
| 事件名 | 参数 | 说明 |
|--------|------|------|
| update:name | (value: string) | 姓名值更新时触发,自动去除首尾空格 |
| update:phone | (value: string) | 手机号值更新时触发,自动过滤非数字字符 |
| delete | - | 点击删除图标时触发 |
### Methods (通过 ref 调用)
| 方法名 | 参数 | 返回值 | 说明 |
|--------|------|--------|---------|
| validateName | - | void | 手动触发姓名验证 |
| validatePhone | - | void | 手动触发手机号验证 |
| getNameError | (name: string) | string | 获取姓名验证错误信息 |
| getPhoneError | (phone: string) | string | 获取手机号验证错误信息 |
### 数据验证
组件内置完整的表单验证:
- **姓名验证**:不能为空,自动去除首尾空格
- **手机号验证**支持中国大陆手机号格式1开头第二位为3-9总长度11位
- **失焦验证**:只在输入框失去焦点时进行验证,避免输入干扰
- **错误提示**:验证失败时显示错误信息,带有淡入动画效果
- **视觉反馈**:输入框边框变红提示错误状态
- **自动过滤**:手机号输入时自动过滤非数字字符
## 样式定制
### CSS 变量系统
组件使用 CSS 变量系统,支持主题定制:
```scss
:root {
--form-primary-color: #00a6ff; // 主色调
--form-error-color: #ff4d4f; // 错误色
--form-text-color: #333; // 文本色
--form-label-color: #86909c; // 标签色
--form-border-color: #e5e8ef; // 边框色
--form-input-border-color: #ddd; // 输入框边框色
--form-bg-color: #fff; // 背景色
--form-header-bg-color: rgba(25, 144, 255, 0.06); // 头部背景色
--form-border-radius: 8px; // 圆角大小
--form-transition: all 0.2s ease; // 过渡动画
}
```
### 主要样式类
```scss
.form-wrapper {
// 表单容器,支持悬停效果和阴影
}
.form-header {
// 表单头部,包含标题和删除按钮
}
.form-title {
// 标题文本,支持文本溢出省略
}
.form-item {
// 表单项容器,支持分隔线
}
.form-input {
// 输入框,支持聚焦和错误状态
}
.form-error {
// 错误信息,带有淡入动画
}
```
### 响应式设计
组件内置响应式支持,在小屏幕设备上自动调整:
- 320px 以下设备优化布局
- 自动调整字体大小和间距
- 保持良好的可用性
### 自定义主题
通过覆盖 CSS 变量来自定义主题:
```scss
// 自定义主题色
:root {
--form-primary-color: #your-primary-color;
--form-error-color: #your-error-color;
--form-border-radius: 12px;
}
// 或者针对特定组件
.your-custom-form {
--form-primary-color: #your-primary-color;
--form-header-bg-color: rgba(your-color, 0.1);
}
```
## 高级用法
### 表单验证集成
```vue
<template>
<FormCard
ref="formCardRef"
:form="form"
title="游客信息"
@update:name="form.name = $event"
@update:phone="form.phone = $event"
@delete="handleDelete"
/>
<button @click="validateForm">提交</button>
</template>
<script setup>
import { reactive, ref } from 'vue'
const formCardRef = ref()
const form = reactive({
name: '',
phone: ''
})
const validateForm = () => {
// 使用组件内置的验证方法
const nameError = formCardRef.value.getNameError(form.name)
const phoneError = formCardRef.value.getPhoneError(form.phone)
if (nameError) {
uni.showToast({
title: nameError,
icon: 'none'
})
return
}
if (phoneError) {
uni.showToast({
title: phoneError,
icon: 'none'
})
return
}
// 提交表单
console.log('表单数据:', form)
}
</script>
```
### 动态表单管理
```vue
<template>
<view>
<FormCard
v-for="(item, index) in passengers"
:key="item.id"
:form="item"
@update:name="item.name = $event"
@update:phone="item.phone = $event"
:title="getPassengerTitle(item.type, index)"
:show-delete-icon="passengers.length > 1"
@delete="removePassenger(index)"
/>
<view class="action-buttons">
<button @click="addAdult">添加成人</button>
<button @click="addChild">添加儿童</button>
</view>
</view>
</template>
<script setup>
import { ref } from 'vue'
const passengers = ref([
{ id: 1, type: 'adult', name: '', phone: '' }
])
let nextId = 2
const getPassengerTitle = (type, index) => {
return type === 'adult' ? `成人${index + 1}` : `儿童${index + 1}`
}
const addAdult = () => {
passengers.value.push({
id: nextId++,
type: 'adult',
name: '',
phone: ''
})
}
const addChild = () => {
passengers.value.push({
id: nextId++,
type: 'child',
name: '',
phone: ''
})
}
const removePassenger = (index) => {
if (passengers.value.length > 1) {
passengers.value.splice(index, 1)
}
}
</script>
```
## 注意事项
1. **数据传递**:使用 `:form` 对象传递数据,包含 `name``phone` 字段
2. **双向绑定**:通过 `@update:name``@update:phone` 事件进行双向绑定
3. **验证机制**:只在失去焦点时进行验证,避免输入干扰
4. **手机号验证**仅支持中国大陆手机号格式验证1开头第二位3-9总长度11位
5. **自动处理**:手机号自动过滤非数字字符,姓名自动去除首尾空格
6. **删除功能**:删除事件需要父组件处理具体逻辑
7. **方法调用**:通过 `ref` 可调用组件内部的验证方法
8. **兼容性**支持微信小程序、H5、App等平台
## 更新日志
### v1.3.0 (2024-12-19)
**性能与可维护性全面优化**
- 🚀 **性能优化**:提取常量定义,优化计算属性逻辑
- 🛠️ **代码重构**:添加完整的 JSDoc 注释和类型定义
- 🎨 **样式升级**:使用 CSS 变量系统,支持主题定制
-**功能增强**:手机号自动过滤非数字字符,姓名自动去除空格
- 🎭 **UI 改进**:新增悬停效果、错误信息动画和阴影效果
- 📱 **响应式设计**:优化小屏幕设备适配
- 🔧 **开发体验**:添加 defineExpose 暴露验证方法,便于测试
- 📝 **文档完善**:更新演示和使用说明
### v1.2.3 (2024-12-19)
**优化验证行为**
- 🎨 优化验证行为,移除实时验证
- ✨ 姓名和手机号只在失去焦点时进行验证
- 🔧 移除不必要的 watch 监听器
- 📝 更新文档和演示说明
- ⚡ 提升组件性能和用户体验
### v1.2.2 (2024-12-19)
**新增姓名验证功能**
- ✨ 新增姓名非空验证功能
- 👤 姓名为空时显示"请输入姓名"提示
- 🔄 支持姓名实时验证,输入内容时错误信息自动隐藏
- 🎯 完善表单验证体系,提升数据完整性
- 💫 优化用户体验,提供友好的输入提示
### v1.2.1 (2024-12-19)
**优化手机号验证功能**
- 🐛 修复validatePhone方法中props引用错误的问题
- ✨ 新增手机号实时验证功能
- 🔄 输入正确手机号时错误信息自动隐藏
- 📱 优化用户输入体验,提供即时反馈
- 🎯 完善demo页面增加功能说明
### v1.2.0 (2024-12-19)
**新增删除功能**
- ✨ 支持删除表单卡片
- 🎯 可配置删除图标显示/隐藏
- 🔄 完善事件系统支持delete事件
- 💫 优化用户交互体验
### v2.0.0
- ✨ 重构组件,支持 props 传值和双向绑定
- ✨ 新增 `title` 属性,支持自定义标题
- ✨ 新增 `showDeleteIcon` 属性,控制删除图标显示
- ✨ 新增完整的事件系统update:name, update:phone, delete
- 🎨 优化样式,新增错误状态和交互效果
- 🔧 改进手机号验证逻辑
- 📝 新增完整的文档和演示示例
### v1.0.0
- 🎉 初始版本发布
- ✨ 基础表单功能
- ✨ 手机号验证
- ✨ 基础样式
## 技术栈
- Vue 3 Composition API
- SCSS
- uni-app
## 浏览器支持
- 微信小程序
- H5 (Chrome, Firefox, Safari, Edge)
- App (iOS, Android)
## 许可证
MIT License