Vue3自定义v-model辅助函数不具备完全响应性,无法识别外部prop变更如何解决?
问题根因
你调用vModel(props.modelValue, context)时传入的是props.modelValue的当前值,属于值传递,辅助函数内部的computed getter始终返回的是这个初始传入的固定值,没有和响应式的props对象建立依赖追踪,自然无法感知外部对prop的更新。
而直接在组件内编写computed时,getter每次执行都会访问响应式对象props的属性,Vue会自动收集这个依赖,prop更新时就会触发computed重新计算。
修复方案
提供两种常用的修改方式,可根据使用习惯选择:
方案1:入参改为getter函数(灵活度更高)
修改辅助函数,接受一个返回目标值的函数作为入参,每次getter执行时主动调用该函数获取最新值:
import { computed, SetupContext, WritableComputedRef } from 'vue'; export const vModel = <T>(getVal: () => T, context: SetupContext, binding = 'modelValue'): WritableComputedRef<T> => computed({ get: () => getVal(), set: (value) => { context.emit(`update:${binding}`, value); }, });
调用方式调整为:
const inputVal = vModel(() => props.modelValue, context);
该方案支持绑定任意计算逻辑的响应式值,不限于props属性。
方案2:入参改为props对象+绑定键名(类型更安全)
修改辅助函数直接接收整个props对象和要绑定的属性名,内部直接访问props的对应属性建立依赖追踪,同时支持泛型类型校验:
import { computed, SetupContext, WritableComputedRef } from 'vue'; // 泛型约束确保传入的绑定键是props的合法属性 export const vModel = <Props extends object, K extends keyof Props>( props: Props, context: SetupContext, binding: K = 'modelValue' as K ): WritableComputedRef<Props[K]> => computed({ get: () => props[binding], set: (value) => { context.emit(`update:${String(binding)}`, value); }, });
调用方式调整为:
// 绑定默认modelValue const inputVal = vModel(props, context); // 绑定自定义名称的v-model,比如v-model:visible // const visible = vModel(props, context, 'visible');
内容的提问来源于stack exchange,提问作者Fex
相关产品推荐
相关产品推荐

