256 lines
5.4 KiB
Vue
256 lines
5.4 KiB
Vue
<template>
|
||
<view class="demo-container">
|
||
<view class="demo-title">FormCard 表单组件演示</view>
|
||
|
||
<view class="demo-description">
|
||
<text>✨ 支持姓名和手机号输入,自动过滤非数字字符</text>
|
||
<text>👤 姓名失去焦点时验证,自动去除首尾空格</text>
|
||
<text>📱 手机号失去焦点时验证,支持中国大陆手机号格式</text>
|
||
<text>🎨 优化UI设计,支持悬停效果和动画</text>
|
||
<text>🗑️ 支持删除操作(可配置显示/隐藏)</text>
|
||
<text>📱 响应式设计,适配小屏幕设备</text>
|
||
</view>
|
||
|
||
<!-- 示例1: 基础用法 -->
|
||
<view class="demo-section">
|
||
<view class="section-title">示例1: 基础用法</view>
|
||
<FormCard
|
||
:form="form1"
|
||
title="游客1"
|
||
@update:name="form1.name = $event"
|
||
@update:phone="form1.phone = $event"
|
||
@delete="handleDelete1"
|
||
/>
|
||
<view class="form-data">
|
||
<text>姓名: {{ form1.name }}</text>
|
||
<text>手机号: {{ form1.phone }}</text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 示例2: 自定义标题 -->
|
||
<view class="demo-section">
|
||
<view class="section-title">示例2: 自定义标题</view>
|
||
<FormCard
|
||
:form="form2"
|
||
title="成人票"
|
||
@update:name="form2.name = $event"
|
||
@update:phone="form2.phone = $event"
|
||
@delete="handleDelete2"
|
||
/>
|
||
<view class="form-data">
|
||
<text>姓名: {{ form2.name }}</text>
|
||
<text>手机号: {{ form2.phone }}</text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 示例3: 隐藏删除图标 -->
|
||
<view class="demo-section">
|
||
<view class="section-title">示例3: 隐藏删除图标</view>
|
||
<FormCard
|
||
:form="form3"
|
||
title="联系人信息"
|
||
:show-delete-icon="false"
|
||
@update:name="form3.name = $event"
|
||
@update:phone="form3.phone = $event"
|
||
/>
|
||
<view class="form-data">
|
||
<text>姓名: {{ form3.name }}</text>
|
||
<text>手机号: {{ form3.phone }}</text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 示例4: 多个表单卡片 -->
|
||
<view class="demo-section">
|
||
<view class="section-title">示例4: 多个表单卡片</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 class="add-btn" @click="addForm">添加游客</button>
|
||
|
||
<view class="form-list-data">
|
||
<view class="list-title">表单数据:</view>
|
||
<view v-for="(item, index) in formList" :key="index" class="list-item">
|
||
<text>游客{{ index + 1 }}: {{ item.name }} - {{ item.phone }}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { ref, reactive } from 'vue'
|
||
import FormCard from './index.vue'
|
||
|
||
// 单个表单数据
|
||
const form1 = reactive({
|
||
name: '',
|
||
phone: ''
|
||
})
|
||
|
||
const form2 = reactive({
|
||
name: '张三',
|
||
phone: '13800138000'
|
||
})
|
||
|
||
const form3 = reactive({
|
||
name: '',
|
||
phone: ''
|
||
})
|
||
|
||
// 多个表单数据
|
||
const formList = ref([
|
||
{ name: '', phone: '' },
|
||
{ name: '', phone: '' }
|
||
])
|
||
|
||
// 事件处理
|
||
const handleDelete1 = () => {
|
||
console.log('删除表单1')
|
||
uni.showToast({
|
||
title: '删除表单1',
|
||
icon: 'none'
|
||
})
|
||
}
|
||
|
||
const handleDelete2 = () => {
|
||
console.log('删除表单2')
|
||
uni.showToast({
|
||
title: '删除表单2',
|
||
icon: 'none'
|
||
})
|
||
}
|
||
|
||
const handleDeleteForm = (index) => {
|
||
console.log(`删除表单${index + 1}`)
|
||
formList.value.splice(index, 1)
|
||
uni.showToast({
|
||
title: `删除游客${index + 1}`,
|
||
icon: 'none'
|
||
})
|
||
}
|
||
|
||
const addForm = () => {
|
||
formList.value.push({ name: '', phone: '' })
|
||
uni.showToast({
|
||
title: '添加游客成功',
|
||
icon: 'none'
|
||
})
|
||
}
|
||
</script>
|
||
|
||
<style scoped lang="scss">
|
||
.demo-container {
|
||
padding: 20rpx;
|
||
background-color: #f5f5f5;
|
||
min-height: 100vh;
|
||
}
|
||
|
||
.demo-title {
|
||
font-size: 32rpx;
|
||
font-weight: bold;
|
||
text-align: center;
|
||
margin-bottom: 20rpx;
|
||
color: #333;
|
||
}
|
||
|
||
.demo-description {
|
||
margin-bottom: 40rpx;
|
||
padding: 20rpx;
|
||
background: linear-gradient(135deg, #f0f9ff 0%, #e0f2fe 100%);
|
||
border-radius: 12rpx;
|
||
border: 1px solid #bae6fd;
|
||
|
||
text {
|
||
display: block;
|
||
font-size: 26rpx;
|
||
color: #0369a1;
|
||
margin-bottom: 8rpx;
|
||
line-height: 1.5;
|
||
|
||
&:last-child {
|
||
margin-bottom: 0;
|
||
}
|
||
}
|
||
}
|
||
|
||
.demo-section {
|
||
margin-bottom: 60rpx;
|
||
}
|
||
|
||
.section-title {
|
||
font-size: 28rpx;
|
||
font-weight: 600;
|
||
margin-bottom: 20rpx;
|
||
color: #333;
|
||
border-left: 6rpx solid #00a6ff;
|
||
padding-left: 16rpx;
|
||
}
|
||
|
||
.form-data {
|
||
margin-top: 20rpx;
|
||
padding: 20rpx;
|
||
background: #fff;
|
||
border-radius: 8rpx;
|
||
border: 1px solid #e5e8ef;
|
||
|
||
text {
|
||
display: block;
|
||
font-size: 24rpx;
|
||
color: #666;
|
||
margin-bottom: 8rpx;
|
||
|
||
&:last-child {
|
||
margin-bottom: 0;
|
||
}
|
||
}
|
||
}
|
||
|
||
.add-btn {
|
||
width: 100%;
|
||
height: 80rpx;
|
||
background: #00a6ff;
|
||
color: #fff;
|
||
border: none;
|
||
border-radius: 8rpx;
|
||
font-size: 28rpx;
|
||
margin-top: 20rpx;
|
||
|
||
&:active {
|
||
background: #0056b3;
|
||
}
|
||
}
|
||
|
||
.form-list-data {
|
||
margin-top: 30rpx;
|
||
padding: 20rpx;
|
||
background: #fff;
|
||
border-radius: 8rpx;
|
||
border: 1px solid #e5e8ef;
|
||
}
|
||
|
||
.list-title {
|
||
font-size: 26rpx;
|
||
font-weight: 600;
|
||
color: #333;
|
||
margin-bottom: 16rpx;
|
||
}
|
||
|
||
.list-item {
|
||
margin-bottom: 8rpx;
|
||
|
||
text {
|
||
font-size: 24rpx;
|
||
color: #666;
|
||
}
|
||
|
||
&:last-child {
|
||
margin-bottom: 0;
|
||
}
|
||
}
|
||
</style> |