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