Vue.js中使用v-for时如何为选中选项展示对应输入字段
解决Vue中v-for循环实例共享状态导致的输入字段同步问题
我帮你分析下问题根源:你现在所有动态添加的规则实例,都共享了同一个selectedRule和selectedFields状态变量,所以当你选择新的规则时,所有实例都会跟着切换显示的字段,这就导致了之前的输入被覆盖的问题。
咱们可以通过给每个添加的规则项维护独立的状态来解决这个问题,具体步骤如下:
1. 调整数据结构,存储每个规则项的独立状态
首先在Vue的data里,新增一个数组来保存每个规则项的状态,每个元素对应一个你添加的规则实例:
data() { return { // 你的原始规则数据 rules: [ { "_id": "5b052126c3a5552bac060fab", "refId": 7929, "type": "text", "text": "Indian Act 1931", "__v": 0, "feilds": [{ "refId": 7912, "name": "arms(if any)", "_id": "5b052126c3a5552bac060fac", "sections": [], "subFeilds": [] }] }, { "_id": "5b05244f90a7000f44bcbbb6", "refId": 7930, "type": "text", "text": "Narcotic", "__v": 0, "feilds": [{ "refId": 7913, "name": "qty", "_id": "5b05244f90a7000f44bcbbb7", "sections": [], "subFeilds": [] }] }, { "_id": "5b052b4090a7000f44bcbbbf", "refId": 7933, "type": "option", "text": "Ker", "__v": 0, "feilds": [{ "refId": 7918, "name": "wild", "_id": "5b052b4090a7000f44bcbbc2", "sections": ["sec1", "sec2"], "subFeilds": [{ "refId": 17890, "name": "qty", "_id": "5b052b4090a7000f44bcbbc4" }, { "refId": 7891, "name": "item", "_id": "5b052b4090a7000f44bcbbc3" }] }, { "refId": 7919, "name": "enc", "_id": "5b052b4090a7000f44bcbbc0", "sections": ["sec2"], "subFeilds": [{ "refId": 7892, "name": "qty", "_id": "5b052b4090a7000f44bcbbc1" }] }] } ], // 新增:存储每个规则项的独立状态 ruleItems: [] } }
2. 修改添加规则的方法
点击"Add Another Rule"时,往ruleItems数组里添加一个带有初始状态的对象:
methods: { addRule() { this.ruleItems.push({ selectedRule: null, // 当前项选中的规则 selectedFields: [] // 当前项对应的字段列表 }) }, // 后续还要修改选择规则的方法 }
3. 更新模板,绑定每个项的独立状态
把原来的v-for循环改成遍历ruleItems,每个项绑定自己的selectedRule和selectedFields:
<!-- 循环每个规则项 --> <div v-for="(item, index) in ruleItems" :key="index" style="margin: 1rem 0; padding: 1rem; border: 1px solid #eee;"> <!-- 选择规则的下拉框,绑定当前项的selectedRule --> <select v-model="item.selectedRule" @change="onRuleSelect(item)"> <option value="">Select Rule</option> <option v-for="rule in rules" :key="rule._id" :value="rule"> {{ rule.text }} </option> </select> <!-- 显示当前项对应的字段 --> <div v-if="item.selectedFields.length" style="margin-top: 1rem;"> <div v-for="field in item.selectedFields" :key="field._id" style="margin-bottom: 0.5rem;"> <label>{{ field.name }}:</label> <input type="text" placeholder="Enter value" style="margin-left: 0.5rem;"> <!-- 如果有子字段,也在这里循环渲染 --> <div v-for="subField in field.subFeilds" :key="subField._id" style="margin-left: 1.5rem; margin-top: 0.3rem;"> <label>{{ subField.name }}:</label> <input type="text" placeholder="Enter sub value" style="margin-left: 0.5rem;"> </div> </div> </div> </div> <!-- 添加规则按钮 --> <button @click="addRule">Add Another Rule</button>
4. 修改规则选择的方法
更新onRuleSelect方法,让它只修改当前选中项的字段列表:
methods: { // ...其他方法 onRuleSelect(item) { if (item.selectedRule) { // 注意你的原始数据里字段拼写是feilds(少了一个i),如果可以建议修正 item.selectedFields = [...item.selectedRule.feilds]; } else { item.selectedFields = []; } } }
这样修改后,每个添加的规则项都有自己独立的状态,选择不同的规则时只会更新当前项的输入字段,其他项的状态不会受到影响,完美解决你遇到的问题。另外提一句,你的原始数据里feilds的拼写是错误的(正确应该是fields),如果有机会建议修正这个拼写,避免后续维护时混淆。
内容的提问来源于stack exchange,提问作者ash
相关产品推荐
相关产品推荐

