Vue 3渲染函数中条件类无响应问题求助
Vue h函数渲染组件时条件类无响应问题解决
问题概述
使用Vue的hyperscript(h函数)渲染组件时,输入组件中展示的invalid props值会随输入内容正常变化,但输入框上绑定的条件类--invalid始终无法更新,无法根据invalid值切换样式。
代码分析
问题核心在于通过h函数传递props时,直接将ref对象传给了子组件,而非传递ref的实际布尔值:
- 父组件中
invalid是ref<boolean>类型,调用render({}, invalid)时将整个ref对象传入render函数 render函数直接把ref对象赋值给copy.invalid,作为props传递给子组件- 子组件接收的
invalidprops是ref对象:- 模板插值
{{ invalid }}能正常显示值,是因为Vue对模板中的props ref做了自动解包 - 但在
:class的对象语法中,invalid作为ref对象,布尔判断永远为true(JS中对象属于truthy值),导致类名始终存在,不会随ref值变化更新
- 模板插值
解决方案
方案1:修改render函数,传递ref的实际值
在render函数中传递ref的.value,同时监听ref变化以保持响应式:
import { h, defineEmits, watch } from "vue"; import theinput from "./input.vue"; const render = (details: any, invalid: any) => { const emit = defineEmits(["update:value"]); // 初始传递ref的实际值 const props = { ...details, invalid: invalid.value, "update:value": (value: any) => emit("update:value", value), }; // 监听ref变化,同步更新组件props watch(invalid, (newVal) => { props.invalid = newVal; }); return h(theinput, props); }; export { render };
方案2:子组件内部解包props
在子组件中通过计算属性将props的invalid转换为布尔值:
<template> <div> invalid: {{ invalid }} <input class="theinput" :class="{ '--invalid': isInvalid }" @input="updateValue" v-model="value" /> </div> </template> <script setup lang="ts"> import { ref, computed } from "vue"; const props = defineProps(["invalid"]); // 自动解包props中的ref,得到布尔值 const isInvalid = computed(() => { return typeof props.invalid === 'object' && 'value' in props.invalid ? props.invalid.value : props.invalid; }); const value = ref(""); const emit = defineEmits(["update:value"]); const updateValue = (event: Event) => { emit("update:value", (event.target as HTMLInputElement).value); }; </script>
临时Workaround说明
你发现的临时解决方法(:class="{ '--invalid': invalid.value }")可行,原因是直接访问了ref对象的value属性获取布尔值。模板插值{{ invalid }}无需.value是因为Vue在模板插值时对props中的ref做了自动解包处理,这属于Vue的特殊行为,并非通用规则。
内容的提问来源于stack exchange,提问作者user3699170
相关产品推荐
相关产品推荐

