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("提交數(shù)據(jù):", 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: "請選擇優(yōu)先級", 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>
效果如下:

一、組件結(jié)構(gòu)設(shè)計原理
1.數(shù)據(jù)流向設(shè)計
父組件通過v-model實現(xiàn)數(shù)據(jù)雙向綁定:
// ProjectForm.vue
const formData = reactive({
tasks: [] // 自動同步到子組件
})
// TaskList.vue
const tasks = computed({
get: () => props.modelValue,
set: (v) => emit('update:modelValue', v)
})
2. 驗證責任劃分
- 父組件:驗證任務列表非空
- 子組件:驗證單個任務字段
二、分步實現(xiàn)流程
步驟1:父組件基礎(chǔ)驗證
// 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:動態(tài)prop綁定
<el-form-item
:prop="`tasks[${index}].name`"
:rules="taskRules.name">
<el-input v-model="item.name"/>
</el-form-item>
三、驗證聯(lián)動機制
1.提交時聯(lián)合驗證
// ProjectForm.vue
const submit = () => {
formRef.value.validate().then(() => {
taskListRef.value.validate().then(() => {
// 全部驗證通過
})
})
}
2. 實時錯誤反饋
// TaskList.vue
watch(() => props.modelValue, () => {
formRef.value?.validate()
}, { deep: true })
四、異常處理方案
// 統(tǒng)一錯誤捕獲
try {
await Promise.all([
formRef.value.validate(),
taskListRef.value.validate()
])
} catch (errors) {
console.error('驗證失敗:', errors)
}
到此這篇關(guān)于vue3中form表單層級嵌套問題的解決詳解的文章就介紹到這了,更多相關(guān)vue3 form表單嵌套內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue結(jié)合Echarts實現(xiàn)點擊高亮效果的示例
下面小編就為大家分享一篇vue結(jié)合Echarts實現(xiàn)點擊高亮效果的示例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-03-03
vue項目debugger調(diào)試看不到源碼的問題及解決
這篇文章主要介紹了vue項目debugger調(diào)試看不到源碼的問題及解決,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-06-06
Vue3監(jiān)聽屬性與Computed的區(qū)別詳解
在 Vue 3 中,watch 和 computed 都是非常重要的概念,它們都可以用于觀察和響應數(shù)據(jù)的變化,但在使用場景和原理上存在明顯的區(qū)別,本文將詳細解析 Vue 3 中監(jiān)聽屬性 (watch) 和計算屬性 (computed) 的區(qū)別,需要的朋友可以參考下2024-02-02
vue-cli3項目配置eslint代碼規(guī)范的完整步驟
這篇文章主要給大家介紹了關(guān)于vue-cli3項目配置eslint代碼規(guī)范的完整步驟,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-09-09

