如何在Vuelidate校验子组件prop的同时维持父子组件双向绑定?
解决方案
问题根因
你当前的代码混用了Vuelidate的选项式validations配置和组合式useVuelidate调用,两者没有建立关联,且没有将父组件传入的value prop作为校验目标传入Vuelidate,导致Vuelidate无法追踪prop的动态变更,因此父组件修改绑定值时校验逻辑无法同步响应。
改造方案
子组件InputValidate修改
完全使用组合式API配置Vuelidate,将prop的value转为响应式ref作为校验目标,保留原有的双向绑定emit逻辑即可:
<template> <div class="form-group"> <label for="name">{{ title }}</label> <input class="form-control" :value="value" @input="$emit('update:value', $event.target.value)" :class="{ 'is-invalid': v$.value.$error }" /> <div class="invalid-feedback"> <p v-for="error of v$.value.$errors" v-bind:key="error.$uid"> {{ error.$message }} </p> </div> </div> </template> <script lang="ts"> import { defineComponent, toRef } from "vue"; import { useVuelidate } from "@vuelidate/core"; import { required } from "@vuelidate/validators"; export default defineComponent({ name: "InputValidate", props: { title: { type: String, default: "Input", }, value: { type: String, default: "", }, // 可选:支持父组件自定义校验规则,提升组件通用性 rules: { type: Object, default: () => ({ required }) } }, setup(props, { expose }) { // 将prop的value转为ref,保证父组件修改时Vuelidate能感知变更 const valueToValidate = toRef(props, 'value') // 传入校验规则和校验目标 const v$ = useVuelidate( { value: props.rules }, { value: valueToValidate } ) // 可选:暴露重置校验状态的方法,供父组件清空表单时调用 const resetValidate = () => v$.$reset() expose({ resetValidate }) return { v$ } }, }); </script>
父组件使用方式
原有调用逻辑无需修改,可直接支持父端操作绑定数据:
<!-- 原有调用写法保持不变 --> <input-validate ref="inputValidateRef" title="Singular" v-model:value="newItem.singular" /> <!-- 父组件清空表单示例 --> <button @click="clearForm">清空</button> <script lang="ts"> import { ref } from 'vue' const newItem = ref({ singular: '' }) // 拿到子组件实例的ref,可选用于重置校验状态 const inputValidateRef = ref() const clearForm = () => { // 直接修改父组件绑定值,子组件会自动同步 newItem.value.singular = '' // 可选:同时清空子组件的校验错误提示 inputValidateRef.value?.resetValidate() } </script>
效果说明
- 保留了原有的双向绑定逻辑,父组件修改绑定值时子组件输入内容、校验状态会自动同步
- Vuelidate校验逻辑正常生效,输入为空时会触发必填校验提示
- 支持父组件清空、赋值等所有操作绑定数据的需求
内容的提问来源于stack exchange,提问作者HardReset
相关产品推荐
相关产品推荐

