目錄
運行結果
首頁 web前端 js教程 Vue中用props為data賦初始值時遇到的問題及解決方法

Vue中用props為data賦初始值時遇到的問題及解決方法

Nov 27, 2018 pm 02:54 PM
javascript vue.js

這篇文章帶給大家的內容是關於Vue中用props給data賦初始值時遇到的問題及解決方法,有一定的參考價值,有需要的朋友可以參考一下,希望對你有所幫助。

前段時間做一個營運活動的項目,上線後產品回饋頁面埋點不對,在排查過程中發現,問題竟然是由於Vue中的data初始值導致,而data的初始值來自於props。為方便描述,現將問題抽像如下:

一、現象

#程式碼:

nbsp;html>


    <meta>
    <title>用props初始化data中变量</title>
    <script></script>


<div>
    <user-info></user-info>
</div>
<script>
    //全局组件
    let userInfo = Vue.component(&#39;userInfo&#39; ,{
        name: &#39;user-info&#39;,
        props: {
            userData: Object
        },
        data() {
          return {
              userName: this.userData.name
          }
        },
        template: `
            <div>
                <div>姓名:{{userName}}
                <div>性别:{{userData.gender}}
                <div>生日:{{userData.birthday}}
            
        `
    });

    //Vue实例
    new Vue({
        el: &#39;#app&#39;,
        data: {
            user: {
                name: &#39;&#39;,
                gender: &#39;&#39;,
                birthday: &#39;&#39;
            }
        },
        created(){
           this.getUserData();
        },
        methods:{
            getUserData(){
                setTimeout(()=>{
                    this.user = {
                        name: &#39;于永雨&#39;,
                        gender: &#39;男&#39;,
                        birthday: &#39;1991-7&#39;
                    }
                }, 500)
            }
        },
        components: {
            userInfo
        }
    });
</script>

登入後複製

程式碼解讀:

Vue中用props為data賦初始值時遇到的問題及解決方法

#根元件data中有一個物件:user,包含三個屬性:name、gender、birthday,初始值都為空字串

模擬api非同步請求, 500毫秒後對user的重新賦值,三個屬性都不再為空

#聲明一個子元件userInfo,props中有一個物件userData,用於接收父元件的user; data中有一個變數userName,初始值來自於userData.name

結果:

Vue中用props為data賦初始值時遇到的問題及解決方法##頁面初始化後,姓名、性別、生日都顯示為空,500毫秒後性別和生日顯示正常結果,僅姓名沒有變化。

為什麼會這樣呢?

我最初的想法:user.name是String,屬於基本資料類型,用它給子元件data中userName賦值,屬於基本資料類型賦值,所以當父元件中user.name變化時,子元件中userName並不會隨之變化。

是這樣的嗎?於是我決定將user.name改為對象,透過引用資料類型賦值,然後觀察是否符合預期。程式碼如下:

nbsp;html>


    <meta>
    <title>用props初始化data中变量-对象形式</title>
    <script></script>


<div>
    <user-info></user-info>
