vue2
vue3
beforeDestroy
改名为 beforeUnmount
destroyed
改名为 unmounted
beforeCreate
===>setup()
created
=======>setup()
beforeMount
===>onBeforeMount
mounted
=======>onMounted
beforeUpdate
===>onBeforeUpdate
updated
=======>onUpdated
beforeUnmount
==>onBeforeUnmount
unmounted
=====>onUnmounted
关于两个销毁生命周期,可以在组件实例上用v-if打成
所有罗列在下面的 API 都应该在组件的
setup()
阶段被同步调用。相关细节请看指南 - 生命周期钩子。
注册一个钩子,在组件被挂载之前被调用。
类型
function onBeforeMount(callback: () => void): void
详细信息
当这个钩子被调用时,组件已经完成了其响应式状态的设置,但还没有创建 DOM 节点。它即将首次执行 DOM 渲染过程。
这个钩子在服务器端渲染期间不会被调用。
注册一个回调函数,在组件挂载完成后执行。
类型
function onMounted(callback: () => void): void
详细信息
组件在以下情况下被视为已挂载:
树内的组件)。这个钩子通常用于执行需要访问组件所渲染的 DOM 树相关的副作用,或是在服务端渲染应用中用于确保 DOM 相关代码仅在客户端执行。
这个钩子在服务器端渲染期间不会被调用。
示例
通过模板引用访问一个元素:
注册一个钩子,在组件即将因为响应式状态变更而更新其 DOM 树之前调用。
类型
function onBeforeUpdate(callback: () => void): void
详细信息
这个钩子可以用来在 Vue 更新 DOM 之前访问 DOM 状态。在这个钩子中更改状态也是安全的。
这个钩子在服务器端渲染期间不会被调用。
注册一个回调函数,在组件因为响应式状态变更而更新其 DOM 树之后调用。
类型
function onUpdated(callback: () => void): void
详细信息
父组件的更新钩子将在其子组件的更新钩子之后调用。
这个钩子会在组件的任意 DOM 更新后被调用,这些更新可能是由不同的状态变更导致的。如果你需要在某个特定的状态更改后访问更新后的 DOM,请使用 nextTick() 作为替代。
这个钩子在服务器端渲染期间不会被调用。
警告
不要在 updated 钩子中更改组件的状态,这可能会导致无限的更新循环!
示例
访问更新后的 DOM
注册一个钩子,在组件实例被卸载之前调用。
类型
function onBeforeUnmount(callback: () => void): void
详细信息
当这个钩子被调用时,组件实例依然还保有全部的功能。
这个钩子在服务器端渲染期间不会被调用。
注册一个回调函数,在组件实例被卸载之后调用。
类型
function onUnmounted(callback: () => void): void
详细信息
一个组件在以下情况下被视为已卸载:
setup()
时创建的计算属性和侦听器) 都已经停止。可以在这个钩子中手动清理一些副作用,例如计时器、DOM 事件监听器或者与服务器的连接。
这个钩子在服务器端渲染期间不会被调用。
示例
注册一个钩子,在捕获了后代组件传递的错误时调用。
类型
function onErrorCaptured(callback: ErrorCapturedHook): void
type ErrorCapturedHook = (
err: unknown,
instance: ComponentPublicInstance | null,
info: string
) => boolean | void
详细信息
错误可以从以下几个来源中捕获:
setup()
函数这个钩子带有三个实参:错误对象、触发该错误的组件实例,以及一个说明错误来源类型的信息字符串。
你可以在 errorCaptured()
中更改组件状态来为用户显示一个错误状态。注意不要让错误状态再次渲染导致本次错误的内容,否则组件会陷入无限循环。
这个钩子可以通过返回 false
来阻止错误继续向上传递。请看下方的传递细节介绍。
错误传递规则
app.config.errorHandler
(前提是这个函数已经定义),这样这些错误都能在一个统一的地方报告给分析服务。errorCaptured
钩子,对于同一个错误,这些钩子会被按从底至上的顺序一一调用。这个过程被称为“向上传递”,类似于原生 DOM 事件的冒泡机制。errorCaptured
钩子本身抛出了一个错误,那么这个错误和原来捕获到的错误都将被发送到 app.config.errorHandler
。errorCaptured
钩子可以通过返回 false
来阻止错误继续向上传递。即表示“这个错误已经被处理了,应当被忽略”,它将阻止其他的 errorCaptured
钩子或 app.config.errorHandler
因这个错误而被调用。注册一个回调函数,若组件实例是 `` 缓存树的一部分,当组件被插入到 DOM 中时调用。
这个钩子在服务器端渲染期间不会被调用。
类型
function onActivated(callback: () => void): void
注册一个回调函数,若组件实例是 KeepAlive
缓存树的一部分,当组件从 DOM 中被移除时调用。
这个钩子在服务器端渲染期间不会被调用。
类型
function onDeactivated(callback: () => void): void
beforeCreate
,其他12个生命周期的 this 都能获得组件实例对应初始化完成的内容。beforeUpdate()
永远只在所有父子组件的 mounted()
之后才会触发!
这是登陆页面{{username}}{{password}}
父组件的前4个声明周期执行完后,开始执行子组件的前7个生命周期,执行完毕后,再接着开始执行父组件的mounted()生命周期。
虽然 Vue 的声明性渲染模型为你抽象了大部分对 DOM 的直接操作,但在某些情况下,我们仍然需要直接访问底层 DOM 元素。要实现这一点,我们可以使用特殊的 ref
attribute:
ref
是一个特殊的 attribute,和 v-for
章节中提到的 key
类似。它允许我们在一个特定的 DOM 元素或子组件实例被挂载后,获得对它的直接引用。这可能很有用,比如说在组件挂载时将焦点设置到一个 input 元素上,或在一个元素上初始化一个第三方库。
为了通过组合式 API 获得该模板 ref,我们需要声明一个同名的 ref:
如果不使用 ,需确保从
setup()
返回 ref:
注意,你只可以在组件挂载后才能访问 ref。如果你想在模板中的表达式上访问 input
,在初次渲染时会是 null
。这是因为在初次渲染前这个元素还压根不存在呢!
v-for
中的模板引用#需要 v3.2.25 及以上版本
当在 v-for
中使用模板引用时,对应的 ref 中包含的值是一个数组,它将在元素被挂载后包含对应整个列表的所有元素:
-
{{ item }}
应该注意的是,ref 数组并不保证与源数组相同的顺序。
除了使用字符串值作名字,ref
attribute 还可以绑定为一个函数,会在每次组件更新时都被调用。该函数会收到元素引用作为其第一个参数:
注意我们这里需要使用动态的 :ref
绑定才能够传入一个函数。当绑定的元素被卸载时,函数也会被调用一次,此时的 el
参数会是 null
。你当然也可以绑定一个组件方法而不是内联函数。
配置v-for
{{ item }}
模板引用也可以被用在一个子组件上。这种情况下引用中获得的值的是组件实例:
如果一个子组件使用的是选项式 API 或没有使用 ,被引用的组件实例和该子组件的
this
完全一致,这意味着父组件对子组件的每一个属性和方法都有完全的访问权。这使得在父组件和子组件之间创建紧密耦合的实现细节变得很容易,当然也因此,应该只在绝对需要时才使用组件引用。大多数情况下,你应该首先使用标准的 props 和 emit 接口来实现父子组件交互。
有一个例外的情况,使用了 的组件是默认私有的:一个父组件无法访问到一个使用了
的子组件中的任何东西,除非子组件在其中通过
defineExpose
宏显式暴露:
当父组件通过模板引用获取到了该组件的实例时,得到的实例类型为 { a: number, b: number }
(ref 都会自动解包,和一般的实例一样)。
TypeScript 用户请参考:为组件的模板引用标注类型
vue3新特性,如果是options api类型的组件,不声明 expose
时,默认暴露当前组件实例的全部内容,声明了 expose
选项, expose 数组内标记的才会暴露。(expose:[]
则什么都不暴露,注意这个问题。也可以利用这个特性提高组件使用的规范。)
export default defineComponent({
expose:['nameA',...],// 可以 expose 当前实例的任何内容
methods:{
nameA(){}
}
})
setup语法糖的情况下,默认是封闭的,需要获取当前组件里的内容的话,必须显式expose出去
<script lang='ts' setup>
import {ref} from 'vue';
let refData = ref('data')
defineExpose({
refData,
})
</script>
TS类型:
import { ref,Ref } from "vue";
//> defineExpose
interface exFace {
ex1:Ref<string>,
ex2?:number
}
let ex1 = ref('1')
let exObj:exFace = {
ex1,
}
// 源码类型: const defineExpose: (exposed?: Record) => void
defineExpose(exObj)