如何在Vuetify数据表格中实现指定行的ValidationObserver校验
我完全懂你现在的困扰——点击表格行里的校验按钮,结果整个表格所有行的校验规则都跑起来了,根本不是只校验当前点击的那一行。这是因为你现在调用的是顶层ValidationObserver提供的validate()方法,这个方法默认会校验它管辖下的所有ValidationProvider组件,而你的整个表格都被这个顶层Observer包着,所以所有行的校验都会被触发。
下面给你两种可行的解决方案,你可以根据自己的需求选择:
方案一:调用validate时指定当前行的校验ID(改动最小)
ValidationObserver的validate()方法其实支持传入参数,指定只校验某个特定vid的ValidationProvider。你只需要修改按钮的触发逻辑,把当前行对应的vid传进去就行:
修改后的代码片段
<ValidationObserver mode="passive" v-slot="{ validate }"> <v-data-table :headers="headers" :items="items" > <template slot="item.postcode" slot-scope="{ item }"> <!-- 这里建议用item的唯一标识(比如id)代替indexOf,避免数组顺序变化导致vid错误 --> <ValidationProvider rules="required" :vid="`postcode-${item.id}`" v-slot="{ errors }" > <v-text-field :error-messages="errors" v-model="item.postcode" class="mb-1" placeholder="Postcode" hide-details dense ></v-text-field> </ValidationProvider> </template> <template slot="item.actions" slot-scope="{ item }"> <!-- 调用validate时传入当前行的vid参数 --> <JobValidationTableAction @validate="validate({ vid: `postcode-${item.id}` })" ></JobValidationTableAction> </template> </v-data-table> </ValidationObserver>
为什么这样有效?
通过{ vid: 'xxx' }参数告诉Observer,只校验匹配这个vid的Provider,这样就只会触发当前行的邮政编码输入框校验,不会影响其他行。
注意:别用
items.indexOf(item)生成vid,如果你的数组有重复项、或者后续做了排序/过滤,indexOf会返回错误的索引,导致vid不唯一。一定要用item本身的唯一标识,比如item.id。
方案二:给每行单独设置ValidationObserver(更彻底的隔离)
如果你的需求是每行的校验状态完全独立(比如要单独显示每行的校验结果),可以把ValidationObserver放到每行的模板里,让每行都有自己的校验上下文:
修改后的代码片段
<v-data-table :headers="headers" :items="items" > <!-- 自定义整行的模板,给每行套一个ValidationObserver --> <template slot="item" slot-scope="{ item }"> <ValidationObserver mode="passive" v-slot="{ validate }"> <!-- 渲染表格的其他列 --> <td>{{ item.name }}</td> <!-- 邮政编码列 --> <td> <ValidationProvider rules="required" vid="postcode" v-slot="{ errors }" > <v-text-field :error-messages="errors" v-model="item.postcode" class="mb-1" placeholder="Postcode" hide-details dense ></v-text-field> </ValidationProvider> </td> <!-- 操作列 --> <td> <JobValidationTableAction @validate="validate()" ></JobValidationTableAction> </td> </ValidationObserver> </template> </v-data-table>
为什么这样有效?
现在每行都有自己的ValidationObserver,点击行内按钮时调用的是当前行Observer的validate()方法,自然只会校验该行内的ValidationProvider,完全不会影响其他行。
两种方案都能解决你的问题,方案一改动小、适合快速修复;方案二更灵活,适合复杂的行内校验场景。
内容的提问来源于stack exchange,提问作者Alex

