
本文介绍如何在 vue3 中为多行表单(如 10 行)独立控制每行的文本框与复选框启用状态:当某行第一个输入框有值时,该行第二个输入框和复选框自动启用;点击“删除”按钮则清空整行数据。核心采用组件化 + v-model 双向绑定方案,避免冗余数据声明。
本文介绍如何在 vue3 中为多行表单(如 10 行)独立控制每行的文本框与复选框启用状态:当某行第一个输入框有值时,该行第二个输入框和复选框自动启用;点击“删除”按钮则清空整行数据。核心采用组件化 + v-model 双向绑定方案,避免冗余数据声明。
在 Vue3 中处理多行、状态隔离的表单交互,不推荐为每行手动声明 10 组响应式变量(如 row1Input1, row2Input1…),这会导致模板臃肿、逻辑耦合且难以维护。最佳实践是将单行封装为可复用的
✅ 核心设计思路
- 每行数据结构统一:{ input1: '', input2: '', checkbox: false }
- 启用条件:仅当 input1 非空字符串(即 !!model.input1)时,input2 和 checkbox 才启用
- 删除操作:重置当前行数据为默认值,不影响其他行
- 父组件仅管理 rows: Array
,子组件专注自身逻辑
? 完整实现代码
<!-- CustomRow.vue(或直接在 setup 中定义) -->
<script setup>
import { computed, defineProps, defineEmits } from 'vue'
const props = defineProps({
index: Number,
modelValue: {
type: Object,
required: true
}
})
const emit = defineEmits(['update:modelValue'])
// 双向绑定支持
const model = computed({
get() {
return props.modelValue
},
set(val) {
emit('update:modelValue', val)
}
})
// 启用判断:input1 有内容才启用后续控件
const isRowEnabled = computed(() => !!model.value.input1)
// 清空当前行
const clearRow = () => {
model.value = { input1: '', input2: '', checkbox: false }
}
</script><template><div class="container-body">
<div class="container-content"></div>
<div class="container-content">
<input :id="`Row${index}-input1`" type="text" v-model="model.input1">
</div>
<div class="container-content">
<input :id="`Row${index}-input2`" type="text" v-model="model.input2" :disabled="!isRowEnabled">
</div>
<div class="container-content">
<div class="custom-control custom-checkbox">
<input :id="`Row${index}-checkbox`" class="form-check-input" type="checkbox" :disabled="!isRowEnabled" v-model="model.checkbox">
</div>
</div>
<div class="container-content delete">
<button>?️ 清空</button>
</div>
</div>
</template>
父组件中使用:
递归分析 Vue 项目组件依赖,从入口文件生成组件层级图,支持 Vue 2/3,输出组件名、文件路径和属性。适用于分析组件结构、排查依赖或了解项目架构。
<script setup>
import { ref, onMounted } from 'vue'
import CustomRow from './CustomRow.vue'
const rows = ref([])
onMounted(() => {
// 初始化 10 行空数据
for (let i = 0; i < 10; i++) {
rows.value.push({ input1: '', input2: '', checkbox: false })
}
})
</script><template><div id="app">
<customrow v-for="(row, idx) in rows" :key="idx" :index="idx" v-model="rows[idx]"></customrow><!-- 调试用:查看实时数据 --><pre class="brush:php;toolbar:false;">{{ rows }}










