Vue 初心者筆記 #17 Props – 由外到內的資料傳遞
本篇文章介紹父子元件之間,由外到內的資料傳遞方式 Props。
Props 基本介紹
Props 是由外層到內層的資料傳遞,分為「靜態傳遞」與「動態傳遞」。
靜態傳遞
直接透過 props
把資料傳進來。
動態傳遞
如果外部資料是即時變動的,我們會使用 v-bind
的方式 (:img-url
) 綁定外層的動態資料。
下方例子中,整個 Vue 應用程式(外層)有一份資料叫做 url
,我們要把它傳到內層的 img-url
裡面做使用。
(這個內層的 img-url
就是 props
定義的 imgUrl
)
等價命名 (camelCase vs. kebab-case)
因為 HTML 的「特性名」是大小寫不敏感的,瀏覽器會把所有大寫字符解釋為小寫字符,因此這裡遇到大寫時要換成 dash (-
) 符號。
因此,camelCase(小駝峰命名)與 kebab-case(短橫線分隔命名)是等價的。
Props 注意事項
單向數據流
下方範例中,如果修改 <input>
標籤裡的值,會因為 Vue 無法更改 props
從外層傳進來的值的緣故,而跳出錯誤訊息。
這個就是 props
「單向數據流」的概念。
Vue 希望 props
傳進來的資料盡量維持單向,而不要反向地寫回去。
因此,要避免這個錯誤,我們可以另外新建一個 data
,來接收 props
從外部傳進來的資料內容。
我們定義一個新的變數 newUrl
來接 props
從外部傳進來的資料,
避免 imgUrl
直接與外層的資料(圖片網址 url
)進行綁定。
把
imgUrl
換成newUrl
,多一層的概念。
這時候,我們再來調整這個變數就不會有問題囉!
尚未宣告的變數
有時候,我們的資料匯入會有一些時間差,導致 Vue 出現抓不到值的錯誤。
這時候我們可以使用 v-if
讓元件的產生時間往後移,讓資料完成時才同步繪製元件!
範例程式碼:
問題:變數還沒傳進去,導致元件跳錯。
解法:如果有電話號碼,才繪製出卡片。
在這個例子中,我們透過 AJAX 抓取遠端的資料後,存進宣告的變數 user
裡面,再將這些圖片顯示出來。
但是因為 user
在做這些傳入的動作時會有時間差,所以會出現找不到變數的錯誤。
因此我們使用 v-if
,假設 user
裡面的某個特性還沒載入,就先不要執行渲染至畫面的動作。
選取一個一定會有的特性,像是這裡就選擇用電話號碼
phone
。
物件傳參考的特性
如果我們在畫面上修改 card user
裡面的 email
,可以發現 Root user
的 email
也會改變,這是因為「物件」會傳遞「參考值」的特性。
我們可以透過下面這個例子來理解。
1 | var a = { user: '小明' }; |
範例中,我們將 b
的 user
改為 '小強'
,結果 a
的 user
也會變成 '小強'
。
這是因為 a
物件在傳遞的時候,是把整個參考值傳遞到 b
上面,所以這時候如果 b
修改,a
也會被修改。
因此,我們在修改 email
的值的時候,外層的 email
的值也會被修改。
維持狀態與生命週期
下面這個例子裡的 <keep-card>
元件,可以透過 Checkbox 的勾選來重新生成。每次勾選 Checkbox,都會讓元件銷毀再生成,即重新執行 AJAX。
如果這是我們想要的結果,那沒問題!
但是如果不希望每次元件生成時,都重新執行一次裡面的程式碼的話,
我們可以給它加上 <keep-alive>
標籤,並把 v-if
從 div
移到卡片上面。
此外,這邊也有剛才提到的時間差問題(AJAX 還沒執行完成,資料還沒有載入好),
所以我們加上v-if
確保資料載入後才讀出資料內容。
取消勾選後,從 Vue DevTools 可以看到 <KeepCard>
會變成 inactive
(暫時隱藏)的狀態。
下次啟動時,就不會重新執行元件的整個生命週期,而是會直接把它呼叫出來囉!
Props 型別與預設值
型別
用 props
傳遞外層資料到內層時,如果要顯示數值資料,可以直接設定 props
的資料型別 (type
),
同時外層的 data
也要以純數值 (Number) 傳遞,不要寫成 String。
預設值
有時候製作元件時,希望它能帶有預設值,可以直接於 props
裡設定 default
屬性。
靜態與動態傳入數值的差異
在使用 HTML 屬性傳入資料內容時,有分為靜態屬性與動態屬性。
以範例中的 HTML 屬性 money
為例:
數值於靜態屬性 money
傳入時會是「字串」,
若加上冒號 :money
,改為動態傳入時,這時候的數值就會是「數值」。
以上資源是我自己整理過後的筆記,若有錯誤歡迎隨時和我聯繫。