在以前的前端開發中,爲了實現咱們的需求,一般採用的方案是經過 JS/Jquery 直接操縱頁面的 DOM 元素,得益於 Jquery 對於 DOM 元素優異的操做能力,咱們能夠很輕易的對獲取到的 DOM 元素進行操做。可是,當咱們開始在前端項目中使用 Vue 這類的 MVVM 框架以後,對於 DOM 的操做咱們就應當徹底的交給框架,而咱們只須要關注於數據。難道,在 Vue 中就不能手動獲取到頁面上的 DOM 元素了嗎,答案固然是能夠手動獲取到 DOM 元素的,在 Vue 中咱們能夠經過使用 ref 實現獲取 DOM 元素的功能,固然,這也只是 ref 其中一項的功能。本章,咱們就來學習 Vue 中 ref 的相關使用。html
學習系列目錄地址:http://www.javashuo.com/article/p-bzzucmub-ba.html前端
倉儲地址:https://github.com/Lanesra712/VueTrial/blob/master/chapter02-bronze/ref.htmlvue
ref 在 Vue 中是用來給元素或是子組件註冊引用信息到父組件或是 Vue 實例上,註冊後的引用信息都會呈如今父組件/Vue 實例的 $.refs 上,這時,咱們就能夠經過 $.refs 獲取到引用的 DOM 對象或是子組件信息。git
例如,咱們能夠獲取到頁面上添加了 ref 的 input 輸入框的值,對於子組件來講,咱們能夠直接獲取到子組件 data 選項中的數據,或是直接調用子組件的方法。github
在咱們使用 JS/Jquery 直接對 DOM 元素進行操做時,不論是對元素樣式的修改(背景顏色從紅色變成藍色)仍是對頁面中的某些佈局進行動態調整(經過點擊按鈕在列表中添加一行新的數據),這都會形成頁面的從新渲染,從而影響咱們網站的性能。而在 Vue 中,經過在內存中生成與真實 DOM 與之對應的數據結構(虛擬 DOM),當頁面發生變化時,經過新的虛擬 DOM 樹與舊的虛擬 DOM 樹進行比對,就能很快的找出差別點,從而得出應施加到真實 DOM 上的改動。web
在使用 JS/Jquery 獲取頁面的 DOM 元素時,咱們通常是根據 id、class、標籤、屬性等其它標識來獲取到頁面上的 DOM 元素。嗯,能夠說,咱們很難拋棄 Jquery 的一個重大緣由,就是當咱們須要獲取到頁面上的 DOM 元素時,使用 Jquery 的 API 相比於原生的 JS 代碼,簡單到極致,有木有。數據結構
document.getElementById('id').value => $('#id').val()
那麼,難道咱們在 Vue 中獲取 DOM 元素仍是採用這樣的方式?app
答案固然是否認的,這種直接操縱 DOM 元素的方式,與咱們使用 Vue 的初衷不符,雖然能達成效果,可是卻不提倡,這裏咱們就可使用 ref 來獲取頁面上的 DOM 元素。框架
在下面的代碼中,我在 input 上添加了一個 ref 屬性,以後,咱們就能夠在 Vue 實例中獲取到這個 input 輸入框的值。這裏,我在 beforeMount、mounted 這兩個 Vue 中的生命週期鉤子函數以及一個按鈕的點擊事件中嘗試獲取到這個 input 輸入框的值。函數
<div id="app"> <input type="text" ref="msgText" v-model="msg" /> <button @click="getElement">獲取元素值</button> </div> <script> var vm = new Vue({ el: "#app", data: { msg: 'Hello ref' }, beforeMount() { console.log('beforeMount: ' + this.$refs.msgText.value) }, mounted() { console.log('mounted: ' + this.$refs.msgText.value) }, methods: { getElement() { console.log(this.$refs.msgText.value) } } }); </script>
運行代碼,從結果中能夠看到,在 beforeMount 這個鉤子函數中,咱們是沒法獲取到這個 DOM 元素的值,結合以前學習的 Vue 生命週期的相關知識,當執行到 beforeMount 鉤子函數時,Vue 雖然已經將模板編譯完成,可是還沒有掛載到頁面 DOM 元素上,所以咱們能夠得出 ref 是在頁面渲染完成後才被建立的。
能夠看到,當咱們在 input 輸入框中添加了 ref 屬性後,在當前的 Vue 實例的 $.refs 上就掛載了當前的 input 框對象。
同使用 ref 獲取頁面的 DOM 元素類似,當咱們須要獲取子組件時,只須要將使用到子組件上的地方添加 ref 屬性便可。在下面的示例代碼中,我添加了一個子組件,當咱們點擊 Vue 實例上的按鈕時,會先調用子組件的方法,而後獲取子組件的數據。
<div id="app"> <input type="text" ref="msgText" v-model="msg" /> <button @click="getElement">獲取元素值</button> <hr> <child ref="childComponent"></child> </div> <template id="child"> <div> <input type="datetime" name="datetime" v-model="local"> <button @click="getLocalData">獲取當前時間</button> </div> </template> <script> var vm = new Vue({ el: "#app", data: { msg: 'Hello ref' }, mounted() { console.log('mounted: ' + this.$refs.msgText.value) }, methods: { getElement() { console.log('input 輸入框的值爲:' + this.$refs.msgText.value) this.$refs.childComponent.getLocalData() console.log('子組件 input 輸入框的值爲:' + this.$refs.childComponent.local) } }, components: { 'child': { template: '#child', data() { return { local: '' } }, methods: { getLocalData() { var date = new Date() this.local = date.toLocaleString() } }, } } }); </script>
能夠看到,當咱們將 ref 添加到子組件上,咱們就能夠在 Vue 實例上獲取到這個註冊的組件引用,同註冊的 DOM 元素同樣,咱們均可以使用添加的 ref 屬性值做爲 key 獲取到註冊的對象。此時,咱們就能夠獲取到這個子組件上的 data 選項和 methods 選項。
由於 Vue 採用 Virtual DOM 的作法渲染網頁,若是咱們直接操做 DOM,很容易產生實際網頁跟 Vue 產生的 Virtual DOM 不一樣步的問題,而經過使用 ref 屬性以後,在一些須要獲取 DOM 元素的狀況下,咱們就能夠很方便的獲取 DOM 元素。固然,當咱們決定在項目中使用 Vue,仍是須要轉變咱們的思路,將操做 DOM 轉變成操做數據。一樣的,經過將 ref 屬性添加到子組件上,咱們就能夠很輕鬆的獲取到子組件的相關信息,這無疑給父組件獲取子組件數據、調用子組件的方法提供了一種新的思路。
一、網頁性能管理詳解
原文出處:https://www.cnblogs.com/danvic712/p/10787366.html