Vue3递归组件props未更新:deep属性脚本取值异常
Vue3递归组件中props.deep在方法里始终为0的问题解决
问题场景
我有两个Vue3递归组件:一个是元素包裹组件<filter-tree>,另一个是元素组件<filter-tree-item>。deep属性在模板中能正确显示对应层级值,但在包裹组件的interact方法中打印props.deep始终为0,即使模板显示的是2。
包裹组件代码
<template> <div class="filter-tree"> <filter-tree-item v-for="item in items" :key="item.id" :deep="deep" :item="item" @on-interact="interact" ></filter-tree-item> </div> </template> <script setup lang="ts"> export interface Props { items: Items[]; deep?: number; } const props = withDefaults(defineProps<Props>(), { deep: 0 }) const interact = () => { console.log(props.deep) // 始终打印0 } </script>
元素组件代码
<template> <p @click="handle">{{ deep }}</p> <!-- 显示正确的层级值 --> <filter-tree v-if="hasChildren" :items="item.children" :deep="deep + 1"></filter-tree> </template> <script setup lang="ts"> export interface Props { item: Item; deep?: number; } const props = withDefaults(defineProps<Props>(), { deep: 0, }); const emits = defineEmits(['on-interact']) const handle = () => { emits('on-interact') } </script>
问题原因
每个递归生成的<filter-tree>都是独立的组件实例,每个实例都有自己的props.deep值:
- 最外层的
<filter-tree>实例deep为0 - 第二层的
<filter-tree>实例deep为1 - 第三层的
<filter-tree>实例deep为2
当你点击深层级的<filter-tree-item>时,它触发的on-interact事件会向上传递到它所在的那个<filter-tree>实例,但你现在在最外层<filter-tree>的interact方法中打印的是当前实例自己的props.deep,也就是最外层的0,而非触发事件的那个层级的deep值。
解决方案
修改元素组件,在触发事件时把当前组件的deep值作为参数传递出去:
1. 修改元素组件的事件触发逻辑
<script setup lang="ts"> // ... 其他代码不变 const handle = () => { emits('on-interact', props.deep) // 传递当前的deep值 } </script>
2. 修改包裹组件的事件处理方法,接收参数
<script setup lang="ts"> // ... 其他代码不变 const interact = (currentDeep: number) => { console.log(currentDeep) // 现在会打印点击元素对应的层级值 } </script>
这样,无论点击哪个层级的元素,interact方法都能拿到对应层级的deep值了。
内容的提问来源于stack exchange,提问作者Sandex
相关产品推荐
相关产品推荐

