<script type="importmap">
  { "imports": { "vue": "https://unpkg.com/vue@3/dist/vue.esm-browser.js" } }
</script>

<script type="module">
  import {
    createApp,
    ref,
    watch,
    nextTick,
    onMounted,
    onUpdated,
    onUnmounted,
    onBeforeMount,
    onBeforeUpdate,
    onBeforeUnmount,
    onErrorCaptured,
    onRenderTracked,
    onRenderTriggered,
    onActivated,
    onDeactivated,
    onServerPrefetch,
  } from "vue";
  
  const LifeCycle = {
    setup() {
      /* First render */
      console.log("setup");
      onBeforeMount(() => console.log("onBeforeMount"));
      onRenderTracked(() => console.log("onRenderTracked")); // Dev Only
      onMounted(() => console.log("onMounted"));
      
      /* Re-render */
      onRenderTriggered(() => console.log("onRenderTriggered")); // Dev Only
      onBeforeUpdate(() => {
        console.log("onBeforeUpdate")
        nextTick().then(() => console.log("nextTick() resolved"))
        // nextTick() will resolve after `onUpdated`
      });
      onUpdated(() => console.log("onUpdated"));
      
      /* Unmount */
      onBeforeUnmount(() => console.log("onBeforeUnmount"));
      onUnmounted(() => console.log("onUnmounted"));
      
      /* Others */
      onErrorCaptured(() => console.log("onErrorCaptured"));
      onActivated(() => console.log("onActivated"));
      onDeactivated(() => console.log("onDeactivated"));
      onServerPrefetch(() => console.log("onServerPrefetch"));
      
      /* States */
      const msg = ref("msg");
      // after `onRenderTriggered`, before `onBeforeUpdate`
      watch(msg, (msg) => console.log(`watch ${msg}`))
      
      return { msg };
    },
    // ref: before `onMounted` `onUpdated` `onUnmounted`
    template: `<p :ref="() => console.log('ref')">{{ msg }}</p>
               <input v-model="msg"/>`,
  };
  
  const app = createApp({
    components: { LifeCycle },
    setup() {
      const mount = ref(false);
      return { mount };
    },
    template: `
<main style="display:grid;grid-template-columns:1fr 1fr">
    <article style="outline:solid 1px">
        <a 
          href="https://cn.vuejs.org/api/composition-api-lifecycle.html"
          target="blank">
            <h1>Vue LifeCycle</h1>
            <img 
              src="https://i1.wp.com/cn.vuejs.org/assets/lifecycle_zh-CN.W0MNXI0C.png"
              style="display:block;max-width:100%" />
        </a>
    </article>
    <aside style="padding:1rem 2rem">
        <button @click="mount=!mount">
            Click me to {{ mount ? 'UNMOUNT' : 'MOUNT' }} the component
        </button>
        <LifeCycle v-if="mount" />
    </aside>
</main>`,
  })
  .mount("#app");
</script>

<div id="app" />
body {margin:0}

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.