【问题标题】:Vue v-model does not work with individual index of arrayVue v-model 不适用于数组的单个索引
【发布时间】:2021-11-03 09:39:07
【问题描述】:

我有一行输入:一个复选框和一个下拉按钮。

然后,有另一个按钮可以添加新的一行输入。

该复选框在选中时会禁用下拉菜单并使其不再需要。

<template>
  <div>
    <tr v-for="(item, i) of timesheet.items" :key="i">
    <div>
        <td>
            <input 
                type= "checkbox"
                v-model="checked"
                id= "{{ 'disable' + i }}" 
                v-on:click= "disable(i)"
            >
        </td>
        <td>
            <select2 
                :id="'project_id-' + i" 
                v-bind:class="{
                    'is-invalid': item.project_id.$error,
                    'is-valid':
                    item.project_id.$dirty &&
                    !item.project_id.$error,
                }"
            >
                <option value="">Select</option>
                <option v-for="(project) in projects" 
                    :selected="project.id == timesheet.project_id" 
                    :key="project.id" 
                    :value="project.id">{{ project.name }}</option>
            </select2>
        </td>
        <td>
            <button 
                type="button" 
                class="btn btn-sm btn-primary" 
                @click="itemCount++"
            >Add Row
            </button>
        </td>
    </div>
    </tr>
  </div>
</template>
<script>
    import { required, minLength } from "vuelidate/lib/validators";
    export default {
        data() {
            return {
                checked: false,
                timesheet: { items: [{ project_id: "" }] },
            }
        },
        validations() {
            if (!this.checked) {
                return{
                    itemCount: 1,
                    timesheet: {
                        items: {
                            required,
                            minLength: minLength(1),
                            $each: { project_id: { required }}
                        }
                    }
                }
            }else{
                return{
                    timesheet: {
                        items: {
                            required,
                            minLength: minLength(1),
                            $each: { project_id: {} }
                        }
                    }
                }                
            }
        },
        watch: {
            itemCount(value, oldValue) {
                if (value > oldValue) {
                    for (let i = 0; i < value - oldValue; i++) {
                        this.timesheet.items.push({
                            project_id: "",
                            checked: false,
                        })
                    }
                } else {
                    this.timesheet.items.splice(value);
                }
            }
        },
        methods: {            
            disable(index){
                const check = 
                        document.getElementById('project_id-' + index).disabled
                $('#project_id-' + index).attr('disabled', !check);
            }
        },        
    }
</script>   

第一个复选框按预期工作,但每当添加另一行时,总是会预先检查新的复选框,并且与第一个复选框的行为完全相反。

那么,我的问题是如何修复我的 v-model?

【问题讨论】:

  • 请显示添加行元素的代码。另外,iitemsCount 是在哪里定义的?复选框有id="disable",这是错字吗?它不应该像'project_id-'+i一样是动态的吗?
  • @Mythos 感谢您的回复。先生,我已经纠正了这些。
  • 我也应该修改我的v-model吗,先生?

标签: javascript vue.js v-model


【解决方案1】:

我发现您的代码存在一些问题。

首先,复选框有id= "{{ 'disable' + i }}",不允许在属性中使用插值,你应该使用:id="'disable' + i"

第二,我还是不明白你在哪里定义了itemsCount,我假设它在data下。

第三,您对所有复选框使用相同的 v-model,即 data 下的 checked 模型。因此,单击任何复选框都会更改checked,并且此更改也将在其他复选框中更新。这就是为什么您的所有复选框都同步运行的原因。

第四,你已经定义了timesheet: { items: [{ project_id: "" }] },所以item 只包含project_id 属性。但是稍后当您添加使用this.timesheet.items.push({ project_id: "", checked: false }) 的项目时,这告诉我您正在尝试为每个item 拥有checked 属性,您打算将其用于每个复选框。那么,你的想法是对的。

您需要做的是在data 中将checked 属性添加到items,并将其用作复选框的v-model。

  data() {
    return {
      itemCount: 1,
      timesheet: { items: [{ project_id: "", checked: false }] },
    };
  },
<input
  type="checkbox"
  v-model="item.checked"
  :id="'disable' + i"
  v-on:click="disable(i)"
/>

【讨论】:

  • 不过,validation() 会触发一些控制台警告:[Vue warn]: Error in render: "ReferenceError: item is not defined"
  • 如何将!this.checked 的正确语法作为if else 部分的条件,先生?
  • 我试过这些:!item.checked!timesheet.item.checked!this.item.checked!this.timesheet.item.checked,但它们都不起作用。
  • 这是一个vuelidate 相关的问题。您应该尝试在 vuelidate 文档中查找它(查找 requiredIf)或者如果您没有找到任何内容,请提出其他问题,我很乐意回答。
  • 注意到,感谢您的帮助,@Mythos 先生
猜你喜欢
  • 2022-01-03
  • 2020-12-07
  • 1970-01-01
  • 1970-01-01
  • 2019-05-27
  • 1970-01-01
  • 2021-11-17
  • 2019-02-14
  • 2018-08-31
相关资源
最近更新 更多