
本文介绍如何在 vue3 中为多行表单(如 10 行)独立控制每行的文本框与复选框启用状态:当某行第一个输入框有值时,该行第二输入框和复选框自动启用;点击删除按钮则清空整行数据。
本文介绍如何在 vue3 中为多行表单(如 10 行)独立控制每行的文本框与复选框启用状态:当某行第一个输入框有值时,该行第二输入框和复选框自动启用;点击删除按钮则清空整行数据。
在 Vue3 中处理多行、状态隔离的表单交互,推荐采用“组件化 + 响应式数据绑定”模式,而非手动维护 10 个独立 ref 或 v-model 变量。这样既保证逻辑内聚、避免模板臃肿,又充分利用 Composition API 的响应式能力。
分析 Vue 3 Composition API 使用情况——审计响应式模式、可组合函数设计、ref 与 reactive 的选择、计算属性、watcher 使用及组件……
✅ 核心设计思路
- 将单行结构封装为可复用的
组件; - 每行数据以对象形式存储(含 input1、input2、checkbox),通过 v-model 双向绑定到父组件数组;
- 利用 computed 动态计算启用状态:input1 非空 → 启用 input2 和 checkbox;
- 删除操作通过 clearRow() 方法重置当前行数据为默认值,不影响其他行。
? 示例代码(完整可运行)
<script setup>
import { computed, ref } from 'vue'
const defaultRowValue = {
input1: '',
input2: '',
checkbox: false
}
// 自定义行组件(可直接在 setup 中定义,或单独文件)
const CustomRow = {
props: ['index', 'modelValue'],
emits: ['update:modelValue'],
setup(props, { emit }) {
const model = computed({
get: () => props.modelValue,
set: (val) => emit('update:modelValue', val)
})
// 当 input1 有输入(非空字符串)时启用关联控件
const isInput1Filled = computed(() => !!model.value.input1.trim())
const clearRow = () => {
model.value = { ...defaultRowValue }
}
return {
model,
clearRow,
isInput1Filled
}
},
template: `
<div class="container-body">
<div class="container-content">
<div class="container-content">
<input
:id="'Row'+index+'-input1'"
type="text"
v-model="model.input1"
>
<div class="container-content">
<input
:id="'Row'+index+'-input2'"
type="text"
v-model="model.input2"
:disabled="!isInput1Filled"
class="disabled"
>
<div class="container-content">
<div class="custom-control custom-checkbox">
<input
:id="'Row'+index+'-checkbox'"
class="form-check-input"
type="checkbox"
:disabled="!isInput1Filled"
v-model="model.checkbox"
>
<div class="container-content delete">
<button @click="clearRow" type="button">?️ 清空
`
}
// 父组件逻辑
const rows = ref(Array.from({ length: 10 }, () => ({ ...defaultRowValue })))
</script><template><div id="app">
<custom-row v-for="(row, idx) in rows" :key="idx" :index="idx" v-model="rows[idx]"></custom-row><!-- 调试用:查看实时数据 --><pre class="brush:php;toolbar:false;">{{ rows }}










