成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Vue中用props給data賦初始值遇到的問題

luck / 3179人閱讀

摘要:基于此,我們很自然的就想到中有監(jiān)聽作用的兩個(gè)功能。正如在所說小結(jié)一下文章開頭的問題是一個(gè)關(guān)于基本數(shù)據(jù)類型和引用數(shù)據(jù)類型賦值的問題在初始化時(shí)被遞歸遍歷轉(zhuǎn)化是用于實(shí)現(xiàn)雙向綁定這么看來,二者是沒有任何關(guān)系的。想當(dāng)然和不加深究實(shí)為大忌,引以為戒。

2018-11-28更:文章發(fā)布后因?yàn)榇嬖诶斫忮e(cuò)誤,經(jīng)@Kim09AI同學(xué)提醒后做了調(diào)整,在此深表感謝。其他不足之處,還望不吝賜教。

前言

前段時(shí)間做一個(gè)運(yùn)營活動(dòng)的項(xiàng)目,上線后產(chǎn)品反饋頁面埋點(diǎn)不對(duì),在排查過程中發(fā)現(xiàn),問題竟然是由于Vue中的data初始值導(dǎo)致,而data的初始值來自于props。為方便描述,現(xiàn)將問題抽象如下:

一、現(xiàn)象 代碼:



    
    用props初始化data中變量
    


代碼解讀:

根組件data中有一個(gè)對(duì)象:user,包含三個(gè)屬性:name、gender、birthday,初始值都為空字符串

模擬api異步請(qǐng)求,500毫秒后對(duì)user的重新賦值,三個(gè)屬性都不再為空

聲明一個(gè)子組件userInfo,props中有一個(gè)對(duì)象userData,用于接收父組件的user;data中有一個(gè)變量userName,初始值來自于userData.name

結(jié)果:

頁面初始化后,姓名、性別、生日都顯示為空,500毫秒后性別和生日顯示正常結(jié)果,僅姓名沒有變化。

為什么會(huì)這樣呢?

二、原因及解決辦法

我最初的想法:user.name是String,屬于基本數(shù)據(jù)類型,用它給子組件data中userName賦值,屬于基本數(shù)據(jù)類型賦值,所以當(dāng)父組件中user.name變化時(shí),子組件中userName并不會(huì)隨之變化。

是這樣的嗎?于是我決定將user.name改為對(duì)象,通過引用數(shù)據(jù)類型賦值,然后觀察是否符合預(yù)期。代碼如下:




    
    用props初始化data中變量-對(duì)象形式
    


運(yùn)行結(jié)果:

完美?。?!

如果我們不想把user.name改為Object類型,有沒有其他的解決辦法呢?

既然基本數(shù)據(jù)類型賦值沒法實(shí)現(xiàn)值同步,那我們可以考慮監(jiān)聽props中的值,然后手動(dòng)變更局部變量。基于此,我們很自然的就想到Vue中有監(jiān)聽作用的兩個(gè)功能:watch、computed。

為了縮減篇幅,我們此處只貼出userInfo組件,其他代碼與第一個(gè)示例一致,具體如下:

方法一:watch
let userInfo = Vue.component("userInfo" ,{
        name: "user-info",
        props: {
            userData: Object
        },
        data() {
          return {
            userName: this.userData.name
          }
        },
        watch: {
            "userData.name": function (val) { //監(jiān)聽props中的屬性
                this.userName = val;
            }
        },
        template: `
            
姓名:{{ userName }}
性別:{{ userData.gender }}
生日:{{ userData.birthday }}
` });
方法二:computed
let userInfo = Vue.component("userInfo" ,{
        name: "user-info",
        props: {
            userData: Object
        },
        data() {
          return {
            userName: this.userData.name
          }
        },
        computed: {
            computedUserName(){
                return this.userData.name
            }
        },
        template: `
            
姓名:{{ computedUserName }}
性別:{{ userData.gender }}
生日:{{ userData.birthday }}
` });

經(jīng)驗(yàn)證,結(jié)果符合皆預(yù)期!

三、走過的彎路 第一條彎路

詳見評(píng)論區(qū)@Kim09AI同學(xué)的評(píng)論。

第二條彎路

其實(shí),曾以為導(dǎo)致文章開頭的問題,是由于data在初始化后深拷貝,props再次變化data并不會(huì)刷新導(dǎo)致的。

直到文章發(fā)布之初,仍然持此觀點(diǎn),后來經(jīng)@Kim09AI同學(xué)提醒才恍然大悟。

當(dāng)初之所以深信是data被深拷貝導(dǎo)致的,主要是自己在翻到Vue官方文檔看到關(guān)于data的描述:

看到"遞歸地”那個(gè)詞,就想當(dāng)然地認(rèn)為data被深拷貝了,因?yàn)?strong>深拷貝的核心原理就是遞歸。

其實(shí)現(xiàn)在再回過頭來看那段描述,包括在Reactivity in Depth一章的描述:

它們真正含義是:Vue會(huì)遞歸地遍歷data所有的屬性,并使用Object.defineProperty把這些屬性全部轉(zhuǎn)為getter/setter,讓data中的屬性更具“交互性”,以此作為實(shí)現(xiàn)雙向綁定的基礎(chǔ)。包括還順便解釋了一下為什么Vue不支持IE8的原因:IE8不支持Object.defineProperty。

這也僅僅解釋了為什么只有在組件初始化之初data中已經(jīng)聲明的屬性才具有“交互性”,即data中屬性的變化會(huì)引起視圖變化,而其他在最初data中沒有聲明的屬性則不會(huì)。正如在The Vue Instance所說:

