Vue3$SideEffect-LifecycleHooks

292 阅读3分钟

Vue3$SideEffect-LifecycleHooks

就像我们可以通过事件来获取和改变数据,组件提供的生命周期钩子也可以看作组件的事件,允许我们在特定的时间点获取和改变数据。 需要注意的是,有些时候我们会复用同一个组件,这时一些生命周期就不会被调用,(比如弹出框组件我们并不想每次关闭都销毁,而只想更新数据。)此时使用 watch 更合适(如果是路由组件的话,也可以使用 onBeforeRouteUpdate)。

生命周期钩子可以分为两类:所有组件都有的 & <KeepAlive> 子组件才有的。

下图是 Vue 组件的生命周期,在使用 Composition API 方式时,需要加上 on 前缀且是 camelCase,并且没有 created 相关函数。图中并未给出 nextTick

lifecycle.png

0. Lifecycle Hooks List

下面是我个人的分类。本文只解释了常用的和 <KeepAlive> 的 hooks,其他可参考 VueCompositionApiLifecycle

  • 常用:onMounted(), onUpdated(), onUnmounted(); <script setup>, nextTick()
  • <KeepAlive> 独有:onActivated(), onDeactivated()
  • 不常用:onBeforeMount(), onBeforeUpdate(), onBeforeUnmounted(), onErrorCaptured()
  • 调试用:onRenderTracked(), onRenderTriggered()
  • 服务端独有:onServerPrefetch()

1. <script setup>

<script setup> 通常用来初始化数据和方法,以及获取 API 数据。具体的功能可参照 VueScriptSetup。 官网的描述:

The code inside is compiled as the content of the component's setup() function. This means that unlike normal <script>, which only executes once when the component is first imported, code inside <script setup> will execute every time an instance of the component is created.

我把获取 API 数据(看作 side effect)和初始化数据分开,因为在我看来,初始化是设置空数据。

对于那些获取 API 数据的方法,可以统一在一处调用,比如 function initData(){}

2. onMounted()

组件加载到页面后,回调函数会被调用。通常用来操作 DOM。

官网的描述:

Registers a callback to be called after the component has been mounted. A component is considered mounted after:

  • All of its synchronous child components have been mounted (does not include async components or components inside <Suspense> trees).
  • Its own DOM tree has been created and inserted into the parent container. Note it only guarantees that the component's DOM tree is in-document if the application's root container is also in-document.

This hook is typically used for performing side effects that need access to the component's rendered DOM, or for limiting DOM-related code to the client in a server-rendered application.

3. onUpdated()

其实这个用的不多,只是为了完整性在这提一下。🙃

只要是数据变化引起了页面变化,onUpdated() 回调都会被执行;相对的 watch / watchEffect 只有在相应的数据变化时回调函数才会被执行。所以 watch / watchEffect 用的更多。

我在实验的时候发现两种情况:

  1. 子用到父的 props,更改了父的数据:parent => child
  2. 父通过 ref 显示子的数据,更改了子的数据:child => parent

官网的描述:

Registers a callback to be called after the component has updated its DOM tree due to a reactive state change. A parent component's updated hook is called after that of its child components.

4. onUnmounted()

当一个组件被销毁时,我们可以在这里做一些清理工作。computed / watcher 这种 Vue 管理的内容会被自动清理,timers, DOM event listeners 这样的浏览器管理的内容需要我们手动清理。有时候我们也在 onBeforeUnmounted() 中清理。

官网的解释是:

Registers a callback to be called after the component has been unmounted. A component is considered unmounted after:

  • All of its child components have been unmounted.
  • All of its associated reactive effects (render effect and computed / watchers created during setup()) have been stopped.

Use this hook to clean up manually created side effects such as timers, DOM event listeners or server connections.

5. onActivated() & onDeactivated()

<KeepAlive> 中才可以使用。 官网的解释:

Registers a callback to be called after the component instance is inserted into / removed from the DOM as part of a tree cached by <KeepAlive>.

6. nextTick()

有时候我们希望等 DOM 更新后做一些事。(等等,为什么不是 onUpdated()?因为它管的太宽了) 官网的解释:

A utility for waiting for the next DOM update flush. nextTick() can be used immediately after a state change to wait for the DOM updates to complete. You can either pass a callback as an argument, or await the returned Promise.