vue中ref引用操作DOM元素的實現(xiàn)
前言
在javascript中,我們用原生的方式獲取頁面中的DOM元素,并操作它們。后來,有了jquery,jquery的強大就在于它可以很方便的操作DOM元素。
在vue中,如何操作DOM元素呢?
首先,在vue中強烈禁用原生與jquery來操作DOM元素。我們要充分的利用vue的優(yōu)勢:MVVM,在vue中程序員幾乎不操作DOM,只需要維護好數(shù)據(jù)即可,vue給程序員提供ref引用,不調用api直接獲取元素組件的使用
一,$refs對象介紹及基本用法
refs對象的介紹:在每個vue的組件實例上,都包含一個 r e f 對象 = = 存儲著對應的 = = D O M 元素 = = 或 = = 組件 = = 的引用, = = 默認情況下,組件的 ref對象==存儲著對應的==DOM元素==或==組件==的引用,==默認情況下,組件的 ref對象==存儲著對應的==DOM元素==或==組件==的引用,==默認情況下,組件的refs指向一個空對象,凡是以$開頭的,都是vue的內置對象

基礎使用方法(獲取DOM元素):比如我們要獲取h1,則我們給它取一個名字并放入ref中,代碼如下:
<h1 ref="myh1">App 根組件</h1>
在引用時,只需在js中:
this.$refs.myh1.style.color = "red";
既可以成功操作:

我們來看看現(xiàn)在的refs中是不是多了myh1這一個成員:

總結一下:vue中有一個$refs對象,默認為空。當我們在DOM元素中為其設置ref值后,相當于在vue的內置對象 $refs中添加了新的成員,我們如果需要操作DOM對象直接通過 $refs獲取即可。
二,使用ref引用組件實例
ref除了可以引入DOM元素,還可以引入組件??梢阅玫浇M件并操控里面的方法與數(shù)據(jù)
大家請看left組件結構
<template>
<div class="left-container">
<h3>left組件------{{ count }}</h3>
<button @click="count += 1">+1</button>
<button @click="resetCount">重置</button>
</div>
</template>
<script>
export default {
data() {
return {
count: 0
}
},
methods: {
resetCount() {
this.count = 0;
}
}
}
</script>
<style>
.left-container {
height: 200px;
background-color: orange;
}
</style>
在我將Left組件導入到App.vue后,我想在App組件中操作Left組件中的元素,比如,我想重置Left組件的count值為0:
首先,與操作DOM元素一樣,我要先給Left組件一個ref值:
<Left ref="comLeft"></Left>
在添加ref后,我們再去觀察$refs,多了成員comLeft:

接著,我再設置一個按鈕,要求按鈕按下后,重置Left組件中的count值為0:
<button @click="onReset">重置Left組件的count值為0</button>
然后設置onReset函數(shù):(用到$refs中的comLeft)
onReset() {
this.$refs.comLeft.resetCount();
}
三,ref的使用案例
3.1 案例需求
案例需求:實現(xiàn)按鈕和文本框的按需展示:
有輸入框->看不到按鈕;
有按鈕->看不到輸入框。
3.2 思路與做法
首先寫出結構,一個輸入框與一個按鈕。點擊按鈕時,按鈕消失,輸入框失去焦點,輸入框消失:
通過上述分析,我們可以知道大的方向是要有一個布爾值,默認如果布爾值為false,則默認展示按鈕隱藏輸入框,否則(true)展示輸入框隱藏按鈕。
需要用到的知識:
用@click=“”綁定點擊事件;v-if與v-show控制元素是否顯示(動態(tài)的添加與刪除元素);使用ref綁定輸入框,并使用輸入框的focus來控制輸入框的焦點。
代碼如下:
<!-- 小demo -->
<input type="text" v-if="inputVisible" @blur="showButton" ref="iptRef"/>
<button v-else @click="showInput">展示輸入框</button>
data() {
return {
//控制輸入框和按鈕的按需切換,默認值為false表示默認展示按鈕隱藏輸入框
inputVisible: false
}
},
methods: {
showThis() {
console.log(this);
console.log(this.$refs.myh1);
console.log(this.$refs.comLeft);
this.$refs.myh1.style.color = "red";
},
onReset() {
console.log(this.$refs);
this.$refs.comLeft.resetCount();
},
showInput() {
//切換布爾值,把文本框展示出來
this.inputVisible = true;
//讓展示出來的文本框自動獲取焦點
this.$refs.iptRef.focus();
},
showButton() {
this.inputVisible = false;
}
},
請自行編譯上述代碼會發(fā)現(xiàn)問題:雖然showInput提供方法讓展示出來的文本框自動獲得焦點,但是在頁面中卻無法實現(xiàn)。
3.2 為什么頁面上無法自動獲得焦點
因為當布爾值變成true的時候,頁面還沒來得及更新,這里就跟聲明周期有關系了,js是單線程,從上往下渲染,布爾值變成true,還是一個將要展示,還沒有展示的狀態(tài),所以在頁面中渲染不出來:

