一、使用$ref特性獲取DOM元素
代碼示例如下所示:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"></div> <script type="text/javascript" src="./vue.js"></script> <script type="text/javascript"> // 全域組件 Vue.component('subComp',{ template:`<div></div>` }); var App={ // 局部組件創建 template:`<div> <subComp ref="subc"></subComp> <button ref="btn">我是按鈕</button> <p ref="sb">alex</p> </div>`, beforeCreate(){ // 在當前組件創建之前調用 console.log(this.$refs.btn); // 輸出:undefined }, created(){ // 在當前組件創建之后調用 console.log(this.$refs.btn); // 輸出:undefined,此時this對象已經有refs屬性,但是DOM還沒有渲染進App組件中 }, beforeMount(){ // 裝載數據到DOM之前會調用 console.log(this.$refs.btn); // 輸出:undefined }, mounted(){ // 裝載數據到DOM之后會調用 console.log(this); // this是一個對象,包含refs屬性$refs: {btn: button, sb: p} console.log(this.$refs.btn); // <button>我是按鈕</button> // 如果是給組件綁定的ref=""屬性那么this.$refs.subc取到的是組件對象 console.log(this.$refs.subc); var op = this.$refs.sb; this.$refs.btn.onclick = function () { console.log(op.innerHTML); // 點擊按鈕控制台輸出:alex } }, }; new Vue({ el:'#app', data(){ return{ } }, template:`<App/>`, components:{ App } }) </script> </body> </html>
1、ref特性為子組件賦予ID引用
盡管存在 prop 和事件,有的時候你仍可能需要在 JavaScript 里直接訪問一個子組件。
為了達到這個目的,你可以通過 ref
特性為這個子組件賦予一個 ID 引用,如下所示:
<button ref="btn">我是按鈕</button> <p ref="sb">alex</p>
2、通過this.$refs.btn訪問 <button> 實例
ref
被用來給元素或子組件注冊引用信息。引用信息將會注冊在父組件的 $refs
對象上。如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子組件上,引用就指向組件實例。
beforeCreate在當前組件創建之前調用,此時輸出肯定為undefined。但是后面created方法是在組件創建之后調用,此時打印this可以發現里面也已經有了refss屬性,但是這個時候DOM還沒有渲染進App組件中,這里涉及到了一個虛擬DOM的概念。直到mounted方法,裝載數據到DOM之后才會正常顯示出this.$refs.btn內容。
mounted(){ // 裝載數據到DOM之后會調用 console.log(this); // this是一個對象,包含refs屬性$refs: {btn: button, sb: p} console.log(this.$refs.btn); // <button>我是按鈕</button>
3、給組件綁定的ref屬性
// 全域組件 Vue.component('subComp',{ template:`<div></div>` }); var App={ // 局部組件創建 template:`<div> <subComp ref="subc"></subComp> <button ref="btn">我是按鈕</button> <p ref="sb">alex</p> </div>`, // 省略代碼 mounted(){ // 裝載數據到DOM之后會調用 console.log(this); // this是一個對象,包含refs屬性$refs: {btn: button, sb: p} console.log(this.$refs.btn); // <button>我是按鈕</button> // 如果是給組件綁定的ref屬性那么this.$refs.subc取到的是組件對象 console.log(this.$refs.subc); var op = this.$refs.sb; this.$refs.btn.onclick = function () { console.log(op.innerHTML); // 點擊按鈕控制台輸出:alex } }, };
如果是給組件綁定的ref屬性,那么this.$refs.subc取到的是組件對象。
4、輸出效果
二、常用$屬性
$refs:獲取組件內的元素
$parent:獲取當前組件的父組件
$children:獲取當前組件的子組件
$root:獲取New Vue的實例化對象
$el:獲取組件對象的DOM元素
三、獲取更新之后的DOM添加事件的特殊情況
1、DOM更新策略
vue實現響應式並不是數據發生變化后DOM立刻發生變化,而是按照一定的策略進行DOM的更新。
(1)配置v-if數據屬性顯示focus(焦點)
在頁面上制作一個input輸入框,在頁面加載時就讓該輸入框獲取焦點。
<body> <div id="app"></div> <script type="text/javascript" src="./vue.js"></script> <script type="text/javascript"> var App={ // 局部組件創建 data(){ return{ isShow:true } }, template:`<div> <input type="text" v-if="isShow" ref="fos"/> </div>`, mounted(){ // 裝載數據到DOM之后會調用 // focus()方法用於給予該元素焦點 this.$refs.fos.focus(); } }; new Vue({ el:'#app', data(){ return{ } }, template:`<App/>`, components:{ App } }) </script> </body>
頁面加載時就讓該輸入框獲取焦點,顯示效果如下:
(2)修改v-if數據屬性看DOM是否發生變化
<body> <div id="app"></div> <script type="text/javascript" src="./vue.js"></script> <script type="text/javascript"> var App={ // 局部組件創建 data(){ return{ isShow:false } }, template:`<div> <input type="text" v-if="isShow" ref="fos"/> </div>`, mounted(){ // 裝載數據到DOM之后會調用 // vue實現響應式並不是數據發生變化后DOM立刻發生變化,而是按照一定的策略進行DOM的更新。 // $nextTick是在下次DOM更新循環結束之后執行的延遲回調,在修改數據之后使用這個方法則可以在回調中獲取更新之后的DOM this.isShow = true; console.log(this.$refs.fos); // 輸出undefined // focus() this.$refs.fos.focus(); // focus() 方法用於給予該元素焦點。 } }; new Vue({ el:'#app', data(){ return{ } }, template:`<App/>`, components:{ App } }) </script> </body>
顯示效果如下:
2、$nextTick方法
$nextTick是在下次DOM更新循環結束之后執行的延遲回調,在修改數據之后使用這個方法則可以在回調中獲取更新之后的DOM。
<body>
<div id="app"></div>
<script type="text/javascript" src="./vue.js"></script>
<script type="text/javascript">
var App={ // 局部組件創建
data(){
return{
isShow:false
}
},
template:`<div>
<input type="text" v-if="isShow" ref="fos"/>
</div>`,
mounted(){ // 裝載數據到DOM之后會調用
// vue實現響應式並不是數據發生變化后DOM立刻發生變化,而是按照一定的策略進行DOM的更新。
// $nextTick:
// 是在下次DOM更新循環結束之后執行的延遲回調,在修改數據之后使用這個方法則可以在回調中獲取更新之后的DOM
this.isShow = true;
console.log(this.$refs.fos); // 輸出undefined
// focus()
// this.$refs.fos.focus(); // focus() 方法用於給予該元素焦點。
this.$nextTick(function () {
// 回調函數中獲取更新之后真實的DOM
this.$refs.fos.focus();
})
}
};
new Vue({
el:'#app',
data(){
return{
}
},
template:`<App/>`,
components:{
App
}
})
</script>
</body>
顯示效果如下所示: