欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解vue.js之props傳遞參數(shù)

 更新時間:2017年12月12日 08:33:43   投稿:laozhang  
給大家詳細(xì)分析了vue.js之props傳遞參數(shù)的相關(guān)知識以及問題解決方法,需要的朋友參考下吧。

本篇文章通過demo實(shí)例給大家詳細(xì)分析了props傳遞參數(shù)的用法以及遇到問題后的解決辦法,以下是全部內(nèi)容。

前段時間用vue做一個后臺管理系統(tǒng),其中每一頁都需要一個表格來展示信息。自然就想到了將表格提取出來做成公共組件,將不同頁面的數(shù)據(jù)傳入進(jìn)行渲染,達(dá)到復(fù)用的目的。

demo地址

1. 問題發(fā)現(xiàn)

在父組件中,需要向表格組件傳遞的數(shù)據(jù)有表格的內(nèi)容數(shù)據(jù)tableData,表格的頁面數(shù)據(jù)page。

<div>
 <my-table :table-data="tableData" :page-info="pageInfo" id="myTable"></my-table>
</div>

其中tableData是個Array對象,是所有需要在表格中展示的數(shù)據(jù)對象組成的一個數(shù)組。而pageInfo是個Object對象,包含了表格頁面信息。在父組件對兩個數(shù)據(jù)對如下初始化,形式如下

tableData:[],
pageInfo: {
 current: 1, // 當(dāng)前是第幾頁
 total: 100, // 數(shù)據(jù)對象的總數(shù)
 size: 20 // 每頁顯示的數(shù)量
}

 

按照官方文檔上的說明,prop是單向綁定的,不應(yīng)該在子組件內(nèi)部改變prop。之所以有想修改prop中數(shù)據(jù)的沖動,主要是prop作為初始值傳入后,子組件想把它當(dāng)作局部數(shù)據(jù)來用。對于這種情況,官方的說法是定義一個局部變量,并用 prop 的值初始化它:

props: ['tableData', 'pageInfo'],
data() {
 return {
  tData: this.tableData,
  page: this.pageInfo
 }
}

然后根據(jù)官方文檔的說法,當(dāng)每次父組件更新時,子組件的所有prop都會更新為最新值。而tableData和pageInfo的信息是異步通過api從server端獲取的:

{
 error: 0,
 msg: "調(diào)用成功.",
 data: {
  restrictioninfo: [...],
  total: 42
 }
}

 

因此當(dāng)獲取到數(shù)據(jù)時父組件需要改變傳入子組件中的值:

me.tableData = Json.data.restrictioninfo;
me.pageInfo.total = Json.data.total;

按理說這時候子組件中的值應(yīng)該更新成server返回的值,但是子組件頁面的總數(shù)更新了,但table數(shù)據(jù)依然是初始化時的空數(shù)組。(黑人問號???)


。

2.賦值與綁定

首先需要定位數(shù)據(jù)是在哪個地方出了問題,于是我做了一個demo來定位問題。

首先看父組件與子組件中各元素的初始值:


然后當(dāng)只改變父組件中數(shù)組的引用時可以看到子組件的props數(shù)組隨之改變,而子組件中綁定的數(shù)組確并沒有隨之改變


因此,可以發(fā)現(xiàn),問題是出在了這一步

props: ['tableData', 'pageInfo'],
data() {
 return {
  tData: this.tableData,
  page: this.pageInfo
 }
}

 

而要弄清楚問題的根源,就得弄清楚vue文檔中深入響應(yīng)式原理。


"在Vue實(shí)例的data選項(xiàng)中,Vue將遍歷此對象所有的屬性,并使用Object.defineProperty把這些屬性全部轉(zhuǎn)為 getter/setter","每個組件實(shí)例都有相應(yīng)的 watcher 實(shí)例對象,它會在組件渲染的過程中把屬性記錄為依賴,之后當(dāng)依賴項(xiàng)的 setter 被調(diào)用時,會通知 watcher 重新計(jì)算,從而致使它關(guān)聯(lián)的組件得以更新。"文檔中說了這么一大堆,簡單理解就是Vue將data選項(xiàng)中的vm.$data.a與DOM中的vm.a進(jìn)行了雙向綁定,即其中一個變化,另一個也會跟著變化。在Vue源碼中是由defineReactive$$1函數(shù)實(shí)現(xiàn)的:

但在子其中主要是利用了Object.defineProperty的get和set方法實(shí)現(xiàn)了雙向綁定。而在子組件中,pros數(shù)據(jù)和子組件的$data是通過如下方式聯(lián)系在一起的:

tData: this.tableData

 

查詢Vue源碼可知this.tableData與tData之間僅僅是賦值,即"="關(guān)系