解決方法是:保證頁面先更新完再執(zhí)行這個操作,延遲this.$refs.iptRef.focus()的使用在這里插入代碼片
如何延遲?我們能不能把這個操作放在updated中?==答案是不能,因為觸發(fā)updated的條件是,只要數(shù)據(jù)發(fā)生變化就可以觸發(fā)。所以,當this.inputVisible發(fā)生變化,就會觸發(fā)事件。(updated:數(shù)據(jù)更新后,完成虛擬DOM的重新渲染和打補丁。組件DOM已完成更新,可執(zhí)行依賴的DOM操作。注意:不要在此函數(shù)中操作數(shù)據(jù)(修改屬性),會陷入死循環(huán))
那么,有什么更好的解決方法呢?
3.3 this.$nextTick(cb)
組件的this.$nextTick(cb)方法,會把cb回調推遲到下一個DOM更新周期之后執(zhí)行
理解:等組件DOM更新完成后,再執(zhí)行cb回調函數(shù),從而保證cb回調可操作最新的DOM元素
用法:在括號中(cb回調函數(shù))放入箭頭函數(shù)并執(zhí)行操作
showInput() {
//切換布爾值,把文本框展示出來
this.inputVisible = true;
//讓展示出來的文本框自動獲取焦點
// this.$refs.iptRef.focus();
this.$nextTick(() => {
this.$refs.iptRef.focus();
})
}
3.4 整體代碼
<template>
<div class="app-container">
<h1 ref="myh1">App 根組件</h1>
<button @click="showThis">打印 this</button>
<button @click="onReset">重置Left組件的count值為0</button>
<hr />
<!-- 小demo -->
<input type="text" v-if="inputVisible" @blur="showButton" ref="iptRef"/>
<button v-else @click="showInput">展示輸入框</button>
<!-- 渲染Left組件 -->
<div class="box">
<Left ref="comLeft"></Left>
</div>
</div>
</template>
<script>
import Left from "./components/Left.vue";
// console.log($refs);
export default {
data() {
return {
//控制輸入框和按鈕的按需切換,默認值為false表示默認展示按鈕隱藏輸入框
inputVisible: false
}
},
methods: {
showThis() {
console.log(this);
console.log(this.$refs.myh1);
console.log(this.$refs.comLeft);
this.$refs.myh1.style.color = "red";
},
onReset() {
console.log(this.$refs);
this.$refs.comLeft.resetCount();
},
showInput() {
//切換布爾值,把文本框展示出來
this.inputVisible = true;
//讓展示出來的文本框自動獲取焦點
// this.$refs.iptRef.focus();
this.$nextTick(() => {
this.$refs.iptRef.focus();
})
},
showButton() {
this.inputVisible = false;
}
},
components: {
Left,
},
// updated() {
// this.$refs.iptRef.focus();
// }錯誤,只要數(shù)據(jù)變化,就會觸發(fā)updated
};
</script>
<style>
</style>
四,總結
看完這節(jié)知識相信已經學會了如何操作頁面中的DOM元素與組件,并知曉了在頁面DOM元素更新完后如何操作元素的方法與原理。
到此這篇關于vue中ref引用操作DOM元素的實現(xiàn)的文章就介紹到這了,更多相關vue ref引用操作DOM內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
vue?parseHTML?函數(shù)拿到返回值后的處理源碼解析
這篇文章主要為大家介紹了vue?parseHTML?函數(shù)拿到返回值后的處理源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-07-07
Element-ui table中過濾條件變更表格內容的方法
下面小編就為大家分享一篇Element-ui table中過濾條件變更表格內容的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-03-03
vue通過滾動行為實現(xiàn)從列表到詳情,返回列表原位置的方法
今天小編就為大家分享一篇vue通過滾動行為實現(xiàn)從列表到詳情,返回列表原位置的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-08-08

