vue3中form表单层级嵌套问题的解决详解

 更新时间:2025年05月20日 09:03:32   作者:拉不动的猪  
这篇文章主要为大家详细介绍了vue3中form表单层级嵌套问题的相关解决方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下

先上代码

parent.vue

<script setup>
import { ref, reactive } from "vue";
import TaskList from "./ChildForm.vue";

const formRef = ref();
const formData = reactive({
  projectName: "",
  manager: "",
  tasks: [],
});

const rules = reactive({
  projectName: [
    { required: true, message: "项目名称不能为空", trigger: "blur" },
    { min: 3, max: 50, message: "长度在3到50个字符", trigger: "blur" },
  ],
  manager: [{ required: true, message: "负责人不能为空", trigger: "change" }],
});

const validateTasks = (rule, value, callback) => {
  if (formData.tasks.length === 0) {
    callback(new Error("至少需要添加一个任务"));
  } else {
    callback();
  }
};

const submit = () => {
  formRef.value.validate((valid) => {
    if (valid) {
      console.log("提交数据:", formData);
    }
  });
};
</script>

<template>
  <el-form ref="formRef" :model="formData" :rules="rules" label-width="120px">
    <el-form-item label="项目名称" prop="projectName">
      <el-input v-model="formData.projectName" />
    </el-form-item>

    <el-form-item label="负责人" prop="manager">
      <el-select v-model="formData.manager">
        <el-option label="张三" value="zhangsan" />
        <el-option label="李四" value="lisi" />
      </el-select>
    </el-form-item>

    <el-form-item prop="tasks" :rules="[{ validator: validateTasks }]">
      <TaskList v-model="formData.tasks" />
    </el-form-item>

    <el-button type="primary" @click="submit">提交</el-button>
  </el-form>
</template>

child.vue

<script setup>
import { ref, computed, reactive } from "vue";

const props = defineProps({
  modelValue: {
    type: Array,
    default: () => [],
  },
});

const emit = defineEmits(["update:modelValue"]);

const taskRules = reactive({
  name: [{ required: true, message: "任务名称不能为空", trigger: "blur" }],
  priority: [{ required: true, message: "请选择优先级", trigger: "change" }],
});

const tasks = computed({
  get: () => props.modelValue,
  set: (value) => emit("update:modelValue", value),
});

const addTask = () => {
  tasks.value.push({ name: "", priority: "medium" });
};

const removeTask = (index) => {
  tasks.value.splice(index, 1);
};
</script>

<template>
  <div class="task-list">
    <el-button @click="addTask">添加任务</el-button>

    <el-form
      v-for="(task, index) in tasks"
      :key="index"
      :model="task"
      :rules="taskRules"
      class="task-form"
    >
      <el-form-item prop="name">
        <el-input v-model="task.name" placeholder="任务名称" />
      </el-form-item>

      <el-form-item prop="priority">
        <el-select v-model="task.priority">
          <el-option label="高" value="high" />
          <el-option label="中" value="medium" />
          <el-option label="低" value="low" />
        </el-select>
      </el-form-item>

      <el-button @click="removeTask(index)">删除</el-button>
    </el-form>
  </div>
</template>

<style scoped>
.task-form {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 10px;
}
</style>

效果如下:

一、组件结构设计原理

1.数据流向设计

父组件通过v-model实现数据双向绑定:

// ProjectForm.vue
const formData = reactive({
  tasks: [] // 自动同步到子组件
})

// TaskList.vue
const tasks = computed({
  get: () => props.modelValue,
  set: (v) => emit('update:modelValue', v)
})

2. 验证责任划分

  • 父组件:验证任务列表非空
  • 子组件:验证单个任务字段

二、分步实现流程

步骤1:父组件基础验证

// ProjectForm.vue
const validateTasks = (_, __, callback) => {
  formData.tasks.length === 0 
    ? callback(new Error('至少需要1个任务')) 
    : callback()
}

步骤2:子组件独立验证

// TaskList.vue
const taskRules = {
  name: { 
    required: true, 
    trigger: 'blur',
    message: '任务名称必填' 
  }
}

步骤3:动态prop绑定

<el-form-item 
  :prop="`tasks[${index}].name`"
  :rules="taskRules.name">
  <el-input v-model="item.name"/>
</el-form-item>

三、验证联动机制

1.提交时联合验证

// ProjectForm.vue
const submit = () => {
  formRef.value.validate().then(() => {
    taskListRef.value.validate().then(() => {
      // 全部验证通过
    })
  })
}

2. 实时错误反馈

// TaskList.vue
watch(() => props.modelValue, () => {
  formRef.value?.validate()
}, { deep: true })

四、异常处理方案

// 统一错误捕获
try {
  await Promise.all([
    formRef.value.validate(),
    taskListRef.value.validate()
  ])
} catch (errors) {
  console.error('验证失败:', errors)
}

到此这篇关于vue3中form表单层级嵌套问题的解决详解的文章就介绍到这了,更多相关vue3 form表单嵌套内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • vue实现全选组件封装实例详解

    vue实现全选组件封装实例详解

    这篇文章主要介绍了vue 全选组件封装,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-02-02
  • 详解Vue2如何监听数组的变化

    详解Vue2如何监听数组的变化

    这篇文章主要来和大家详细探讨一下Vue2中是如何监听数组的变化的,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2024-03-03
  • vue观察模式浅析

    vue观察模式浅析

    这篇文章主要介绍了vue观察模式浅析,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-09-09
  • vue.config.js中配置分包策略及常见的配置选项

    vue.config.js中配置分包策略及常见的配置选项

    在Vue.js中分包(Code Splitting)是一种将应用程序代码拆分为不同的块或包的技术,从而在需要时按需加载这些包,下面这篇文章主要给大家介绍了关于vue.config.js中配置分包策略及常见的配置选项的相关资料,需要的朋友可以参考下
    2024-02-02
  • Vue实现图片预览功能的详细指南

    Vue实现图片预览功能的详细指南

    在现代 web 应用程序中,图片预览功能提升了用户体验,使用户可以在上传图片之前查看图片内容,本文将详细介绍如何在 Vue.js 应用中实现图片预览功能,包括基本实现、进阶功能、与 Element UI 的集成、常见优化技巧以及与其他库的结合使用,需要的朋友可以参考下
    2024-09-09
  • vue结合Echarts实现点击高亮效果的示例

    vue结合Echarts实现点击高亮效果的示例

    下面小编就为大家分享一篇vue结合Echarts实现点击高亮效果的示例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-03-03
  • vue项目debugger调试看不到源码的问题及解决

    vue项目debugger调试看不到源码的问题及解决

    这篇文章主要介绍了vue项目debugger调试看不到源码的问题及解决,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-06-06
  • Vue3监听属性与Computed的区别详解

    Vue3监听属性与Computed的区别详解

    在 Vue 3 中,watch 和 computed 都是非常重要的概念,它们都可以用于观察和响应数据的变化,但在使用场景和原理上存在明显的区别,本文将详细解析 Vue 3 中监听属性 (watch) 和计算属性 (computed) 的区别,需要的朋友可以参考下
    2024-02-02
  • Vue2.x安装并使用SCSS的全部过程

    Vue2.x安装并使用SCSS的全部过程

    这篇文章主要给大家介绍了关于Vue2.x安装并使用SCSS的相关资料,以及如何在vue 2.x中全局引用公共scss文件,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-03-03
  • vue-cli3项目配置eslint代码规范的完整步骤

    vue-cli3项目配置eslint代码规范的完整步骤

    这篇文章主要给大家介绍了关于vue-cli3项目配置eslint代码规范的完整步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-09-09

最新评论