关于页面的Vue 组件的执行顺序(简化版)
- 执行
<script setup>里的代码
- 这时会创建响应式数据(如 ref、reactive),注册生命周期钩子(如 onMounted),定义方法等。
- 模板编译
- Vue 会把
<template>里的内容编译成虚拟 DOM。
- 挂载阶段
- Vue 把虚拟 DOM 渲染成真实 DOM,并把 DOM 元素赋值给你在
<template>里用的 ref。
- 执行
onMounted回调
- 这时组件已经挂载到页面上,大部分情况下
ref绑定的 DOM 元素已经有值,但在某些特殊情况下(比如复杂的v-if/v-for、异步渲染等),ref 赋值可能还没完成。
- DOM 更新完成后,执行
nextTick回调
- 这时可以100%保证
ref绑定的 DOM 元素已经有值。
注意,这里重点是区分 computed 和 nextTick 的差异
setup 阶段:只是创建了 ref 对象(比如 const myRef = ref()),此时 myRef.value 还是 null。
模板渲染阶段:Vue 会把 <template> 里的 ref="myRef" 绑定到真实 DOM 元素上。
onMounted 阶段:大部分情况下,myRef.value 已经是 DOM 元素,但不是100%保证。
nextTick 阶段:一定可以拿到 DOM 元素。
报错类
如果 useScroll 没有生效(比如 scrollTop 没有变化、滚动事件没有触发),很可能是绑定和滚动的元素不对,或者滚动事件没有被触发。下面帮你详细分析原因和排查方法:
1. 现在的结构
<template>
<div ref="detailRef">
<tab-control ... />
</div>
<div class="detail top-page">
...
</div>
</template>
你把 ref="detailRef" 绑定在了最外层的一个 div上,但页面实际滚动的区域可能不是这个 div,而是 .detail.top-page 或整个页面。