Vue3钩子函数用法介绍(一文详解Vue3.x)

一、生命周期钩子函数

Vue3与Vue2有一个很大的变化就是将beforeCreate和created两个生命周期函数合并为一个新的setup函数。setup函数是在组件创建之前被调用的。

import { defineComponent, onBeforeMount, onMounted } from 'vue';

export default defineComponent({
  setup() {
    onBeforeMount(() => {
      // 组件加载中...
    });

    onMounted(() => {
      // 组件已经加载完毕
    });

    return {};
  }
});

在Vue3中onBeforeMount和onMounted是两个新添加的函数,它们可以分别代替Vue2中的beforeCreate和mounted函数。

除了onBeforeMount和onMounted之外,还有许多其他的生命周期钩子函数,下面对它们进行一一介绍。

1.1、onBeforeMount

在组件挂载到DOM之前调用。此阶段我们可以访问组件实例化时传入的属性,并可以修改一些属性来确保组件渲染时的正确性。

import { onBeforeMount } from 'vue';

export default {
  setup(props) {
    onBeforeMount(() => {
      // 使用组件传入的属性props
      console.log(props);

      // 修改props属性
      props.count += 1;
    });

    return {};
  }
};

1.2、onMounted

在组件挂载到DOM后调用。当组件实例被创建、并且挂载到 DOM 上时,这个钩子函数将被调用。可以在这里进行一些初始化的 DOM 依赖,在需要的时候进行销毁。

import { onMounted } from 'vue';

export default {
  setup(props) {
    onMounted(() => {
      // DOM操作和初始化
      console.log('Component Mounted');
    });

    return {};
  }
};

1.3、onBeforeUpdate

在数据更新但是在重新渲染之前被调用。典型的用例是在更新之前取消对以前请求的未决承诺或使用以前的 DOM 作为参考点计算新的初始状态。

import { onBeforeUpdate } from 'vue';

export default {
  setup(props) {
    onBeforeUpdate(() => {
      // 在数据更新但是在重新渲染之前调用
      console.log('Update Before Update');
    });

    return {};
  }
};

1.4、onUpdated

在数据更改导致虚拟 DOM 重新渲染并应用更新后调用。此钩子函数在组件更新后被调用,当你想要操作组件的状态时非常有用。

import { onUpdated, ref } from 'vue';

export default {
  setup(props) {
    const count = ref(props.count);

    onUpdated(() => {
      console.log(`Count value after update is ${count.value}`);
    });

    return { count };
  }
};

1.5、onBeforeUnmount

在组件卸载之前调用。我们可以在这个钩子函数中完成一些组件卸载之前需要的操作。

import { onBeforeUnmount } from 'vue';

export default {
  setup(props) {
    onBeforeUnmount(() => {
      // 在组件卸载之前调用
      console.log('Component Before Unmount');
    });

    return {};
  }
};

1.6、onUnmounted

在该组件卸载并且其对应的 DOM 元素被删除后调用。同样,你可以在这里做一些组件卸载后的清理的操作。

import { onUnmounted } from 'vue';

export default {
  setup(props) {
    onUnmounted(() => {
      // 在组件卸载并且其对应的 DOM 元素被删除后调用
      console.log('Component Unmount');
    });

    return {};
  }
};

二、异步钩子函数

异步钩子函数是在组件实例化完毕后,在生命周期钩子函数被调用之前异步执行的回调函数。在Vue3中,引入了一个新的异步钩子函数–onMountedAsync。

import { onMountedAsync } from 'vue';

export default {
    setup(props) {
      onMountedAsync(async () => {
        await someOperation()
        console.log('Mounted has been called');
      });
  
      return {}
    }
};

值得注意的是,异步钩子函数不会影响组件创建周期钩子的执行,而且他的返回值不会对组件的状态有任何影响。这样就可以在组件创建后,异步地做一些操作,并且在控制台看到输出,这对于进行测试是非常有帮助的。

三、watchEffect钩子函数

Vue2中的watch可以实现对属性的监听,使用户操作可以自动更新相应的数据,但是Vue2中watch函数的写法比较笨重。在Vue3中引入了watchEffect钩子函数,可以让我们更加方便地对数据进行监听。

import { watchEffect } from 'vue';

export default {
  setup(props) {
    watchEffect(() => {
      console.log(props.count);
    });

    return {};
  }
};

watchEffect拥有响应式上下文,值得注意的是,这里不用自行监听属性值的变化,Vue会自动处理这个过程。

四、provide&inject钩子函数

Vue2中prop和event是父子组件传递数据和通信的方式,但是prop在跨层级时不太好用。在Vue3中,我们可以用provide和inject向所有的后代节点注入一个依赖。

// 父组件
import { provide } from 'vue';
import Child from './child';

export default {
  setup() {
    provide('data', 'provide&inject');
    return {};
  }
}

// 子组件
import { inject } from 'vue';

export default {
  setup() {
    const data = inject('data');
    console.log(data); // 'provide&inject'
    return {};
  }
};

在provide中,第一个参数是我们需要共享的变量名,在后代组件使用inject时,也需要传入这个变量名,这样就可以获取前代组件传递过来的数据。

五、computed&watch钩子函数

Vue3中,computed和watch函数的使用方式与Vue2中非常相似。

5.1、computed

在setup中使用computed函数。

import { computed } from 'vue';

export default {
  setup() {
    const count = ref(0);
    const double = computed(() => count.value * 2);

    return {
      count,
      double
    };
  }
};

在模板中进行使用。

<template>
   <h1>{{ count }}</h1>
   <h1>{{ double }}</h1>
</template>

computed能够帮助我们派生一个值,然后让这个值与其它值进行绑定,当绑定的值发生变化时,computed函数也会自动更新。

5.2、watch

跟Vue2中一样,watch函数可以用来监听某个属性的变化。

import { watch } from 'vue';

export default {
  props: {
    count: {
      type: Number,
      default: 0
    }
  },
  setup(props) {
    watch(() => props.count, (newCount, oldCount) => {
      console.log(`Count changed from ${oldCount} to ${newCount}`);
    });

    return {};
  }
};

在这个例子中,当props.count的值发生变化时,watch函数会被触发。

六、onRenderTracked&onRenderTriggered钩子函数

onRenderTracked和onRenderTriggered这两个函数都是Vue3中跟追踪渲染响应式依赖相关的 API,这两个函数可以用来分析组件何时被重新渲染,以及渲染的原因是什么。

6.1、onRenderTracked

onRenderTracked函数会在组件渲染时被调用。它的第一个参数是一个 fn。

import { onRenderTracked } from 'vue';

export default {
  setup() {
    onRenderTracked((event) => {
      console.log(`Component rendered in ${event.duration}ms`);
    });

    return {};
  }
};

在这个例子中,我们可以获取组件渲染的耗时。

6.2、onRenderTriggered

onRenderTriggered会在渲染器重新渲染之前被调用。可以用来跟踪重新渲染的原因。

import { onRenderTriggered } from 'vue';

export default {
  setup() {
    onRenderTriggered((event) => {
      const reasons = event.why;
      console.log(`Component re-rendered by ${reasons}`);
    });

    return {};
  }
};

结语

在Vue3中,钩子函数绝不仅仅是生命周期函数,还有许多其他类型的钩子函数。大家可以根据自己的需要挑选适合自己的钩子函数,提高开发效率。同时也要注意不要滥用钩子函数,否则会导致代码可读性的下降。

Published by

风君子

独自遨游何稽首 揭天掀地慰生平