Vue.js-11:第十一章 - Vue 中 ref 的使用

来源:https://www.cnblogs.com/danvic712/archive/2019/04/29/10787366.html
-Advertisement-
Play Games

一、前言 在之前的前端開發中,為了實現我們的需求,通常採用的方案是通過 JS/Jquery 直接操縱頁面的 DOM 元素,得益於 Jquery 對於 DOM 元素優異的操作能力,我們可以很輕易的對獲取到的 DOM 元素進行操作。但是,當我們開始在前端項目中使用 Vue 這類的 MVVM 框架之後,對 ...


 一、前言

  在之前的前端開發中,為了實現我們的需求,通常採用的方案是通過 JS/Jquery 直接操縱頁面的 DOM 元素,得益於 Jquery 對於 DOM 元素優異的操作能力,我們可以很輕易的對獲取到的 DOM 元素進行操作。但是,當我們開始在前端項目中使用 Vue 這類的 MVVM 框架之後,對於 DOM 的操作我們就應當完全的交給框架,而我們只需要關註於數據。難道,在 Vue 中就不能手動獲取到頁面上的 DOM 元素了嗎,答案當然是可以手動獲取到 DOM 元素的,在 Vue 中我們可以通過使用 ref 實現獲取 DOM 元素的功能,當然,這也只是 ref 其中一項的功能。本章,我們就來學習 Vue 中 ref 的相關使用。

  學習系列目錄地址:https://www.cnblogs.com/danvic712/p/9549100.html

  倉儲地址:https://github.com/Lanesra712/VueTrial/blob/master/chapter02-bronze/ref.html

 二、乾貨合集

  ref 在 Vue 中是用來給元素或是子組件註冊引用信息到父組件或是 Vue 實例上,註冊後的引用信息都會呈現在父組件/Vue 實例的 $.refs 上,這時,我們就可以通過 $.refs 獲取到引用的 DOM 對象或是子組件信息。

  例如,我們可以獲取到頁面上添加了 ref 的 input 輸入框的值,對於子組件來說,我們可以直接獲取到子組件 data 選項中的數據,或是直接調用子組件的方法。

  1、虛擬 DOM

  在我們使用 JS/Jquery 直接對 DOM 元素進行操作時,不管是對元素樣式的修改(背景顏色從紅色變成藍色)還是對頁面中的某些佈局進行動態調整(通過點擊按鈕在列表中添加一行新的數據),這都會造成頁面的重新渲染,從而影響我們網站的性能。而在 Vue 中,通過在記憶體中生成與真實 DOM 與之對應的數據結構(虛擬 DOM),當頁面發生變化時,通過新的虛擬 DOM 樹與舊的虛擬 DOM 樹進行比對,就能很快的找出差異點,從而得出應施加到真實 DOM 上的改動。

虛擬DOM(圖片版權屬於 Vue 作者尤雨溪)

  2、使用 ref 獲取頁面 DOM 元素

  在使用 JS/Jquery 獲取頁面的 DOM 元素時,我們一般是根據 id、class、標簽、屬性等其它標識來獲取到頁面上的 DOM 元素。嗯,可以說,我們很難拋棄 Jquery 的一個重大原因,就是當我們需要獲取到頁面上的 DOM 元素時,使用 Jquery 的 API 相比於原生的 JS 代碼,簡單到極致,有木有。

document.getElementById('id').value => $('#id').val()

  那麼,難道我們在 Vue 中獲取 DOM 元素還是採用這樣的方式?

  答案當然是否定的,這種直接操縱 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 框對象。

  3、使用 ref 獲取子組件對象

  同使用 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 屬性添加到子組件上,我們就可以很輕鬆的獲取到子組件的相關信息,這無疑給父組件獲取子組件數據、調用子組件的方法提供了一種新的思路。

 四、參考

  1、網頁性能管理詳解

  2、重排重繪,看這一篇就夠了

  3、Vue作者尤雨溪:Vue 2.0,漸進式前端解決方案

  4、vue中的 ref 和 $refs


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 本文拷貝自: http://aix.colintree.cn/zh/HowToInstallExtensions.html 並且強烈推薦 http://aix.colintree.cn 網站。 首先呢,找到下載好的.aix文件下載的文件不是aix的話: aix文件需要作為一個整體上傳,所以不需要再做 ...
  • 首先熟悉導入、導出項目是為了養成良好的備份習慣。 一、登陸App Inventor 2編程界面都大同小異,在項目菜單下麵有導入項目和導出項目菜單。 二、打開導入項目界面,選擇要導入的aia文件。 三、導入成功後,可以看到指南針項目的內容 四、修改項目後,記得導出項目到本地電腦硬碟或U盤作為備份。 ...
  • 註意:每次退出前導出自己的項目到本地做備份。 單機版特點: 1.同步官方最新版本,沒有對java源代碼進行修改,僅修改war\login.jsp及\war\WEB-INF\appengine-web.xml; 2.無需聯網,已經設置Rendezvous伺服器為127.0.0.1:8888; 3.帶有 ...
  • 路由大家應該都知道,在微信小程式也是有的,畢竟它是單頁面應用程式。在WeChat中有五種跳轉方式,分別是wx.switchTab、wx.reLaunch、wx.redirectTo、wx.navigateTo、wx.navigateBack。今天我們就說一說 如何使用這幾個API來跳轉頁面,並且我們 ...
  • Intent:即意圖,一般是用來啟動新的Activity,按照啟動方式分為兩類:顯式Intent 和 隱式Intent 顯示Intent就是直接以“類名稱”來指定要啟動哪一個Activity:Intent intent = new Intent(this , activity.class); 其中a ...
  • 插敘:之前電腦一直遇到VPN登錄不了的問題,試了幾臺電腦都能正常連接,只有我的電腦不可以,VPN大佬建議我直接重裝系統,索性就直接重新裝了系統,結果就能連接了。昨天開始上傳包的時候,發現用Application Loader登錄的時候,填寫了正確的開發者賬號一直登錄不上去,如下圖。 點了圖上的地址 ...
  • 我們的目標:搭建一個本地多用戶的App Inventor 2 伺服器 演示: http://ai2.fsyz.net [舊 win] http://ai2n.fsyz.net [新 Centos] 目的:課堂教學,社團活動,興趣學習 優勢:管理許可權(用戶管理,賬號切換,資源打包),網路鏈接速度快,擁 ...
  • 表單類控制項承載了一個網頁數據的錄入與交互,本章將介紹如何使用指令v-model完成表單的數據雙向綁定。 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...