Vue组合式API中Computed依赖Props不更新问题排查
问题原因与解决方案
核心问题
你遇到的问题根源是解构defineProps返回的响应式对象时,破坏了属性的响应式。
defineProps返回的是一个特殊的响应式props对象,但直接通过const { txt } = defineProps(...)解构出来的txt是普通字符串值,不再具备响应式能力。你的computed依赖这个非响应式的静态值,所以父组件的txt更新时,txtComputed不会重新计算。
而模板中直接用txt能正常更新,是因为Vue模板会自动对props对象做响应式代理,模板里的txt实际指向props.txt,而非你解构出的普通变量。
三种解决方法
方法1:直接使用props对象(推荐,简单直观)
不解构props,直接通过props对象访问属性,确保computed依赖响应式的props属性:
<template> <p>{{ txt }}</p> <p>{{ txt + " 1" }}</p> <p>{{ txtComputed }}</p> </template> <script lang="ts" setup> const props = defineProps<{ txt: string }>() const txtComputed = computed(() => { return props.txt + " 1" }) </script>
方法2:用toRef将单个props转为响应式ref
如果需要单独使用某个props属性,用toRef把props上的属性转为响应式ref:
<template> <p>{{ txt }}</p> <p>{{ txt + " 1" }}</p> <p>{{ txtComputed }}</p> </template> <script lang="ts" setup> import { toRef, computed } from 'vue' const props = defineProps<{ txt: string }>() const txt = toRef(props, 'txt') const txtComputed = computed(() => { return txt.value + " 1" }) </script>
注意这里需要访问txt.value,因为它是一个ref对象。
方法3:用toRefs批量转换props为响应式ref
如果需要解构多个props属性,用toRefs把整个props对象转为包含响应式ref的对象:
<template> <p>{{ txt }}</p> <p>{{ txt + " 1" }}</p> <p>{{ txtComputed }}</p> </template> <script lang="ts" setup> import { toRefs, computed } from 'vue' const props = defineProps<{ txt: string }>() const { txt } = toRefs(props) const txtComputed = computed(() => { return txt.value + " 1" }) </script>
同样,访问时需要用txt.value。
内容的提问来源于stack exchange,提问作者moxyom
相关产品推荐
相关产品推荐

