<template>
<div class="component-card-demo-wrap form-demo-base">
<TsForm :model="formData" :rules="rules" ref="mainFormRef" labelWidth="80">
<TsFormItem label="Username" prop="username" required>
<TsInput v-model="formData.username" placeholder="Enter username" />
</TsFormItem>
<TsFormItem label="Password" prop="password" required>
<TsInput v-model="formData.password" type="password" placeholder="Enter password" />
</TsFormItem>
<TsFormItem label="Email" prop="email">
<TsInput v-model="formData.email" placeholder="Enter email" />
</TsFormItem>
<TsFormItem label="Gender" prop="gender">
<TsSelect v-model="formData.gender" :options="genderOption" placeholder="Select gender" />
</TsFormItem>
<TsFormItem label="Date" prop="date">
<TsDatePicker v-model="formData.date" :placeholders="['Select start date', 'Select end date']" clearable />
</TsFormItem>
<TsFormItem label="Time" prop="time">
<TsTimePicker v-model="formData.time" placeholder="Select time" />
</TsFormItem>
<TsFormItem label="Options" prop="options">
<TsCheckboxGroup v-model="formData.options">
<TsCheckbox label="Option 1" value="option1">选项1</TsCheckbox>
<TsCheckbox label="Option 2" value="option2">选项2</TsCheckbox>
<TsCheckbox label="Option 3" value="option3">选项3</TsCheckbox>
</TsCheckboxGroup>
</TsFormItem>
<TsFormItem label="Choice" prop="choice">
<TsRadioGroup v-model="formData.choice">
<TsRadio label="Choice 1" value="choice1">选项1</TsRadio>
<TsRadio label="Choice 2" value="choice2">选项2</TsRadio>
<TsRadio label="Choice 3" value="choice3">选项3</TsRadio>
</TsRadioGroup>
</TsFormItem>
<TsFormItem label="Agree" prop="agree">
<TsSwitch v-model="formData.agree" placeholder="Choose agree" />
</TsFormItem>
<TsFormItem>
<TsButton type="primary" @click="handleMainSubmit">Submit</TsButton>
<TsButton @click="resetMainForm" style="margin-left: 10px">Reset</TsButton>
</TsFormItem>
</TsForm>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import {
TsButton,
TsCheckbox,
TsCheckboxGroup,
TsDatePicker,
TsForm,
TsFormItem,
TsInput,
TsRadio,
TsRadioGroup,
TsSelect,
TsSwitch,
TsTimePicker,
} from 'tui';
import type { FormRules } from 'tui/components/form/src/types';
import type { TsFormInstance } from 'tui/components/form';
const formData = ref({
username: '',
password: '',
email: '',
date: [],
time: '',
options: [],
choice: '',
gender: '',
agree: false,
});
const genderOption = [
{ label: 'men', value: 'men' },
{ label: 'women', value: 'women' },
];
const rules = ref<FormRules>({
username: [
{ required: true, message: 'Please input username', trigger: 'blur' },
{ min: 3, max: 11, message: 'Length should be 3 to 11', trigger: 'blur' },
],
password: [
{ required: true, message: 'Please input password', trigger: 'blur' },
{ min: 6, message: 'At least 6 characters', trigger: 'blur' },
],
email: [{ type: 'email', message: 'Please input correct email', trigger: 'blur' }],
gender: [{ required: true, message: 'Please select gender', trigger: 'change' }],
date: [{ required: true, message: 'Please select a date', trigger: 'change' }],
time: [{ required: true, message: 'Please select a time', trigger: 'change' }],
options: [{ type: 'array', required: true, message: 'Please select at least one option', trigger: 'change' }],
choice: [{ required: true, message: 'Please select a choice', trigger: 'change' }],
});
const mainFormRef = ref<TsFormInstance | null>(null);
const handleMainSubmit = async () => {
await mainFormRef.value?.validate();
};
const resetMainForm = () => {
mainFormRef.value?.resetFields();
};
</script>
<style scoped>
.form-demo-base {
padding: 20px 0;
width: 500px;
}
</style>
inline 使表单项横向排列,适用于搜索和筛选场景。<template>
<div class="component-card-demo-wrap">
<TsForm :model="formData" :rules="rules" ref="searchFormRef" inline>
<TsFormItem label="Username" prop="username" required>
<TsInput v-model="formData.username" placeholder="Enter username" clearable />
</TsFormItem>
<TsFormItem label="Password" prop="password" required>
<TsInput v-model="formData.password" type="password" placeholder="Enter password" />
</TsFormItem>
<TsFormItem label="Email" prop="email">
<TsInput v-model="formData.email" placeholder="Enter email" />
</TsFormItem>
<TsFormItem>
<TsButton type="primary" :loading="searchLoading" @click="handleSearch">Search</TsButton>
<TsButton @click="handleResetSearch" style="margin-left: 10px">Reset</TsButton>
</TsFormItem>
</TsForm>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { TsButton, TsForm, TsFormItem, TsInput, TsToast } from 'tui';
import type { FormRules } from 'tui/components/form/src/types';
import type { TsFormInstance } from 'tui/components/form';
const rules = ref<FormRules>({
username: [{ required: true, message: 'Please enter username', trigger: 'blur' }],
password: [{ required: true, message: 'Please enter password', trigger: 'blur' }],
email: [{ type: 'email', message: 'Please enter a valid email', trigger: 'blur' }],
});
const formData = ref({
username: '',
password: '',
email: '',
});
const searchFormRef = ref<TsFormInstance | null>(null);
const searchLoading = ref(false);
const handleSearch = () => {
if (!searchFormRef.value || searchLoading.value) return;
searchFormRef.value.validate().then((validated) => {
if (!validated) return;
searchLoading.value = true;
setTimeout(() => {
TsToast({ message: '搜索成功', type: 'success' });
searchLoading.value = false;
}, 2000);
});
};
const handleResetSearch = () => {
searchFormRef.value?.resetFields();
};
</script>
labelPosition 控制标签位置,适合需要更清晰布局的场景。<template>
<div class="component-card-demo-wrap form-demo-position">
<TsForm :model="formData" :rules="rules" ref="formRef" labelPosition="top">
<TsFormItem label="Username" prop="username" required>
<TsInput v-model="formData.username" placeholder="Enter username" />
</TsFormItem>
<TsFormItem label="Password" prop="password" required>
<TsInput v-model="formData.password" type="password" placeholder="Enter password" />
</TsFormItem>
<TsFormItem label="Email" prop="email">
<TsInput v-model="formData.email" placeholder="Enter email" />
</TsFormItem>
<TsFormItem label="Gender" prop="gender">
<TsSelect v-model="formData.gender" :options="genderOption" placeholder="Select gender" />
</TsFormItem>
<TsFormItem label="Agree" prop="agree">
<TsSwitch v-model="formData.agree" placeholder="Choose agree" />
</TsFormItem>
<TsFormItem>
<TsButton type="primary" @click="handleSubmit">Submit</TsButton>
<TsButton @click="resetForm" style="margin-left: 10px">Reset</TsButton>
</TsFormItem>
</TsForm>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { TsButton, TsForm, TsFormItem, TsInput, TsSelect, TsSwitch } from 'tui';
import type { FormRules } from 'tui/components/form/src/types';
import type { TsFormInstance } from 'tui/components/form';
const rules = ref<FormRules>({
username: [{ required: true, message: 'Please enter username', trigger: 'blur' }],
password: [{ required: true, message: 'Please enter password', trigger: 'blur' }],
email: [{ type: 'email', message: 'Please enter a valid email', trigger: 'blur' }],
});
const formData = ref({
username: '',
password: '',
email: '',
gender: '',
agree: false,
});
const genderOption = [
{ label: 'men', value: 'men' },
{ label: 'women', value: 'women' },
];
const formRef = ref<TsFormInstance | null>(null);
const handleSubmit = async () => {
try {
await formRef.value?.validate();
console.log('Form submitted:', formData.value);
} catch (error) {
console.error('Form validation failed:', error);
}
};
const resetForm = () => {
formRef.value?.resetFields();
formRef.value?.clearValidate();
};
</script>
<style scoped>
.form-demo-position {
width: 600px;
padding: 16px;
border: 1px solid #a8a8a873;
border-radius: 2px;
}
</style>