VUE父子组件生命周期

104 阅读3分钟

在 Vue 中,父组件和子组件的生命周期是相互独立的,但它们之间存在着某些交互。父组件和子组件在创建、更新、销毁等生命周期的不同阶段可能会相互影响。

父组件和子组件的生命周期钩子

1. 父组件生命周期

父组件的生命周期钩子与子组件相似,但父组件的生命周期会受到子组件的影响。在父组件中,子组件的创建、更新和销毁会触发相应的钩子。

  • beforeCreate:在父组件创建前触发,但此时子组件尚未被创建。
  • created:父组件实例已创建,数据和事件已初始化,但尚未挂载到 DOM,此时子组件的实例还未创建。
  • beforeMount:父组件挂载前触发,子组件的实例已经创建,但还未挂载到 DOM。
  • mounted:父组件挂载后触发,子组件的 DOM 元素也已挂载。
  • beforeUpdate:当父组件的响应式数据发生变化并即将更新时触发,但此时子组件的 DOM 尚未更新。
  • updated:当父组件的数据更新并且视图重新渲染后触发,此时子组件的 DOM 已经更新。
  • beforeUnmount:当父组件将要销毁时触发,此时子组件也将销毁。
  • unmounted:当父组件销毁后触发,子组件的销毁也已完成。

2. 子组件生命周期

子组件的生命周期钩子与父组件的类似。子组件的创建和销毁是父组件生命周期的一部分,父组件和子组件的生命周期会有交集:

  • beforeCreate:子组件实例创建前触发,父组件的 beforeCreate 钩子已经执行,但子组件的 datacomputedmethods 尚未初始化。
  • created:子组件实例创建后触发,此时可以访问 dataprops,但尚未挂载到 DOM。此时可以获取初始数据或执行初始化任务。
  • beforeMount:子组件挂载前触发,父组件的 beforeMount 钩子已经执行。
  • mounted:子组件挂载后触发,父组件的 mounted 钩子也已触发。
  • beforeUpdate:子组件在数据发生变化,视图即将更新时触发。
  • updated:子组件在视图更新后触发,父组件的 updated 钩子也已触发。
  • beforeUnmount:子组件将要销毁时触发,父组件的 beforeUnmount 钩子也会被调用。
  • unmounted:子组件销毁后触发,父组件的 unmounted 钩子也会被调用。

父子组件的生命周期交互

1. 父组件传递数据给子组件

父组件通过 props 向子组件传递数据。当父组件的状态发生变化时(例如通过 datacomputed 更新),子组件会重新渲染。这会触发子组件的更新生命周期钩子,如 beforeUpdateupdated

2. 子组件向父组件传递数据

子组件可以通过 $emit 向父组件发送事件,父组件通过监听这些事件来更新自身状态。父组件的状态变化也会影响子组件的渲染。

3. 销毁顺序

当父组件销毁时,子组件会先销毁。父组件的 beforeUnmountunmounted 钩子会在子组件销毁后执行。这是因为 Vue 会先销毁子组件的实例,然后再销毁父组件。

生命周期执行顺序(父子组件)

以下是父子组件生命周期的执行顺序,假设父组件创建了一个子组件:

  1. 父组件:

    • beforeCreate
    • created
    • beforeMount
    • 子组件:
      • beforeCreate
      • created
      • beforeMount
      • mounted
    • mounted
  2. 数据更新(父组件数据变化):

    • 父组件:
      • beforeUpdate
      • updated
    • 子组件:
      • beforeUpdate
      • updated
  3. 销毁:

    • 父组件:
      • beforeUnmount
    • 子组件:
      • beforeUnmount
      • unmounted
    • 父组件:
      • unmounted

示例代码

父组件 (ParentComponent.vue)

vue复制代码<template>
  <div>
    <h1>父组件</h1>
    <child-component :message="message" @updateMessage="updateMessage" />
  </div>
</template>

<script setup>
import { ref, onMounted, onBeforeUnmount } from 'vue'
import ChildComponent from './ChildComponent.vue'

const message = ref('Hello from Parent')

const updateMessage = (newMessage) => {
  message.value = newMessage
}

onMounted(() => {
  console.log('父组件已挂载')
})

onBeforeUnmount(() => {
  console.log('父组件即将销毁')
})
</script>

子组件 (ChildComponent.vue)

vue复制代码<template>
  <div>
    <p>{{ message }}</p>
    <button @click="sendMessage">Update Message</button>
  </div>
</template>

<script setup>
import { ref, onMounted, onBeforeUnmount, defineProps, defineEmits } from 'vue'

const props = defineProps({
  message: String
})

const emit = defineEmits(['updateMessage'])

const sendMessage = () => {
  emit('updateMessage', 'New message from Child')
}

onMounted(() => {
  console.log('子组件已挂载')
})

onBeforeUnmount(() => {
  console.log('子组件即将销毁')
})
</script>

总结

  • 父组件生命周期:在父组件创建、更新、销毁时,会触发与子组件交互的生命周期钩子。
  • 子组件生命周期:子组件生命周期钩子受父组件生命周期的影响,并且子组件也有自己独立的生命周期。
  • 交互与依赖:父组件和子组件之间可以通过 props$emit 实现数据和事件的交互,生命周期钩子可以帮助我们在不同阶段管理这些交互。