vue.js中怎么利用props傳遞參數(shù),針對(duì)這個(gè)問(wèn)題,這篇文章詳細(xì)介紹了相對(duì)應(yīng)的分析和解答,希望可以幫助更多想解決這個(gè)問(wèn)題的小伙伴找到更簡(jiǎn)單易行的方法。
創(chuàng)新互聯(lián)堅(jiān)持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:成都做網(wǎng)站、成都網(wǎng)站建設(shè)、成都外貿(mào)網(wǎng)站建設(shè)、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿足客戶于互聯(lián)網(wǎng)時(shí)代的興國(guó)網(wǎng)站設(shè)計(jì)、移動(dòng)媒體設(shè)計(jì)的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!1. 問(wèn)題發(fā)現(xiàn)
在父組件中,需要向表格組件傳遞的數(shù)據(jù)有表格的內(nèi)容數(shù)據(jù)tableData,表格的頁(yè)面數(shù)據(jù)page。
其中tableData是個(gè)Array對(duì)象,是所有需要在表格中展示的數(shù)據(jù)對(duì)象組成的一個(gè)數(shù)組。而pageInfo是個(gè)Object對(duì)象,包含了表格頁(yè)面信息。在父組件對(duì)兩個(gè)數(shù)據(jù)對(duì)如下初始化,形式如下
tableData:[], pageInfo: { current: 1, // 當(dāng)前是第幾頁(yè) total: 100, // 數(shù)據(jù)對(duì)象的總數(shù) size: 20 // 每頁(yè)顯示的數(shù)量 }
按照官方文檔上的說(shuō)明,prop是單向綁定的,不應(yīng)該在子組件內(nèi)部改變prop。之所以有想修改prop中數(shù)據(jù)的沖動(dòng),主要是prop作為初始值傳入后,子組件想把它當(dāng)作局部數(shù)據(jù)來(lái)用。對(duì)于這種情況,官方的說(shuō)法是定義一個(gè)局部變量,并用 prop 的值初始化它:
props: ['tableData', 'pageInfo'], data() { return { tData: this.tableData, page: this.pageInfo } }
然后根據(jù)官方文檔的說(shuō)法,當(dāng)每次父組件更新時(shí),子組件的所有prop都會(huì)更新為最新值。而tableData和pageInfo的信息是異步通過(guò)api從server端獲取的:
{ error: 0, msg: "調(diào)用成功.", data: { restrictioninfo: [...], total: 42 } }
因此當(dāng)獲取到數(shù)據(jù)時(shí)父組件需要改變傳入子組件中的值:
me.tableData = Json.data.restrictioninfo; me.pageInfo.total = Json.data.total;
按理說(shuō)這時(shí)候子組件中的值應(yīng)該更新成server返回的值,但是子組件頁(yè)面的總數(shù)更新了,但table數(shù)據(jù)依然是初始化時(shí)的空數(shù)組。(黑人問(wèn)號(hào)???)
。
2.賦值與綁定
首先需要定位數(shù)據(jù)是在哪個(gè)地方出了問(wèn)題,于是我做了一個(gè)demo來(lái)定位問(wèn)題。
首先看父組件與子組件中各元素的初始值:
然后當(dāng)只改變父組件中數(shù)組的引用時(shí)可以看到子組件的props數(shù)組隨之改變,而子組件中綁定的數(shù)組確并沒(méi)有隨之改變
因此,可以發(fā)現(xiàn),問(wèn)題是出在了這一步
props: ['tableData', 'pageInfo'], data() { return { tData: this.tableData, page: this.pageInfo } }
而要弄清楚問(wèn)題的根源,就得弄清楚vue文檔中深入響應(yīng)式原理。
"在Vue實(shí)例的data選項(xiàng)中,Vue將遍歷此對(duì)象所有的屬性,并使用Object.defineProperty把這些屬性全部轉(zhuǎn)為 getter/setter","每個(gè)組件實(shí)例都有相應(yīng)的 watcher 實(shí)例對(duì)象,它會(huì)在組件渲染的過(guò)程中把屬性記錄為依賴,之后當(dāng)依賴項(xiàng)的 setter 被調(diào)用時(shí),會(huì)通知 watcher 重新計(jì)算,從而致使它關(guān)聯(lián)的組件得以更新。"文檔中說(shuō)了這么一大堆,簡(jiǎn)單理解就是Vue將data選項(xiàng)中的vm.$data.a與DOM中的vm.a進(jìn)行了雙向綁定,即其中一個(gè)變化,另一個(gè)也會(huì)跟著變化。在Vue源碼中是由defineReactive$$1函數(shù)實(shí)現(xiàn)的:
但在子其中主要是利用了Object.defineProperty的get和set方法實(shí)現(xiàn)了雙向綁定。而在子組件中,pros數(shù)據(jù)和子組件的$data是通過(guò)如下方式聯(lián)系在一起的:
tData: this.tableData
查詢Vue源碼可知this.tableData與tData之間僅僅是賦值,即"="關(guān)系
而上述的initData函數(shù)是在組件構(gòu)建時(shí)候執(zhí)行的,因此只會(huì)在create時(shí)執(zhí)行一次。這也是為什么官方文檔中"作為初始值傳入"這一說(shuō)法,因?yàn)樗揪椭粫?huì)執(zhí)行一次。當(dāng)組件構(gòu)建完成后,this.tableData與tData就沒(méi)有半毛錢(qián)關(guān)系了,其中一個(gè)的變化并不會(huì)引起另一個(gè)變化。當(dāng)然,這種說(shuō)法并不準(zhǔn)確,因?yàn)樵谏衔闹?,我們?dòng)態(tài)改變父組件傳入的total,子組件也"隨之"改變,感覺(jué)就像是綁定在一起了啊,這又是怎么回事呢?
3.引用類型帶來(lái)的假象
當(dāng)然,我們還是要從官方文檔出發(fā)來(lái)解決這個(gè)問(wèn)題。文檔中有這樣一個(gè)提示:
這里就需要理解引用類型的概念,引用數(shù)據(jù)類型值指保存在堆內(nèi)存中的對(duì)象。也就是,變量中保存的實(shí)際上的只是一個(gè)指針,這個(gè)指針指向內(nèi)存中的另一個(gè)位置,該位置保存著對(duì)象。訪問(wèn)方式是按引用訪問(wèn)。例如一個(gè)js對(duì)象a,他在內(nèi)存中的存儲(chǔ)形式如下圖所示:
var a = new Object();
當(dāng)操作時(shí),需要先從棧中讀取內(nèi)存地址,然后再延指針找到保存在堆內(nèi)存中的值再操作。
a.name = 'xz';
引用類型變量賦值,本質(zhì)上賦值的是存儲(chǔ)在棧中的指針,將指針復(fù)制到棧中未新變量分配的空間中,而這個(gè)指針副本和原指針指向存儲(chǔ)在堆中的同一個(gè)對(duì)象;賦值操作結(jié)束后,兩個(gè)變量實(shí)際上將引用同一個(gè)對(duì)象。因此,在使用時(shí),改變其中的一個(gè)變量的值,將影響另一個(gè)變量。
var b = a;
在了解了引用類型之后,我們?cè)趤?lái)看看上文提到的動(dòng)態(tài)改變傳入子組件前后內(nèi)存中的情況:
me.tableData = Json.data.restrictioninfo; me.pageInfo.total = Json.data.total; ======================================== props: ['tableData', 'pageInfo'], data() { return { tData: this.tableData, page: this.pageInfo } }
首先對(duì)tableData的改變是改變了其引用的指針,而對(duì)pageInfo則改變了其中一個(gè)屬性的值,因此動(dòng)態(tài)改變前:
動(dòng)態(tài)改變后:
關(guān)于vue.js中怎么利用props傳遞參數(shù)問(wèn)題的解答就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,如果你還有很多疑惑沒(méi)有解開(kāi),可以關(guān)注創(chuàng)新互聯(lián)成都網(wǎng)站設(shè)計(jì)公司行業(yè)資訊頻道了解更多相關(guān)知識(shí)。
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無(wú)理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。