EP13 - 模板參照

閱讀時間約 1 分鐘
Template Refs 模板參照是什麼東西啊?
我倒是很需要模板!希望可以重複使用啊~
不知道是不是這個東西?

雖然 Vue 的聲明式渲染模型為您抽象了大部分的直接 DOM 操作,但仍然可能有需要直接訪問底層 DOM 元素的情況。為了實現這一點,我們可以使用特殊的 ref 屬性:

<template>
<input ref="input">
</template>

ref 是一個特殊屬性,類似於在 v-for 章節中討論的 key 屬性。它允許我們在元素或子組件實例被掛載後獲得對特定 DOM 元素或子組件實例的直接參照。例如,在您需要在組件掛載時程序化地聚焦輸入框,或在元素上初始化第三方庫時非常有用。

訪問模板參照 - Accessing the Refs​

使用 Composition API 獲取參照時,我們可以使用 useTemplateRef() 3.5+助手:

<script setup>
import { useTemplateRef, onMounted } from 'vue'

// 第一個參數必須與模板中的 ref 值匹配
const input = useTemplateRef('my-input')

onMounted(() => {
input.value.focus()
})
</script>

<template>
<input ref="my-input" />
</template>

使用 TypeScript 時,Vue 的 IDE 支援和 vue-tsc 會根據 ref 屬性使用的元素或組件,自動推斷 inputRef.value 的類型。

3.5 版本之前的用法

在 3.5 版本之前,useTemplateRef() 尚未引入,我們需要宣告一個名稱與模板 ref 屬性值匹配的 ref

<script setup>
import { ref, onMounted } from 'vue'

// 宣告一個 ref 來保存元素參照
// 名稱必須與模板 ref 值匹配
const input = ref(null)

onMounted(() => {
input.value.focus()
})
</script>

<template>
<input ref="input" />
</template>

如果不使用 <script setup>,請確保在 setup() 中返回 ref

export default {
setup() {
const input = ref(null)
// ...
return {
input
}
}
}

請注意,您只能在組件掛載後訪問參照。如果您嘗試在模板表達式中訪問 input,它在第一次渲染時會是 null。這是因為元素只有在第一次渲染後才存在!

如果您嘗試監視模板參照的變化,請確保考慮到參照值為 null 的情況:

watchEffect(() => {
if (input.value) {
input.value.focus()
} else {
// 還未掛載,或者元素被卸載(例如通過 v-if)
}
})

另請參見:模板參照的類型定义

v-for 中的參照 - Refs inside v-for​

需要 v3.2.25 或更高版本

ref 用於 v-for 時,對應的 ref 應該包含一個數組值,該數組在掛載後將填充元素:

<script setup>
import { ref, useTemplateRef, onMounted } from 'vue'

const list = ref([
/* ... */
])

const itemRefs = useTemplateRef('items')

onMounted(() => console.log(itemRefs.value))
</script>

<template>
<ul>
<li v-for="item in list" ref="items">
{{ item }}
</li>
</ul>
</template>

在 3.5 版本之前的使用情況

<script setup>
import { ref, onMounted } from 'vue'

const list = ref([
/* ... */
])

const itemRefs = ref([])

onMounted(() => console.log(itemRefs.value))
</script>

<template>
<ul>
<li v-for="item in list" ref="itemRefs">
{{ item }}
</li>
</ul>
</template>

需要注意的是,ref 數組並不保證與源數組具有相同的順序。

函數參照 - Function Refs​

除了使用字串鍵,ref 屬性也可以綁定到一個函數,該函數會在每次組件更新時被調用,並允許您完全靈活地選擇將元素引用存儲在何處。該函數會接收元素引用作為第一個參數:

<template>
<input :ref="(el) => { /* 將 el 指派給某個屬性或 ref */ }">
</template>