</div>
<script>
    //全局组件
    let userInfo = Vue.component(&#39;userInfo&#39; ,{
        name: &#39;user-info&#39;,
        props: {
            userData: Object
        },
        data() {
          return {
              userName: this.userData.name
          }
        },
        template: `
            <div>
                <div>姓名:{{userName.text}}
                <div>性别:{{userData.gender}}
                <div>生日:{{userData.birthday}}
            
        `
    });


    //Vue实例
    new Vue({
        el: &#39;#app&#39;,
        data: {
            user: {
                name: {text: &#39;&#39;},
                gender: &#39;&#39;,
                birthday: &#39;&#39;
            }
        },
        created(){
           this.getUserData();
        },
        methods:{
            getUserData(){
                setTimeout(()=>{
                    this.user = {
                        name: {text: &#39;于永雨&#39;},
                        gender: &#39;男&#39;,
                        birthday: &#39;1991-7&#39;
                    }
                }, 500)
            }
        },
        components: {
            userInfo
        }
    });
</script>

登入後複製

運行結果:姓名仍然沒有值,和第一次結果一樣! ! ! Vue中用props為data賦初始值時遇到的問題及解決方法

二、原因

那麼,原因到底是什麼呢?百思不得解,後來和朋友討論時,有人提出:會不會因為data在初始化時深拷貝?

我覺得這種解釋比較可靠,於是去收集證據,首先去Vue官網翻了一下關於data的文檔,其中:


當看到"遞歸地"那個詞,基本上就能斷定上面的推論是正確的,因為深拷貝的核心原理就是遞歸

原來,Vue中用props為data賦初始值時遇到的問題及解決方法Vue初始化時會遞歸地遍歷data所有的​​屬性,並使用Object.defineProperty把這些屬性全部轉為getter/setter,用來實現雙向綁定。 官方文件在Reactivity in Depth一章中明確有說:

#還順便解釋了為什麼Vue不支持IE8的原因:IE8不支援Object.defineProperty。

三、解決方法

既然因為data深拷貝的原因,data無法隨著props的變化而更新,我們很自然的就想到Vue中用props為data賦初始值時遇到的問題及解決方法Vue中有監聽作用的兩個功能:watch、computed

修改程式碼如下,觀察結果:

nbsp;html>


    <meta>
    <title>解决方案:watch、computed</title>
    <script></script>


<div>
    <user-info></user-info>
</div>
<script>
    //全局组件
    let userInfo = Vue.component(&#39;userInfo&#39; ,{
        name: &#39;user-info&#39;,
        props: {
            userData: Object
        },
        data() {
          return {
            userName: this.userData.name
          }
        },
        computed: {
            computedUserName(){
                return this.userData.name
            }
        },
        watch: {
            &#39;userData.name&#39;: function (val) {//监听props中的属性
                this.userName = val;
            }
        },
        template: `
            <div>
                <div>姓名(watch):{{ userName }}
                <div>姓名(computed):{{ computedUserName }}
                <div>性别:{{ userData.gender }}
                <div>生日:{{ userData.birthday }}
            
        `
    });


    //Vue实例
    new Vue({
        el: &#39;#app&#39;,
        data: {
            user: {
                name: &#39;&#39;,
                gender: &#39;&#39;,
                birthday: &#39;&#39;
            }
        },
        created(){
           this.getUserData();
        },
        methods:{
            getUserData(){
                setTimeout(()=>{
                    this.user = {
                        name: &#39;于永雨&#39;,
                        gender: &#39;男&#39;,
                        birthday: &#39;1991-7&#39;
                    }
                }, 500)
            }
        },
        components: {
            userInfo
        }
    });
</script>

登入後複製

運行結果

完美! ! !

四、總結:關於Vue中props的要點

###事後又仔細翻了一下關於props的文檔:############## #######大概梳理一下:######1.props是單向資料流:父元件的資料變化,透過props即時反應在子元件中,反之不然######2 .不允許在子元件中直接操作props######3.可以變相操作props######(1)在data中宣告局部變量,並用props初始化,###弊端:局部變數不隨著props更新而更新#########(2)在computed中對props值轉換後輸出#########

以上是Vue中用props為data賦初始值時遇到的問題及解決方法的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

如何使用WebSocket和JavaScript實現線上語音辨識系統 如何使用WebSocket和JavaScript實現線上語音辨識系統 Dec 17, 2023 pm 02:54 PM

如何使用WebSocket和JavaScript實現線上語音辨識系統引言:隨著科技的不斷發展,語音辨識技術已成為了人工智慧領域的重要組成部分。而基於WebSocket和JavaScript實現的線上語音辨識系統,具備了低延遲、即時性和跨平台的特點,成為了廣泛應用的解決方案。本文將介紹如何使用WebSocket和JavaScript來實現線上語音辨識系

WebSocket與JavaScript:實現即時監控系統的關鍵技術 WebSocket與JavaScript:實現即時監控系統的關鍵技術 Dec 17, 2023 pm 05:30 PM