而上述的initData函數(shù)是在組件構(gòu)建時候執(zhí)行的,因此只會在create時執(zhí)行一次。這也是為什么官方文檔中"作為初始值傳入"這一說法,因?yàn)樗揪椭粫?zhí)行一次。當(dāng)組件構(gòu)建完成后,this.tableData與tData就沒有半毛錢關(guān)系了,其中一個的變化并不會引起另一個變化。當(dāng)然,這種說法并不準(zhǔn)確,因?yàn)樵谏衔闹?,我們動態(tài)改變父組件傳入的total,子組件也"隨之"改變,感覺就像是綁定在一起了啊,這又是怎么回事呢?

3.引用類型帶來的假象

當(dāng)然,我們還是要從官方文檔出發(fā)來解決這個問題。文檔中有這樣一個提示:


這里就需要理解引用類型的概念,引用數(shù)據(jù)類型值指保存在堆內(nèi)存中的對象。也就是,變量中保存的實(shí)際上的只是一個指針,這個指針指向內(nèi)存中的另一個位置,該位置保存著對象。訪問方式是按引用訪問。例如一個js對象a,他在內(nèi)存中的存儲形式如下圖所示:

var a = new Object();

 


當(dāng)操作時,需要先從棧中讀取內(nèi)存地址,然后再延指針找到保存在堆內(nèi)存中的值再操作。

a.name = 'xz';

 


引用類型變量賦值,本質(zhì)上賦值的是存儲在棧中的指針,將指針復(fù)制到棧中未新變量分配的空間中,而這個指針副本和原指針指向存儲在堆中的同一個對象;賦值操作結(jié)束后,兩個變量實(shí)際上將引用同一個對象。因此,在使用時,改變其中的一個變量的值,將影響另一個變量。

var b = a;

 


在了解了引用類型之后,我們在來看看上文提到的動態(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
 }
}

 

首先對tableData的改變是改變了其引用的指針,而對pageInfo則改變了其中一個屬性的值,因此動態(tài)改變前:


動態(tài)改變后:


這樣就解釋了為什么子組件頁面的總數(shù)更新了,但table數(shù)據(jù)依然是初始化時的空數(shù)組。因?yàn)橐妙愋偷拇嬖?,我們動態(tài)改變父組件傳入的total,子組件也"隨之"改變了。

相關(guān)文章

  • Pinia進(jìn)階setup函數(shù)式寫法封裝到企業(yè)項(xiàng)目

    Pinia進(jìn)階setup函數(shù)式寫法封裝到企業(yè)項(xiàng)目

    這篇文章主要為大家介紹了Pinia進(jìn)階setup函數(shù)式寫法封裝到企業(yè)項(xiàng)目實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07
  • vue項(xiàng)目中字符串換行顯示方式(返回的數(shù)據(jù)包含‘\r\n’字符)

    vue項(xiàng)目中字符串換行顯示方式(返回的數(shù)據(jù)包含‘\r\n’字符)

    這篇文章主要介紹了vue項(xiàng)目中字符串換行顯示方式(返回的數(shù)據(jù)包含‘\r\n’字符),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • Vue實(shí)現(xiàn)雙向滑動輸入條

    Vue實(shí)現(xiàn)雙向滑動輸入條

    這篇文章主要為大家詳細(xì)介紹了Vue實(shí)現(xiàn)雙向滑動輸入條,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • 解決vue 局部過濾器獲取不到this的問題

    解決vue 局部過濾器獲取不到this的問題

    這篇文章主要介紹了解決vue 局部過濾器獲取不到this的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-01-01
  • vue3常用的指令之v-bind和v-on指令用法

    vue3常用的指令之v-bind和v-on指令用法

    vue的v-on與v-bind,v-on就是用于綁定事件的,下面這篇文章主要給大家介紹了關(guān)于vue3常用的指令之v-bind和v-on指令用法的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-12-12
  • Vue之組件的自定義事件詳解

    Vue之組件的自定義事件詳解

    這篇文章主要為大家介紹了Vue之組件的自定義事件,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2021-11-11
  • 詳解vue過度效果與動畫transition使用示例

    詳解vue過度效果與動畫transition使用示例

    Vue 在插入、更新或者移除 DOM 時,提供多種不同方式的應(yīng)用過渡效果,Vue 提供了內(nèi)置的過渡封裝組件transition,該組件用于包裹要實(shí)現(xiàn)過渡效果的組件
    2021-10-10
  • vue中使用 pinia 全局狀態(tài)管理的實(shí)現(xiàn)

    vue中使用 pinia 全局狀態(tài)管理的實(shí)現(xiàn)

    本文主要介紹了vue中使用 pinia 全局狀態(tài)管理的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07
  • Vue 搭建Vuex環(huán)境詳解

    Vue 搭建Vuex環(huán)境詳解

    這篇文章主要為大家介紹了Vue搭建Vuex環(huán)境,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2021-11-11
  • Vue中引入第三方JS庫的四種方式

    Vue中引入第三方JS庫的四種方式

    在開發(fā)Vue項(xiàng)目的時候,有時需要使用一些非ES6格式的沒有export的js庫,下面這篇文章主要給大家介紹了關(guān)于Vue中引入第三方JS庫的詳細(xì)步驟,需要的朋友可以參考下
    2022-04-04

最新評論