雖然 Vue 的聲明(míng)性渲染模型為(wèi)你抽象了(le)大部分對 DOM 的直接操作(zuò),但(dàn)在某些情況下(xià),我們仍然需要(yào)直接訪問(wèn)底層 DOM 元素。要(yào)實現這(zhè)一(yī)點,我們可(kě)以使用特殊的 ref attribute:
template
<input ref="input">
ref 是一(yī)個特殊的 attribute,和(hé) v-for 章(zhāng)節中提到的 key 類似。它允許我們在一(yī)個特定的 DOM 元素或子組件實例被挂載後,獲得對它的直接引用。這(zhè)可(kě)能(néng)很(hěn)有用,比如(rú)說在組件挂載時(shí)将焦點設置到一(yī)個 input 元素上(shàng),或在一(yī)個元素上(shàng)初始化一(yī)個第三方庫。
訪問(wèn)模闆引用
挂載結束後引用都(dōu)會被暴露在 this.$refs 之上(shàng):
vue
<script>
export default {
mounted() {
this.$refs.input.focus()
}
}
</script>
<template>
<input ref="input" />
</template>
注意,你隻可(kě)以在組件挂載後才能(néng)訪問(wèn)模闆引用。如(rú)果你想在模闆中的表達式上(shàng)訪問(wèn) $refs.input,在初次渲染時(shí)會是 null。這(zhè)是因為(wèi)在初次渲染前這(zhè)個元素還不存在呢!
v-for 中的模闆引用
需要(yào) v3.2.25 及以上(shàng)版本
當在 v-for 中使用模闆引用時(shí),相應的引用中包含的值是一(yī)個數(shù)組:
vue
<script>
export default {
data() {
return {
list: [
/* ... */
]
}
},
mounted() {
console.log(this.$refs.items)
}
}
</script>
<template>
<ul>
<li v-for="item in list" ref="items">
{{ item }}
</li>
</ul>
</template>
應該注意的是,ref 數(shù)組并不保證與源數(shù)組相同的順序。
函數(shù)模闆引用
除了(le)使用字符串值作(zuò)名字,ref attribute 還可(kě)以綁定為(wèi)一(yī)個函數(shù),會在每次組件更新時(shí)都(dōu)被調用。該函數(shù)會收到元素引用作(zuò)為(wèi)其第一(yī)個參數(shù):
template
<input :ref="(el) => { /* 将 el 賦值給一(yī)個數(shù)據屬性或 ref 變量 */ }">
注意我們這(zhè)裏需要(yào)使用動态的 :ref 綁定才能(néng)夠傳入一(yī)個函數(shù)。當綁定的元素被卸載時(shí),函數(shù)也會被調用一(yī)次,此時(shí)的 el 參數(shù)會是 null。你當然也可(kě)以綁定一(yī)個組件方法而不是內(nèi)聯函數(shù)。
組件上(shàng)的 ref
這(zhè)一(yī)小節假設你已了(le)解組件的相關知識,或者你也可(kě)以先跳(tiào)過這(zhè)裏,之後再回來看(kàn)。
模闆引用也可(kě)以被用在一(yī)個子組件上(shàng)。這(zhè)種情況下(xià)引用中獲得的值是組件實例:
vue
<script>
import Child from './Child.vue'
export default {
components: {
Child
},
mounted() {
// this.$refs.child 是 <Child /> 組件的實例
}
}
</script>
<template>
<Child ref="child" />
</template>
如(rú)果一(yī)個子組件使用的是選項式 API ,被引用的組件實例和(hé)該子組件的 this 完全一(yī)緻,這(zhè)意味着父組件對子組件的每一(yī)個屬性和(hé)方法都(dōu)有完全的訪問(wèn)權。這(zhè)使得在父組件和(hé)子組件之間(jiān)創建緊密耦合的實現細節變得很(hěn)容易,當然也因此,應該隻在絕對需要(yào)時(shí)才使用組件引用。大多數(shù)情況下(xià),你應該首先使用标準的 props 和(hé) emit 接口來實現父子組件交互。
expose 選項可(kě)以用于限制對子組件實例的訪問(wèn):
js
export default {
expose: ['publicData', 'publicMethod'],
data() {
return {
publicData: 'foo',
privateData: 'bar'
}
},
methods: {
publicMethod() {
/* ... */
},
privateMethod() {
/* ... */
}
}
}
在上(shàng)面這(zhè)個例子中,父組件通(tōng)過模闆引用訪問(wèn)到子組件實例後,僅能(néng)訪問(wèn) publicData 和(hé) publicMethod。
網站建設開(kāi)發|APP設計開(kāi)發|小程序建設開(kāi)發