文章目錄
- 1. ref是什么
- 2. ref的使用
- 3. ref的特性
- 4. 使用場景
- 5. 注意事項
- 6. 與 React 的對比
- 7. 動態 ref
- 8. 函數式組件中的 ref
- 9. 組合式 API 中的 ref
- 10. 總結
1. ref是什么
ref 被用來給元素或子組件注冊引用信息。引用信息將會注冊在父組件的 $refs 對象上。可以通過實例對象獲取到后進行一些操作。
- 如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素
<div ref="divRef">hello</div>
- 如果用在子組件上,引用就指向組件實例
<list-component ref="listRef"></list-component>
- 如果在v-for循環中使用了ref,引用指向的就是數組類型。
<div v-for="item in list" :ref="item.xxx"></div>
2. ref的使用
在給組件綁定ref=xxx的屬性后,通過this.$refs.xxx,就可以獲取到組件的實例,進而可以操作組件的方法,獲取到屬性,如下例子,通過獲取到list組件的實例,得到了組件內部的xxx屬性。
- 普通ref
<list-component ref="listRef"></list-component>console.log(this.$refs.listRef.xxx)
- 循環里的ref
如果在v-for循環中使用了ref,引用指向的就是數組類型,為了確保唯一性,可以使用id拼接的方式。
<div v-for="item in list" :ref="`ref${item.id}`"></div>console.log(this.$refs[`ref${item.id}`])
3. ref的特性
- 非響應式:
$refs
對象不會觸發視圖更新,即便引用的元素或者組件有了變化。 - 延遲更新:
$refs
是在 DOM 更新結束之后才會進行更新的,所以在初始化階段或者數據變更時,直接訪問$refs
可能無法獲取到最新的引用。 - 生命周期鉤子:在
mounted
鉤子函數里訪問$refs
是比較穩妥的,因為這時 DOM 已經完成了首次渲染。
4. 使用場景
- DOM 操作:
// 聚焦輸入框this.$refs.inputRef.focus()// 滾動到特定元素this.$refs.scrollContainer.scrollTop = 100
- 調用子組件方法:
// 調用子組件的刷新方法this.$refs.childComponent.refreshData()
- 訪問子組件屬性:
// 獲取子組件的內部狀態const count = this.$refs.counterComponent.count
5. 注意事項
- 避免濫用:應當優先考慮使用數據綁定或者事件機制來實現組件間的通信,只有在確實需要直接操作 DOM 或者組件實例時才使用
ref
。 - 異步更新:由于 Vue 的 DOM 更新是異步進行的,所以在修改數據之后立即訪問
$refs
可能無法獲取到更新后的 DOM。這種情況下,可以使用this.$nextTick()
來確保 DOM 已經更新完畢。this.list = [...newList] this.$nextTick(() => {// 此時可以獲取到更新后的 ref 列表console.log(this.$refs.itemRefs) })
6. 與 React 的對比
在 React 中,ref
的使用方式和 Vue 既有相似之處,也存在差異:
-
創建方式:
// Vue <div ref="myDiv"></div>// React <div ref={this.myRef}></div>
-
類型區別:
- 在 Vue 里,
ref
可以直接指向 DOM 元素或者組件實例。 - 在 React 中,
ref
可以是一個回調函數,也可以是通過createRef()
創建的對象。
- 在 Vue 里,
-
訪問方法:
// Vue this.$refs.myDiv// React this.myRef.current
7. 動態 ref
借助動態綁定的方式,可以實現 ref
的動態管理:
<component :ref="dynamicRefName"></component>// 在不同條件下使用不同的 ref
this.dynamicRefName = condition ? 'refA' : 'refB'
8. 函數式組件中的 ref
函數式組件沒有自己的實例,所以在使用 ref
時會指向其渲染的根節點:
// 函數式組件
const FunctionalComp = {functional: true,render(h, context) {return <div>Functional Component</div>}
}// 使用 ref 獲取根 DOM
<FunctionalComp ref="funcRef" />
this.$refs.funcRef // 指向 <div> 元素
9. 組合式 API 中的 ref
在組合式 API 里,可以通過 defineExpose
來暴露組件的屬性和方法:
<template><button ref="btnRef" @click="handleClick">Click</button>
</template><script setup>
import { ref, onMounted } from 'vue'const btnRef = ref(null)const handleClick = () => {console.log('Button clicked')
}// 暴露給父組件
defineExpose({handleClick
})onMounted(() => {btnRef.value.focus()
})
</script>
10. 總結
ref
是 Vue 提供的一種直接操作 DOM 或者組件實例的方式。- 要注意
ref
的非響應式特性以及延遲更新的特點。 - 建議在必要的場景下使用
ref
,并優先采用聲明式的數據綁定。 - 在組合式 API 中,可以使用
defineExpose
有選擇性地暴露組件的方法和屬性。
本次分享就到這兒啦,我是鵬多多,如果您看了覺得有幫助,歡迎評論,關注,點贊,轉發,我們下次見~
往期文章
- css使用aspect-ratio制作4:3和9:16和1:1等等比例布局
- Web前端頁面開發阿拉伯語種適配指南
- flutter-使用extended_image操作圖片的加載和狀態處理以及緩存和下載
- flutter-制作可縮放底部彈出抽屜評論區效果
- flutter-實現Tabs吸頂的PageView效果
- Vue2全家桶+Element搭建的PC端在線音樂網站
- 助你上手Vue3全家桶之Vue3教程
- 超詳細!vue組件通信的10種方式
- 超詳細!Vuex手把手教程
- 使用nvm管理node.js版本以及更換npm淘寶鏡像源
- vue中利用.env文件存儲全局環境變量,以及配置vue啟動和打包命令
個人主頁
- CSDN
- GitHub
- 掘金