如何清除Vue3 Composition API中‘Slot 'default'渲染函数外调用’警告?
解决Vue3插槽调用警告问题
警告信息
[Vue warn]: Slot "default" invoked outside of the render function: this will not track dependencies used in the slot. Invoke the slot function inside the render function instead.
功能运行正常,但需要清除该警告,原始代码如下:
<template> <ul class="flex" data-test-id="tab-wrapper"> <li v-for="(tab, index) in tabs" :key="index" @click="currentTab = tab" > {{ tab }} </li> </ul> <slot /> </template> <script setup> import { provide, ref, useSlots } from "vue"; const slots = useSlots(); const tabs = (slots.default && slots.default().map(tab => tab?.props?.title)) ?? []; const currentTab = ref(tabs[0]); provide("currentTab", currentTab); </script>
问题原因
你在<script setup>顶层直接调用了slots.default(),这属于在Vue渲染函数上下文之外执行插槽函数。Vue要求插槽函数必须在渲染过程中调用,才能正确跟踪插槽内部的响应式依赖,否则就会抛出该警告。
解决方案
将获取tabs的逻辑放到computed计算属性中,计算属性的求值过程会被纳入渲染上下文,这样调用插槽函数就符合Vue的要求。同时添加监听确保currentTab能随插槽内容动态更新:
<template> <ul class="flex" data-test-id="tab-wrapper"> <li v-for="(tab, index) in tabs" :key="index" @click="currentTab = tab" > {{ tab }} </li> </ul> <slot /> </template> <script setup> import { provide, ref, useSlots, computed, watch } from "vue"; const slots = useSlots(); // 用computed包裹插槽处理逻辑,确保在渲染上下文内调用插槽函数 const tabs = computed(() => { return (slots.default && slots.default().map(tab => tab?.props?.title)) ?? []; }); const currentTab = ref(tabs.value[0]); // 监听tabs变化,同步更新currentTab,避免插槽内容变更后选中项失效 watch(tabs, (newTabs) => { if (newTabs.length > 0 && !newTabs.includes(currentTab.value)) { currentTab.value = newTabs[0]; } }, { immediate: true }); provide("currentTab", currentTab); </script>
修改说明
- computed包裹插槽处理:computed的回调函数在组件渲染时执行,此时调用
slots.default()处于渲染函数上下文内,符合Vue规范,警告会被消除。 - 添加watch监听:tabs变为响应式计算属性后,当插槽内容动态变化时,tabs会自动更新,通过watch同步currentTab的值,避免出现选中项不存在的情况。
- 保留原有功能:修改后tab生成、切换逻辑与原代码完全一致,功能不受影响。
内容的提问来源于stack exchange,提问作者Cin88
相关产品推荐
相关产品推荐