小結(jié)一下:

文章開頭的問題是一個(gè)關(guān)于基本數(shù)據(jù)類型和引用數(shù)據(jù)類型賦值的問題

data在初始化時(shí)被遞歸遍歷轉(zhuǎn)化是用于實(shí)現(xiàn)雙向綁定

這么看來,二者是沒有任何關(guān)系的。

四、關(guān)于Vue中props的要點(diǎn)

事后又仔細(xì)翻了一下關(guān)于props的文檔:

大概梳理一下:
1.props是單向數(shù)據(jù)流:父組件的數(shù)據(jù)變化,通過props實(shí)時(shí)反應(yīng)在子組件中,反之不然

2.不允許在子組件中直接操作props

3.可以變相操作props
(1)在data中聲明局部變量,并用props初始化
(2)在computed中對(duì)props值轉(zhuǎn)換后輸出

五、一點(diǎn)反思

分享是一種知識(shí)的傳遞,嚴(yán)謹(jǐn)和正確是最重要的,技術(shù)文章更是如此。想當(dāng)然和不加深究實(shí)為大忌,引以為戒。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/99420.html

相關(guān)文章

  • vue 開發(fā)中遇到問題匯總(踩坑指南)

    摘要:組件中使用定時(shí)器及銷毀問題如果我們?cè)陧撁嬷惺褂昧艘粋€(gè)定時(shí)器,當(dāng)從頁面跳轉(zhuǎn)到頁面時(shí),如果不手動(dòng)清除這個(gè)定時(shí)器,那么它仍舊會(huì)執(zhí)行,這不是我們所期望的。 公司年初開始從jquery轉(zhuǎn)型到vue開發(fā),思想上從jquery的操作DOM到vue的操作數(shù)據(jù),剛開始還不太習(xí)慣,但用了一段時(shí)間發(fā)現(xiàn)確實(shí)比較方便。在剛開始用vue的時(shí)候,也踩了一些坑,現(xiàn)在分享出來,供剛?cè)腴T上手開發(fā)vue的朋友參考,都是一些...

    wean 評(píng)論0 收藏0
  • vue組件通信全面總結(jié)

    摘要:當(dāng)一個(gè)組件沒有聲明任何時(shí),這里會(huì)包含所有父作用域的綁定和除外,并且可以通過傳入內(nèi)部組件在創(chuàng)建高級(jí)別的組件時(shí)非常有用。 寫在前面 組件間的通信是是實(shí)際開發(fā)中非常常用的一環(huán),如何使用對(duì)項(xiàng)目整體設(shè)計(jì)、開發(fā)、規(guī)范都有很實(shí)際的的作用,我在項(xiàng)目開發(fā)中對(duì)此深有體會(huì),總結(jié)下vue組件間通信的幾種方式,討論下各自的使用場(chǎng)景 文章對(duì)相關(guān)場(chǎng)景預(yù)覽 父->子組件間的數(shù)據(jù)傳遞 子->父組件間的數(shù)據(jù)傳遞 兄弟...

    余學(xué)文 評(píng)論0 收藏0
  • vue2.0學(xué)習(xí)筆記(組件基礎(chǔ))

    摘要:組件的復(fù)用你可以將組件進(jìn)行任意次數(shù)的復(fù)用注意當(dāng)點(diǎn)擊按鈕時(shí),每個(gè)組件都會(huì)各自獨(dú)立維護(hù)它的。 1、基本示例 // 定義一個(gè)名為 button-counter 的新組件 Vue.component(button-counter, { data: function () { return { count: 0 } }, template: You cli...

    mingzhong 評(píng)論0 收藏0
  • 論如何用Vue實(shí)現(xiàn)一個(gè)彈窗-一個(gè)簡單組件實(shí)現(xiàn)

    摘要:前言最近在使用框架,用到了對(duì)話框組件,大致實(shí)現(xiàn)的效果,跟我之前自己在移動(dòng)端項(xiàng)目里面弄的一個(gè)彈窗組件差不太多?,F(xiàn)在基本上彈窗組件都已實(shí)現(xiàn)的差不多了,還差一個(gè)彈窗的關(guān)閉事件,這里就涉及到子組件往父組件傳參了。 前言 最近在使用element-ui框架,用到了Dialog對(duì)話框組件,大致實(shí)現(xiàn)的效果,跟我之前自己在移動(dòng)端項(xiàng)目里面弄的一個(gè)彈窗組件差不太多。然后就想著把這種彈窗組件的實(shí)現(xiàn)方式與大家...

    xialong 評(píng)論0 收藏0
  • 論如何用Vue實(shí)現(xiàn)一個(gè)彈窗-一個(gè)簡單組件實(shí)現(xiàn)

    摘要:前言最近在使用框架,用到了對(duì)話框組件,大致實(shí)現(xiàn)的效果,跟我之前自己在移動(dòng)端項(xiàng)目里面弄的一個(gè)彈窗組件差不太多?,F(xiàn)在基本上彈窗組件都已實(shí)現(xiàn)的差不多了,還差一個(gè)彈窗的關(guān)閉事件,這里就涉及到子組件往父組件傳參了。 前言 最近在使用element-ui框架,用到了Dialog對(duì)話框組件,大致實(shí)現(xiàn)的效果,跟我之前自己在移動(dòng)端項(xiàng)目里面弄的一個(gè)彈窗組件差不太多。然后就想著把這種彈窗組件的實(shí)現(xiàn)方式與大家...

    snowLu 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<