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中插槽slot的用法详解

    Vue中插槽slot的用法详解

    插槽(Slot)是Vue.js中一个非常重要的概念,它极大地提高了组件的复用性和灵活性,通过插槽,我们可以自定义组件的内容,使其能够适应不同的场景,本文将结合实际案例,详细介绍Vue中插槽的基本用法、类型以及高级技巧,需要的朋友可以参考下
    2024-11-11
  • Vue中使用JsonView来展示Json树的实例代码

    Vue中使用JsonView来展示Json树的实例代码

    这篇文章主要介绍了Vue之使用JsonView来展示Json树的实例代码,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-11-11
  • vue3使用reactive赋值后页面不改变

    vue3使用reactive赋值后页面不改变

    本文主要介绍了vue3使用reactive赋值后页面不改变,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-04-04
  • Vue2+Elementui Dialog实现封装自定义弹窗组件

    Vue2+Elementui Dialog实现封装自定义弹窗组件

    在日常的管理系统界面中,我们写的最多的除了列表表格之外,就是各种弹窗组件,本文就来为大家详细介绍一下Vue2如何结合Elementui Dialog实现封装自定义弹窗组件,希望对大家有所帮助
    2023-12-12
  • Vue折叠面板组件的封装

    Vue折叠面板组件的封装

    这篇文章主要为大家详细介绍了Vue折叠面板组件的封装,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-04-04
  • vue组件打包并发布到npm的全过程

    vue组件打包并发布到npm的全过程

    这篇文章主要介绍了vue组件打包并发布到npm的全过程,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-01-01
  • VUE Token的失效处理详解

    VUE Token的失效处理详解

    这篇文章主要为大家介绍了VUE Token的失效处理,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2021-11-11
  • Vue中通过Vue.extend动态创建实例的方法

    Vue中通过Vue.extend动态创建实例的方法

    这篇文章主要介绍了Vue中通过Vue.extend动态创建实例的方法,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-08-08
  • 手把手教你如何运行一个前端uniapp项目

    手把手教你如何运行一个前端uniapp项目

    这篇文章主要介绍了如何设置和运行一个基于uni-app框架的项目,包括安装必要的软件、克隆项目并安装依赖,以及如何使用HBuilderX进行项目运行和调试,需要的朋友可以参考下
    2025-01-01
  • vue下载excel文件的四种方法实例

    vue下载excel文件的四种方法实例

    最近vue项目中遇到了需求,客户端需要实现以excel表格形式下载数据,这篇文章主要给大家介绍了关于vue下载excel文件的四种方法,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-06-06

最新评论