feat: 商品详情交互开发
This commit is contained in:
461
components/FormCard/README.md
Normal file
461
components/FormCard/README.md
Normal file
@@ -0,0 +1,461 @@
|
||||
# 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
|
||||
Reference in New Issue
Block a user