vue3+ts实现一个表单组件

1. 创建表单组件

首先,创建一个表单组件,包括姓名、手机号、年龄、学校、性别等基本信息的输入框,并添加省市区和街道地点的选择功能。

<template>
  <form @submit.prevent="submitForm">
    <el-form :model="formData" :rules="formRules" ref="formData" label-width="100px">
      <el-form-item label="姓名" prop="name">
        <el-input v-model="formData.name"></el-input>
      </el-form-item>
      <el-form-item label="手机号" prop="phone">
        <el-input v-model="formData.phone"></el-input>
      </el-form-item>
      <el-form-item label="年龄" prop="age">
        <el-input v-model.number="formData.age"></el-input>
      </el-form-item>
      <el-form-item label="学校" prop="school">
        <el-input v-model="formData.school"></el-input>
      </el-form-item>
      <el-form-item label="性别" prop="gender">
        <el-radio-group v-model="formData.gender">
          <el-radio label="male"></el-radio>
          <el-radio label="female"></el-radio>
        </el-radio-group>
      </el-form-item>
      <el-form-item label="地点" prop="location">
        <el-radio-group v-model="locationType">
          <el-radio :label="'district'" @change="handleLocationTypeChange">省市区</el-radio>
          <el-radio :label="'street'" @change="handleLocationTypeChange">街道</el-radio>
        </el-radio-group>
        <div v-if="locationType === 'district'">
          <!-- 展示省市区组件 -->
          <el-cascader
            v-model="formData.district"
            :options="districtOptions"
            @change="handleDistrictChange"
            placeholder="请选择省市区"
          ></el-cascader>
        </div>
        <div v-else-if="locationType === 'street'">
          <!-- 展示街道多选组件 -->
          <el-select
            v-model="formData.street"
            multiple
            filterable
            remote
            reserve-keyword
            :remote-method="loadStreets"
            placeholder="请输入街道名称"
          ></el-select>
        </div>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" native-type="submit">提交</el-button>
      </el-form-item>
    </el-form>
  </form>
</template>

<script setup lang="ts">
import { ref } from 'vue';
import axios from 'axios';

const formData = ref({
  name: '',
  phone: '',
  age: undefined,
  school: '',
  gender: 'male', // 默认选项
  district: [], // 省市区选择结果
  street: [], // 街道选择结果(多选)
});

const formRules = ref({
  name: [{ required: true, message: '请输入姓名', trigger: 'blur' }],
  phone: [
    { required: true, message: '请输入手机号', trigger: 'blur' },
    { pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号', trigger: 'blur' },
  ],
  age: [
    { required: true, message: '请输入年龄', trigger: 'blur' },
    { type: 'number', min: 1, max: 150, message: '请输入1-150之间的数字', trigger: 'blur' },
  ],
  school: [{ required: true, message: '请输入学校名称', trigger: 'blur' }],
  gender: [{ required: true, message: '请选择性别', trigger: 'change' }],
  district: [{ required: true, message: '请选择省市区', trigger: 'change' }],
  street: [{ required: true, message: '请选择街道', trigger: 'change' }],
});

const locationType = ref('district'); // 默认选择省市区

const districtOptions = ref([]); // 省市区选项

// 加载街道列表
const loadStreets = async (query: string) => {
  try {
    const response = await axios.get(`/api/streets?query=${query}`);
    return response.data.streets.map((street: any) => ({
      label: street.name,
      value: street.id,
    }));
  } catch (error) {
    console.error('Error loading streets:', error);
    return [];
  }
};

// 处理地点类型变化
const handleLocationTypeChange = () => {
  // 清空之前选择的值
  formData.street = [];
};

// 处理省市区选择变化
const handleDistrictChange = () => {
  // 根据选择的省市区加载街道数据(这里可以根据实际需求进行调整)
};

// 提交表单
const submitForm = async () => {
  try {
    await $refs.formData.validate();
    if (formData.value.locationType === 'district') {
      // 处理省市区数据
    } else if (formData.value.locationType === 'street') {
      // 处理街道数据
    }
    // 提交表单逻辑,例如调用后端接口
    console.log('Form data:', formData.value);
    // 使用 axios 发送表单数据到后端
    await axios.post('/api/submit', formData.value);
  } catch (error) {
    console.error('Submit error:', error);
  }
};
</script>

2. 实现数据加载和交互逻辑

在上述代码中,使用了Vue 3的Composition API结合TypeScript来管理表单数据、验证规则、组件交互等。

  • formData: 表单数据对象,包括姓名、手机号、年龄、学校、性别、省市区、街道等字段。
  • formRules: 表单验证规则,确保必填字段不能为空且格式正确。
  • locationType: 控制显示省市区选择还是街道选择的组件。
  • districtOptions: 省市区选项数据,通过后端接口获取。
  • loadStreets: 异步加载街道列表的方法,支持搜索功能。
  • handleLocationTypeChange: 处理地点类型变化的方法,清空街道选择数据。
  • handleDistrictChange: 处理省市区选择变化的方法,可以根据选择的省市区加载对应的街道数据。
  • submitForm: 提交表单的方法,包括表单验证和实际数据提交到后端接口。

3. 数据加载和提交

确保通过axios调用后端接口来获取省市区和街道数据,并在选择省市区时加载相应的街道数据。在提交表单时,将表单数据以JSON格式发送到后端处理。

相关推荐

  1. vue3+ts实现一个组件

    2024-07-11 15:24:03       22 阅读
  2. 使用vue3+ts封装一个Slider滑块组件

    2024-07-11 15:24:03       21 阅读
  3. 使用vue3+ts封装一个Switch开关组件

    2024-07-11 15:24:03       26 阅读
  4. vue2 elementui 封装一个动态复杂组件

    2024-07-11 15:24:03       41 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-11 15:24:03       53 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-11 15:24:03       56 阅读
  3. 在Django里面运行非项目文件

    2024-07-11 15:24:03       46 阅读
  4. Python语言-面向对象

    2024-07-11 15:24:03       57 阅读

热门阅读

  1. LeetCode K次取反后最大化的数组和(贪心算法)

    2024-07-11 15:24:03       16 阅读
  2. 力扣3148.矩阵中的最大得分

    2024-07-11 15:24:03       18 阅读
  3. AtCoder Beginner Contest 359

    2024-07-11 15:24:03       17 阅读
  4. [NOIP2005 提高组] 篝火晚会(含代码)

    2024-07-11 15:24:03       20 阅读
  5. react获取访问过的路由历史记录

    2024-07-11 15:24:03       20 阅读
  6. 编程范式实现思路介绍

    2024-07-11 15:24:03       18 阅读
  7. 表单验证的艺术:WebKit 支持 HTML 表单的全面解析

    2024-07-11 15:24:03       17 阅读
  8. Android --- Kotlin学习之路:基础语法学习笔记

    2024-07-11 15:24:03       20 阅读
  9. 智能制造热点词汇科普篇——工业微服务

    2024-07-11 15:24:03       21 阅读
  10. C++中的模板(二)

    2024-07-11 15:24:03       20 阅读
  11. slf4j日志框架和logback详解

    2024-07-11 15:24:03       19 阅读
  12. Redis的配置和优化

    2024-07-11 15:24:03       18 阅读