WebSocket與JavaScript:實現即時監控系統的關鍵技術引言:隨著互聯網技術的快速發展,即時監控系統在各個領域中得到了廣泛的應用。而實現即時監控的關鍵技術之一就是WebSocket與JavaScript的結合使用。本文將介紹WebSocket與JavaScript在即時監控系統中的應用,並給出程式碼範例,詳細解釋其實作原理。一、WebSocket技

如何利用JavaScript和WebSocket實現即時線上點餐系統 如何利用JavaScript和WebSocket實現即時線上點餐系統 Dec 17, 2023 pm 12:09 PM

如何利用JavaScript和WebSocket實現即時線上點餐系統介紹:隨著網路的普及和技術的進步,越來越多的餐廳開始提供線上點餐服務。為了實現即時線上點餐系統,我們可以利用JavaScript和WebSocket技術。 WebSocket是一種基於TCP協定的全雙工通訊協議,可實現客戶端與伺服器的即時雙向通訊。在即時線上點餐系統中,當使用者選擇菜餚並下訂單

如何使用WebSocket和JavaScript實現線上預約系統 如何使用WebSocket和JavaScript實現線上預約系統 Dec 17, 2023 am 09:39 AM

如何使用WebSocket和JavaScript實現線上預約系統在當今數位化的時代,越來越多的業務和服務都需要提供線上預約功能。而實現一個高效、即時的線上預約系統是至關重要的。本文將介紹如何使用WebSocket和JavaScript來實作一個線上預約系統,並提供具體的程式碼範例。一、什麼是WebSocketWebSocket是一種在單一TCP連線上進行全雙工

JavaScript與WebSocket:打造高效率的即時天氣預報系統 JavaScript與WebSocket:打造高效率的即時天氣預報系統 Dec 17, 2023 pm 05:13 PM

JavaScript和WebSocket:打造高效的即時天氣預報系統引言:如今,天氣預報的準確性對於日常生活以及決策制定具有重要意義。隨著技術的發展,我們可以透過即時獲取天氣數據來提供更準確可靠的天氣預報。在本文中,我們將學習如何使用JavaScript和WebSocket技術,來建立一個高效的即時天氣預報系統。本文將透過具體的程式碼範例來展示實現的過程。 We

簡易JavaScript教學:取得HTTP狀態碼的方法 簡易JavaScript教學:取得HTTP狀態碼的方法 Jan 05, 2024 pm 06:08 PM

JavaScript教學:如何取得HTTP狀態碼,需要具體程式碼範例前言:在Web開發中,經常會涉及到與伺服器進行資料互動的場景。在與伺服器進行通訊時,我們經常需要取得傳回的HTTP狀態碼來判斷操作是否成功,並根據不同的狀態碼來進行對應的處理。本篇文章將教你如何使用JavaScript來取得HTTP狀態碼,並提供一些實用的程式碼範例。使用XMLHttpRequest

JavaScript與WebSocket:打造高效率的即時影像處理系統 JavaScript與WebSocket:打造高效率的即時影像處理系統 Dec 17, 2023 am 08:41 AM

JavaScript是一種廣泛應用於Web開發的程式語言,而WebSocket則是一種用於即時通訊的網路協定。結合二者的強大功能,我們可以打造一個高效率的即時影像處理系統。本文將介紹如何利用JavaScript和WebSocket來實作這個系統,並提供具體的程式碼範例。首先,我們需要明確指出即時影像處理系統的需求和目標。假設我們有一個攝影機設備,可以擷取即時的影像數

如何在JavaScript中取得HTTP狀態碼的簡單方法 如何在JavaScript中取得HTTP狀態碼的簡單方法 Jan 05, 2024 pm 01:37 PM

JavaScript中的HTTP狀態碼取得方法簡介:在進行前端開發中,我們常常需要處理與後端介面的交互,而HTTP狀態碼就是其中非常重要的一部分。了解並取得HTTP狀態碼有助於我們更好地處理介面傳回的資料。本文將介紹使用JavaScript取得HTTP狀態碼的方法,並提供具體程式碼範例。一、什麼是HTTP狀態碼HTTP狀態碼是指當瀏覽器向伺服器發起請求時,服務

See all articles