Vue3 setup语法下滚动控制按钮v-if显隐失效问题排查
关联模板代码
<div class="app__land-bottom" v-if="isVisible"> <a href="#projects"> <img ref="arrowRef" id="arrow" src="./../assets/down.png" alt srcset /> </a> </div>
问题根因
代码不生效是两个问题叠加导致的,核心问题是响应式变量操作错误:
- ref响应式变量赋值方式错误:Vue3
<script setup>中通过ref()创建的响应式变量是包装对象,在脚本逻辑中修改值必须操作其.value属性。原代码直接给isVisible赋值布尔值,相当于覆盖了ref对象的引用,完全丢失响应性,模板始终只能拿到初始值false,因此按钮一直隐藏。
- ref响应式变量赋值方式错误:Vue3
- 事件监听绑定/移除的函数引用不一致:原代码在添加和移除scroll监听时都传入了新写的匿名箭头函数,两个函数内存地址完全不同,移除监听时无法匹配到之前绑定的回调,会造成内存泄漏,虽然不是本次显隐失效的直接原因,但属于必须修复的逻辑问题。
修复方案
按照以下三点调整即可:
- 所有对ref变量的赋值操作,都通过
.value属性完成 - 将scroll事件的回调抽为固定引用的独立函数,保证绑定和移除时传入的是同一个函数
- 组件挂载后主动执行一次显隐判断逻辑,避免首屏未触发滚动事件时状态错误
修复后的完整代码如下:
<script setup> import { ref, onMounted, onUnmounted } from "vue"; const isVisible = ref(false); const hideArrow = () => { const currentScroll = window.pageYOffset; // 脚本中修改ref值必须操作.value,逻辑可简化为直接赋值判断结果 isVisible.value = currentScroll < 100; } onMounted(() => { window.addEventListener("scroll", hideArrow); hideArrow(); // 初始化时主动执行一次,保证首屏状态正确 }); onUnmounted(() => { // 传入和绑定时完全一致的函数引用,才能正确移除监听 window.removeEventListener("scroll", hideArrow); }); </script>
补充说明:Vue2中data返回的属性会被挂载到组件实例this上,直接通过
this.xxx赋值即可触发响应式更新;Vue3的ref是独立的响应式包装类型,仅在模板中使用时会被自动解包,脚本逻辑中必须显式访问.value才能正确读写值。
内容的提问来源于stack exchange,提问作者user15392697
相关产品推荐
相关产品推荐

