当前位置:网站首页>06 【生命周期 模板引用】
06 【生命周期 模板引用】
2022-08-10 09:03:00 【DSelegent】
11.生命周期
vue2

vue3

- Vue3.0中可以继续使用Vue2.x中的生命周期钩子,但有有两个被更名:
beforeDestroy改名为beforeUnmountdestroyed改名为unmounted
- Vue3.0也提供了 Composition API 形式的生命周期钩子,与Vue2.x中钩子对应关系如下:
beforeCreate===>setup()created=======>setup()
在setup比beforeCreate还先执行beforeMount===>onBeforeMountmounted=======>onMountedbeforeUpdate===>onBeforeUpdateupdated=======>onUpdatedbeforeUnmount==>onBeforeUnmountunmounted=====>onUnmounted
关于两个销毁生命周期,可以在组件实例上用v-if打成
所有罗列在下面的 API 都应该在组件的
setup()阶段被同步调用。相关细节请看指南 - 生命周期钩子。
11.1 onBeforeMount#
注册一个钩子,在组件被挂载之前被调用。
类型
function onBeforeMount(callback: () => void): void详细信息
当这个钩子被调用时,组件已经完成了其响应式状态的设置,但还没有创建 DOM 节点。它即将首次执行 DOM 渲染过程。
这个钩子在服务器端渲染期间不会被调用。
11.2 onMounted#
注册一个回调函数,在组件挂载完成后执行。
类型
function onMounted(callback: () => void): void详细信息
组件在以下情况下被视为已挂载:
- 其所有同步子组件都已经被挂载 (不包含异步组件或
<Suspense>树内的组件)。 - 其自身的 DOM 树已经创建完成并插入了父容器中。注意仅当根容器在文档中时,才可以保证组件 DOM 树也在文档中。
这个钩子通常用于执行需要访问组件所渲染的 DOM 树相关的副作用,或是在服务端渲染应用中用于确保 DOM 相关代码仅在客户端执行。
这个钩子在服务器端渲染期间不会被调用。
- 其所有同步子组件都已经被挂载 (不包含异步组件或
示例
通过模板引用访问一个元素:
<script setup> import { ref, onMounted } from 'vue' const el = ref() onMounted(() => { el.value // <div> }) </script> <template> <div ref="el"></div> </template>
11.3 onBeforeUpdate#
注册一个钩子,在组件即将因为响应式状态变更而更新其 DOM 树之前调用。
类型
function onBeforeUpdate(callback: () => void): void详细信息
这个钩子可以用来在 Vue 更新 DOM 之前访问 DOM 状态。在这个钩子中更改状态也是安全的。
这个钩子在服务器端渲染期间不会被调用。
11.4 onUpdated#
注册一个回调函数,在组件因为响应式状态变更而更新其 DOM 树之后调用。
类型
function onUpdated(callback: () => void): void详细信息
父组件的更新钩子将在其子组件的更新钩子之后调用。
这个钩子会在组件的任意 DOM 更新后被调用,这些更新可能是由不同的状态变更导致的。如果你需要在某个特定的状态更改后访问更新后的 DOM,请使用 nextTick() 作为替代。
这个钩子在服务器端渲染期间不会被调用。
警告
不要在 updated 钩子中更改组件的状态,这可能会导致无限的更新循环!
示例
访问更新后的 DOM
<script setup> import { ref, onUpdated } from 'vue' const count = ref(0) onUpdated(() => { // 文本内容应该与当前的 `count.value` 一致 console.log(document.getElementById('count').textContent) }) </script> <template> <button id="count" @click="count++">{ { count }}</button> </template>
11.5 onBeforeUnmount#
注册一个钩子,在组件实例被卸载之前调用。
类型
function onBeforeUnmount(callback: () => void): void详细信息
当这个钩子被调用时,组件实例依然还保有全部的功能。
这个钩子在服务器端渲染期间不会被调用。
11.6 onUnmounted#
注册一个回调函数,在组件实例被卸载之后调用。
类型
function onUnmounted(callback: () => void): void详细信息
一个组件在以下情况下被视为已卸载:
- 其所有子组件都已经被卸载。
- 所有相关的响应式作用 (渲染作用以及
setup()时创建的计算属性和侦听器) 都已经停止。
可以在这个钩子中手动清理一些副作用,例如计时器、DOM 事件监听器或者与服务器的连接。
这个钩子在服务器端渲染期间不会被调用。
示例
<script setup> import { onMounted, onUnmounted } from 'vue' let intervalId onMounted(() => { intervalId = setInterval(() => { // ... }) }) onUnmounted(() => clearInterval(intervalId)) </script>
11.7 onErrorCaptured#
注册一个钩子,在捕获了后代组件传递的错误时调用。
类型
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因这个错误而被调用。
11.8 onActivated#
注册一个回调函数,若组件实例是 `` 缓存树的一部分,当组件被插入到 DOM 中时调用。
这个钩子在服务器端渲染期间不会被调用。
类型
function onActivated(callback: () => void): void
11.9 onDeactivated#
注册一个回调函数,若组件实例是 KeepAlive 缓存树的一部分,当组件从 DOM 中被移除时调用。
这个钩子在服务器端渲染期间不会被调用。
类型
function onDeactivated(callback: () => void): void
11.10 汇总
<template>
<h2>当前求和为:{
{sum}}</h2>
<button @click="sum++">点我+1</button>
</template>
<script>
import {ref,onBeforeMount,onMounted,onBeforeUpdate,onUpdated,onBeforeUnmount,onUnmounted} from 'vue'
export default {
name: 'Demo',
setup(){
console.log('---setup---')
//数据
let sum = ref(0)
//通过组合式API的形式去使用生命周期钩子
onBeforeMount(()=>{
console.log('---onBeforeMount---')
})
onMounted(()=>{
console.log('---onMounted---')
})
onBeforeUpdate(()=>{
console.log('---onBeforeUpdate---')
})
onUpdated(()=>{
console.log('---onUpdated---')
})
onBeforeUnmount(()=>{
console.log('---onBeforeUnmount---')
})
onUnmounted(()=>{
console.log('---onUnmounted---')
})
//返回一个对象(常用)
return {sum}
},
//通过配置项的形式使用生命周期钩子
//#region
beforeCreate() {
console.log('---beforeCreate---')
},
created() {
console.log('---created---')
},
beforeMount() {
console.log('---beforeMount---')
},
mounted() {
console.log('---mounted---')
},
beforeUpdate(){
console.log('---beforeUpdate---')
},
updated() {
console.log('---updated---')
},
beforeUnmount() {
console.log('---beforeUnmount---')
},
unmounted() {
console.log('---unmounted---')
},
//#endregion
}
</script>
12.模板引用
虽然 Vue 的声明性渲染模型为你抽象了大部分对 DOM 的直接操作,但在某些情况下,我们仍然需要直接访问底层 DOM 元素。要实现这一点,我们可以使用特殊的 ref attribute:
<input ref="input">
ref 是一个特殊的 attribute,和 v-for 章节中提到的 key 类似。它允许我们在一个特定的 DOM 元素或子组件实例被挂载后,获得对它的直接引用。这可能很有用,比如说在组件挂载时将焦点设置到一个 input 元素上,或在一个元素上初始化一个第三方库。
12.1 访问模板引用
为了通过组合式 API 获得该模板 ref,我们需要声明一个同名的 ref:
<template>
<input ref="input" />
</template>
<script setup>
import { ref, onMounted } from 'vue'
// 声明一个 ref 来存放该元素的引用
// 必须和模板 ref 同名
const input = ref(null)
onMounted(() => {
input.value.focus()
})
</script>
如果不使用 <script setup>,需确保从 setup() 返回 ref:
<template>
<input ref="input" />
</template>
<script>
import Demo from './components/Demo.vue';
import { onMounted, ref } from 'vue';
export default {
components: { Demo },
name: 'App',
setup() {
// 声明一个 ref 来存放该元素的引用
// 必须和模板 ref 同名
const input = ref(null)
onMounted(() => {
input.value.focus()
})
return {
input
}
},
};
</script>
注意,你只可以在组件挂载后才能访问 ref。如果你想在模板中的表达式上访问 input,在初次渲染时会是 null。这是因为在初次渲染前这个元素还压根不存在呢!
12.2v-for 中的模板引用#
需要 v3.2.25 及以上版本
当在 v-for 中使用模板引用时,对应的 ref 中包含的值是一个数组,它将在元素被挂载后包含对应整个列表的所有元素:
<script setup>
import { ref, onMounted } from 'vue'
const list = ref([1, 2, 3])
const itemRefs = ref([])
onMounted(() => {
alert(itemRefs.value.map(i => i.textContent))
})
</script>
<template>
<ul>
<li v-for="item in list" ref="itemRefs">
{
{ item }}
</li>
</ul>
</template>
应该注意的是,ref 数组并不保证与源数组相同的顺序。
12.3 函数模板引用
除了使用字符串值作名字,ref attribute 还可以绑定为一个函数,会在每次组件更新时都被调用。该函数会收到元素引用作为其第一个参数:
<input :ref="(el) => { /* 将 el 赋值给一个数据属性或 ref 变量 */ }">
注意我们这里需要使用动态的 :ref 绑定才能够传入一个函数。当绑定的元素被卸载时,函数也会被调用一次,此时的 el 参数会是 null。你当然也可以绑定一个组件方法而不是内联函数。
12.4 组件上的 ref
模板引用也可以被用在一个子组件上。这种情况下引用中获得的值的是组件实例:
<script setup>
import { ref, onMounted } from 'vue'
import Child from './Child.vue'
const child = ref(null)
onMounted(() => {
// child.value 是 <Child /> 组件的实例
})
</script>
<template>
<Child ref="child" />
</template>
如果一个子组件使用的是选项式 API 或没有使用 <script setup>,被引用的组件实例和该子组件的 this 完全一致,这意味着父组件对子组件的每一个属性和方法都有完全的访问权。这使得在父组件和子组件之间创建紧密耦合的实现细节变得很容易,当然也因此,应该只在绝对需要时才使用组件引用。大多数情况下,你应该首先使用标准的 props 和 emit 接口来实现父子组件交互。
有一个例外的情况,使用了 <script setup> 的组件是默认私有的:一个父组件无法访问到一个使用了 <script setup> 的子组件中的任何东西,除非子组件在其中通过 defineExpose 宏显式暴露:
<script setup>
import { ref } from 'vue'
const a = 1
const b = ref(2)
defineExpose({
a,
b
})
</script>
当父组件通过模板引用获取到了该组件的实例时,得到的实例类型为 { a: number, b: number } (ref 都会自动解包,和一般的实例一样)。
TypeScript 用户请参考:为组件的模板引用标注类型
边栏推荐
- PTA 习题2.2 数组循环左移
- DAY25:逻辑漏洞复现
- J9 digital science: Web 3.0 is about data ownership or decentralized?
- Flink运行时架构 完整使用 (第四章)
- shell遍历文件夹并输出
- 【微服务架构】为故障设计微服务架构
- Mongo的简单操作-数据库用户的查询、创建与删除
- 不想再干会计了,蝶变向新,勇往直前,最后成功通过转行测试实现月薪翻倍~
- iwemeta metaverse: a doll sells for 9999 yuan, and Bubble Mart thinks it is not expensive at all
- CAD转WPF: 关于CAD图纸文件转换为WPF矢量代码文件(xaml文件)的技巧
猜你喜欢
随机推荐
Spotify使用C4模型表达其架构设计
The first offline workshop in 2022!Data application experience day for application developers is coming | TiDB Workshop Day
对称加密与非对称加密的区别
It is obvious that a unique index is added, why does it still generate duplicate data?
Unity—UGUI control
【数据架构】分布式数据网格作为集中式数据单体的解决方案
DataStream API(基础篇) 完整使用 (第五章)
多线程知识点总结之温故而知新
PTA 习题2.1 简单计算器
不想再干会计了,蝶变向新,勇往直前,最后成功通过转行测试实现月薪翻倍~
线程池的基本概念、结构、类
2 模块一:科研思维培养
Question brushing tool h
Guys, may I ask, the oraclecdc error report is not serialized, but I see that the source code does not inherit serialization, what is the reason?
J9数字论:关于DAO 特点的宏观分析
速卖通卖家如何抓住产品搜索权重
m.bjhjwy.com全面教学设备 类型包括: 教学仪器, 教学设备 ,
多线程浅谈
设计分享|基于单片机的从左到右流水灯
Compilation failure:找不到符号




![[System Design] S3 Object Storage](/img/62/0e3fef066b06ba83cadb406cfa075b.png)