注意,我們使用了一個動態的 :ref 綁定,因此可以傳遞一個函數而不是 ref 名稱字串。當元素卸載時,參數將為 null。當然,您也可以使用一個方法來代替內聯函數。

在組件上使用參照 - Ref on Component​

這部分假設您已經具備組件的相關知識。如果沒有,可以跳過,稍後再回來閱讀。

ref 也可以用在子組件上。在這種情況下,ref 將引用子組件實例:

<script setup>
import { useTemplateRef, onMounted } from 'vue'
import Child from './Child.vue'

const childRef = useTemplateRef('child')

onMounted(() => {
// childRef.value 將持有 <Child /> 的實例
})
</script>

<template>
<Child ref="child" />
</template>

3.5 之前的用法:

<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>

如果子組件使用 Options API 或沒有使用 <script setup>,那麼引用的實例將與子組件的 this 相同,這意味著父組件可以完全訪問子組件的每個屬性和方法。這使得在父子組件之間創建緊密耦合的實現細節變得容易,因此應僅在絕對需要時使用組件 ref。在大多數情況下,您應該首先嘗試使用標準的 propsemit 接口來實現父子交互。

這裡有一個例外:使用 <script setup> 的組件默認是私有的:父組件引用使用 <script setup> 的子組件時,無法訪問任何內容,除非子組件選擇使用 defineExpose 宏來暴露公共接口:

<script setup>
import { ref } from 'vue'

const a = 1
const b = ref(2)

// 編譯器宏(如 defineExpose)不需要被導入
defineExpose({
a,
b
})
</script>

當父組件通過模板 ref 獲得此組件的實例時,取回的實例將是 { a: number, b: number } 的形狀(ref 將自動解包,就像在正常實例上一樣)。

另見:組件模板 Refs 的類型化

Q:總結一下tempelate跟ref關係?

<template>ref 在 Vue 中有著密切的關係,因為 ref 通常是在模板中使用來獲取對 DOM 元素或子組件實例的引用。這兩者的關係可以總結如下:

templateref 的關係

1. 定義模板結構

  • <template> 標籤用來定義 Vue 組件的 HTML 結構,這是組件的視圖部分。
  • 在模板內部,你可以使用標準的 HTML 標籤以及 Vue 的指令來構建組件的界面。

2. 引用 DOM 元素

  • ref 是一個特殊屬性,當應用於模板中的 DOM 元素時,Vue 會在組件掛載後將該元素的引用存儲到相應的變量中。
  • 例如,<input ref="inputElement"> 會讓你在組件邏輯中使用 this.$refs.inputElement(或在 Composition API 中使用 ref 變量)來訪問該輸入框元素。

3. 引用子組件

  • ref 也可以用於子組件,允許你在父組件中直接訪問子組件實例及其方法和屬性。
  • 例如,<ChildComponent ref="childComponent"> 會讓你在父組件中使用 this.$refs.childComponent 來訪問子組件的實例。

示例代碼

以下是一個簡單的示例,展示了如何在模板中使用 ref 來引用 DOM 元素和子組件:

<template>
<div>
<!-- 引用 DOM 元素 -->
<input ref="inputElement" placeholder="Type something" />
<!-- 引用子組件 -->
<ChildComponent ref="childComponent" />
</div>
</template>

<script>
import { ref, onMounted } from 'vue'
import ChildComponent from './ChildComponent.vue'

export default {
components: { ChildComponent },
setup() {
// 使用 ref 來保存 DOM 元素的引用
const inputElement = ref(null)
// 使用 ref 來保存子組件實例的引用
const childComponent = ref(null)

onMounted(() => {
// 可以在組件掛載後訪問這些引用
console.log(inputElement.value) // DOM 元素
console.log(childComponent.value) // 子組件實例
})

return {
inputElement,
childComponent
}
}
}
</script>
  • <template>:用於定義組件的視圖結構,包括 HTML 和 Vue 指令。
  • ref:用於獲取模板中 DOM 元素或子組件實例引用,從而在組件邏輯中進行操作。

