疑问
最近,一直在学习 Vue 3,此前我不懂前端,也没写过 Vue 2,所以是从 0 开始学习 Vue 3 的。很多对普通人不是疑问的,在我这里也会不太清楚。
我在写项目的时候,常见的一种场景是这样的:页面加载的时候,需要从后端或者服务提取数据,然后渲染到页面上。不知道这样的情况大家怎么写?
const list = ref([])
async function getData() {
const param1 = "something"
const param2 = "something"
const result = await getDataFromServer(param1, param2)
list.value = result.data
}
getData()
我一般默认会这样写,就是先写个函数,里面是调用远程数据的。然后直接调用这个函数。
后来,我知道了有生命周期钩子这种东西,比如 onMounted
,那么上面的情况,就还可以有一种写法:
//... ...
onMounted(() => {
getData()
})
那么到底应该在 代码里直接调用,还是应该用 onMounted
钩子函数呢?
解答
在Vue 3中,立即调用一个函数和在onMounted
钩子中调用该函数之间的主要区别在于它们执行的时机以及它们可以访问的Vue组件上下文的差异。
- 立即调用函数:当你在组件的
setup
函数中声明并立即调用一个函数时,这个函数会在组件的初始化阶段立即执行。这意味着它会在组件的其它生命周期钩子之前执行,甚至在模板和DOM被渲染之前。这对于初始化状态或执行不依赖于DOM的逻辑是有用的。然而,由于此时组件尚未挂载,所以无法访问到DOM元素,同时也无法保证所有的子组件或异步数据已经加载完成。 - 使用
onMounted
:onMounted
是Vue的一个生命周期钩子,它会在组件的DOM已经被挂载到页面上之后调用。这意味着当你在onMounted
钩子中调用函数时,你可以安全地执行DOM操作或者执行依赖于子组件已经挂载的操作。此时,组件已经完成了初始渲染,因此对于需要访问或修改DOM的操作,onMounted
是一个理想的位置。
总结一下,主要区别在于:
- 执行时机:立即调用函数在组件初始化时立即执行,而onMounted在组件挂载完成后执行。
- 能做什么:立即调用函数适用于不需要DOM,且不依赖于组件挂载的逻辑。而onMounted适用于需要访问或修改DOM,或依赖于子组件已挂载的场景。
- 访问组件上下文:在Vue 3的setup函数中,无论是立即调用函数还是onMounted中调用的函数,都可以访问组件上下文(通过setup的参数或useContext),但是在onMounted中可以确保所有的响应式数据已经准备好,且组件已经挂载。
选择哪种方式取决于你的具体需求和你需要执行的操作类型。
总结
以上是 GPT 给我的回答,我是存疑的,不过总算还是有一些提示的。首先,onMounted
更多关乎视觉的渲染问题,可能涉及到 DOM 的就位问题。所以,初步的结论是,如果不涉及到界面 DOM 元素的等待,那么可以直接调用,否则应该用 onMounted
。
不过我在调试的时候发现 onMounted
的另一个问题,就是在 Vite 调试环境下,如果用了 onMounted
,一旦触发了 HMR,那么有些情况下,里面的回调不会执行。因为 HMR 只是热加载它认为变化的模块,如果没有涉及当前的模块,那么很可能不会再次触发 onMounted
的回调,但是页面又真的被刷新了,导致出现了数据空白,必须在 onUpdated
回调中调用,才能解决。