透過在模板中使用 ref 屬性,你可以在 Vue 組件中輕鬆地訪問和操作具體的 DOM 元素或子組件,實現更靈活的交互和控制。

不知道是不是週末的關係?這邊怎麼看的霧濛濛www
太想放假了!各位週末愉快~
希望下次再來看這些文件會更熟一點www
avatar-img
2會員
70內容數
分享生活趣事~
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
卡關的人生 的其他內容
在 Vue.js 中,watch 是用來監控數據變化並執行副作用的工具。副作用指的是函數對外部狀態的變更,例如更新 DOM、進行網絡請求或修改全局變量。watch 允許我們在數據變化時自動響應,這對於處理異步操作和更新狀態非常有用。它也支持深層監聽和清理功能,能夠應對複雜的副作用場景。
在這篇文章中,探討了 Vue 組件的生命周期鉤子以及它們在不同階段的應用。每個 Vue 組件在創建時,會經歷一系列初始化步驟,這些步驟中會執行特定的生命週期鉤子函數,例如 onMounted、onUpdated 和 onUnmounted 等。這些鉤子允許開發者在組件的特定階段插入自定義代碼。
使用 v-bind 可以將 HTML 屬性、樣式或類別綁定到 Vue 的數據,實現單向數據綁定。而 v-model 則是用於表單元素的雙向數據綁定,使輸入和數據同步更新。使用 v-bind 可以讓我們綁定非字符串值,例如布爾值或對象,從而在處理更複雜的應用場景時更為靈活。
Vue.js 的事件修飾符提供了一種簡化和直觀的方式來處理事件。與傳統 JavaScript 中需要手動檢查條件和處理事件相比,Vue 的修飾符(如 .prevent、.stop、.enter)使代碼更加清晰和易於管理。這些修飾符直接在模板中指定事件行為,減少了樣板代碼,提升了可讀性。
v-for 用於渲染陣列或物件列表,支持索引和嵌套。使用 key 來提高渲染效率。v-if 和 v-for 不應同時在同一節點上使用。
Conditional Rendering 根據條件決定是否渲染元素。Vue.js 的 v-if 在條件為真時渲染,v-else-if 處理額外條件,v-show 始終渲染元素但用 CSS 控制顯示。v-if 會創建或銷毀元素,v-show 只改變顯示樣式。
在 Vue.js 中,watch 是用來監控數據變化並執行副作用的工具。副作用指的是函數對外部狀態的變更,例如更新 DOM、進行網絡請求或修改全局變量。watch 允許我們在數據變化時自動響應,這對於處理異步操作和更新狀態非常有用。它也支持深層監聽和清理功能,能夠應對複雜的副作用場景。
在這篇文章中,探討了 Vue 組件的生命周期鉤子以及它們在不同階段的應用。每個 Vue 組件在創建時,會經歷一系列初始化步驟,這些步驟中會執行特定的生命週期鉤子函數,例如 onMounted、onUpdated 和 onUnmounted 等。這些鉤子允許開發者在組件的特定階段插入自定義代碼。
使用 v-bind 可以將 HTML 屬性、樣式或類別綁定到 Vue 的數據,實現單向數據綁定。而 v-model 則是用於表單元素的雙向數據綁定,使輸入和數據同步更新。使用 v-bind 可以讓我們綁定非字符串值,例如布爾值或對象,從而在處理更複雜的應用場景時更為靈活。
Vue.js 的事件修飾符提供了一種簡化和直觀的方式來處理事件。與傳統 JavaScript 中需要手動檢查條件和處理事件相比,Vue 的修飾符(如 .prevent、.stop、.enter)使代碼更加清晰和易於管理。這些修飾符直接在模板中指定事件行為,減少了樣板代碼,提升了可讀性。
v-for 用於渲染陣列或物件列表,支持索引和嵌套。使用 key 來提高渲染效率。v-if 和 v-for 不應同時在同一節點上使用。
Conditional Rendering 根據條件決定是否渲染元素。Vue.js 的 v-if 在條件為真時渲染,v-else-if 處理額外條件,v-show 始終渲染元素但用 CSS 控制顯示。v-if 會創建或銷毀元素,v-show 只改變顯示樣式。
你可能也想看
Google News 追蹤
Thumbnail
這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
Thumbnail
11/20日NVDA即將公布最新一期的財報, 今天Sell Side的分析師, 開始調高目標價, 市場的股價也開始反應, 未來一週NVDA將重新回到美股市場的焦點, 今天我們要分析NVDA Sell Side怎麼看待這次NVDA的財報預測, 以及實際上Buy Side的倉位及操作, 從
Thumbnail
Hi 大家好,我是Ethan😊 相近大家都知道保濕是皮膚保養中最基本,也是最重要的一步。無論是在畫室裡長時間對著畫布,還是在旅途中面對各種氣候變化,保持皮膚的水分平衡對我來說至關重要。保濕化妝水不僅能迅速為皮膚補水,還能提升後續保養品的吸收效率。 曾經,我的保養程序簡單到只包括清潔和隨意上乳液
Thumbnail
各位使用 Vue.js 開發的小夥伴們,你們都怎麼實作父子層組件資料的雙向綁定呢?如果你還在寫 prop + emit 的話,不妨進來看看吧。
Thumbnail
在本章節中,我們探討了 PHP 中如何引用和管理套件。學習了如何使用 Composer 來安裝第三方套件,以及如何引用自定義模組。此外,我們還介紹了如何創建和使用自定義套件,並列舉了一些在 PHP 社群中常見且廣泛使用的套件和庫。通過掌握這些知識,開發者可以更有效地管理和利用各種資源。
Thumbnail
最近觀察到許多網站有一個特性,就是有些網站會使用不同的模板做同一個關鍵字。 很多開發者在做產品的時候會有一個特性,就是會使用相同的模板。使用相同模板的好處不外乎是減少重複開發的時間、快速上站。 因為其實在程式開發中有很多功能可能是相似甚至是重複的。在這種情況下我們不應該重複去開發相同功能,而
Thumbnail
本章節的目的是介紹Java中的套件使用,包括如何引用第三方套件和自定義模組,如何創建和使用自定義套件,以及介紹一些常見的Java標準庫套件。這些內容將幫助讀者更好地理解和使用Java的套件系統。
Thumbnail
※ 視圖模板 視圖模板(View Templates) 是在 MVC 架構中負責展示數據的 HTML 文件,包含模板語法,用於在渲染時插入實際數據。它們的主要目的是分離數據與展示邏輯,讓代碼更加模塊化和易於維護。 視圖模板設計和使用的核心理念,就是「重複的事情不要重複做、效益最大化、有效利用資源
Thumbnail
在 TypeScript 中,套件是模組化代碼的集合,可以提高代碼的可重用性和可維護性。常見的套件包括各種庫和框架,如 lodash、express 等。以下是有關引用套件、自定義套件和常見套件的詳細介紹。
Thumbnail
因為最近想嘗試編碼風格,於是就選了一套比較"不嚴格"的輔助工具來摸索。 編輯器 VS CODE 框架 VUE3 打包工具 VITE 編碼風格 Standard 環境 version { "nodejs":"v18.18.0", "npm":"9.8.1" }
Thumbnail
平常我們在 html 上常看到的例如 v-for、v-model 等等... 也是VUE已經幫我們定義好的指令,而這次我們可以依這自己的需求來建立。 此功能屬於較進階的功能,因此實戰中會比較少見,市面上還是有不少完善的套件能達到同樣效果,建議可以先往這方面察找
Thumbnail
我們在實作中,難免會遇到在不同組件中,卻有需求相同的資料格式,因此 mixins 可以達到我們的需求,除了 data 以外也包含了 methods 可以共用,舉例來說,學生資料可能會在,班級跟社團內被使用,當我們要撰寫元件時,就可以省略多餘的 data 定義。
Thumbnail
這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
Thumbnail
11/20日NVDA即將公布最新一期的財報, 今天Sell Side的分析師, 開始調高目標價, 市場的股價也開始反應, 未來一週NVDA將重新回到美股市場的焦點, 今天我們要分析NVDA Sell Side怎麼看待這次NVDA的財報預測, 以及實際上Buy Side的倉位及操作, 從
Thumbnail
Hi 大家好,我是Ethan😊 相近大家都知道保濕是皮膚保養中最基本,也是最重要的一步。無論是在畫室裡長時間對著畫布,還是在旅途中面對各種氣候變化,保持皮膚的水分平衡對我來說至關重要。保濕化妝水不僅能迅速為皮膚補水,還能提升後續保養品的吸收效率。 曾經,我的保養程序簡單到只包括清潔和隨意上乳液
Thumbnail
各位使用 Vue.js 開發的小夥伴們,你們都怎麼實作父子層組件資料的雙向綁定呢?如果你還在寫 prop + emit 的話,不妨進來看看吧。
Thumbnail
在本章節中,我們探討了 PHP 中如何引用和管理套件。學習了如何使用 Composer 來安裝第三方套件,以及如何引用自定義模組。此外,我們還介紹了如何創建和使用自定義套件,並列舉了一些在 PHP 社群中常見且廣泛使用的套件和庫。通過掌握這些知識,開發者可以更有效地管理和利用各種資源。
Thumbnail
最近觀察到許多網站有一個特性,就是有些網站會使用不同的模板做同一個關鍵字。 很多開發者在做產品的時候會有一個特性,就是會使用相同的模板。使用相同模板的好處不外乎是減少重複開發的時間、快速上站。 因為其實在程式開發中有很多功能可能是相似甚至是重複的。在這種情況下我們不應該重複去開發相同功能,而
Thumbnail
本章節的目的是介紹Java中的套件使用,包括如何引用第三方套件和自定義模組,如何創建和使用自定義套件,以及介紹一些常見的Java標準庫套件。這些內容將幫助讀者更好地理解和使用Java的套件系統。
Thumbnail
※ 視圖模板 視圖模板(View Templates) 是在 MVC 架構中負責展示數據的 HTML 文件,包含模板語法,用於在渲染時插入實際數據。它們的主要目的是分離數據與展示邏輯,讓代碼更加模塊化和易於維護。 視圖模板設計和使用的核心理念,就是「重複的事情不要重複做、效益最大化、有效利用資源
Thumbnail
在 TypeScript 中,套件是模組化代碼的集合,可以提高代碼的可重用性和可維護性。常見的套件包括各種庫和框架,如 lodash、express 等。以下是有關引用套件、自定義套件和常見套件的詳細介紹。
Thumbnail
因為最近想嘗試編碼風格,於是就選了一套比較"不嚴格"的輔助工具來摸索。 編輯器 VS CODE 框架 VUE3 打包工具 VITE 編碼風格 Standard 環境 version { "nodejs":"v18.18.0", "npm":"9.8.1" }
Thumbnail
平常我們在 html 上常看到的例如 v-for、v-model 等等... 也是VUE已經幫我們定義好的指令,而這次我們可以依這自己的需求來建立。 此功能屬於較進階的功能,因此實戰中會比較少見,市面上還是有不少完善的套件能達到同樣效果,建議可以先往這方面察找
Thumbnail
我們在實作中,難免會遇到在不同組件中,卻有需求相同的資料格式,因此 mixins 可以達到我們的需求,除了 data 以外也包含了 methods 可以共用,舉例來說,學生資料可能會在,班級跟社團內被使用,當我們要撰寫元件時,就可以省略多餘的 data 定義。