Vue中 props 這些知識點,可以在來復習一下!
如果你一直在閱讀有關"props"內容,你會發現我們可能也一直在使用它們(即使沒有意識到),但也許你并不完全確定它們是什么。或者如何正確使用它們,并充分利用它們。
當你讀完這篇指南時,你就會知道成為一名高效的Vue開發者所需要知道的關于props的一切。
在本指南中,我們將介紹關于 props 的最重要的事情:
- 什么是 props ?
- props 的兩個主要特點
- 如何將 props 傳遞給其他組件
- 添加 props 類型
- 添加必填的 props
- 設置默認值
什么是 props ?
props 是我們在不同組件之間傳遞變量和其他信息的方式。這類似于在 JS 中,我們可以將變量作為參數傳遞給函數:
這里,我們將變量myMessage作為參數message傳遞給函數。在函數內部,我們可以將該值作為message訪問。
props的工作原理與此非常相似。我們將props傳遞給另一個組件,然后該組件可以使用該值。但是首先需要了解一些規則。
props 的兩個主要特點
在處理props時,有兩件事需要特別注意:
- props 通過組件樹傳遞給后代(而不是向上傳遞)
- props 是只讀的,不能修改
Vue 使用單向數據流,這意味著數據只能從父組件流向子組件,不能將數據從子對象傳遞到父對象。因為父組件“擁有”它傳遞的值,所以子組件不能修改它。如果只允許一個組件更改它,那么跟蹤bug就更容易了,因為我們確切地知道應該從哪里查找。
在開發確保沒有違反這兩條規則,開發就會變得更容易些,出問題也比較好找原因。接著來看看如何將 props 從一個組件傳遞到另一個組件。
將 props 傳遞給其他組件
如果希望將值從組件傳遞到子組件,這與添加HTML屬性完全相同。
- <template>
- <Camera
- name="Sony A7RIV"
- img="../sony-a7riv.jpg"
- />
- </template>
Camera組件將使用name和img props 來渲染自身頁面。內容大概如下:
- <template>
- <div class="camera">
- <h2 class="camera__name">{{ name }}</h2>
- <img class="camera__image" :src="img" />
- </div>
- </template>
在這里,我們將name渲染到h2標記中,并使用img設置img標記上的src屬性。
但是,如果我們將此信息存儲在某個位置的變量中怎么辦?
為此,我們需要使用稍微不同的語法,因為我們希望使用 JS 表達式而不是傳遞字符串。
- <template>
- <Camera
- v-bind:name="cameraName"
- v-bind:img="cameraImage"
- />
- </template>
v-bind:name="cameraName"行告訴Vue將 JS 表達式cameraName綁定到 propname。JS 表達式是 JS 的任何代碼段??赡苁窍裎覀冊诖颂庍@樣的變量名,或更復雜的名稱。
還可以使用邏輯或 img 設置圖像路徑:
- <template>
- <Camera
- v-bind:name="cameraName"
- v-bind:img="cameraImage || '../no-camera-found.jpg'"
- />
- </template>
v-bind 可以用簡寫形式 :
- <template>
- <Camera
- :name="cameraName"
- :img="cameraImage || '../no-camera-found.jpg'"
- />
- </template>
添加 props
在此代碼實際起作用之前,我們需要獲取Camera組件才能實際收聽props。默認情況下,組件會忽略它們。為此,我們必須在組件定義中添加一個props部分:
- export default {
- name: 'Camera',
- props: ['name', 'img'],
- }
通常不建議這么寫,應該為props對象指定類型:
- export default {
- name: 'Camera',
- props: {
- name: {
- type: String,
- },
- img: {
- type: String,
- }
- }
- }
通過從數組到對象,我們可以指定更多的 props 細節,比如類型。我們為什么要向props 添加類型?
在Vue中,props 可以有很多不同的類型:
- String
- Number
- Boolean (true 或者 false)
- Array
- Object
通過添加類型,我們可以設置我們期望收到的數據類型。如果我們將camera的props中的name設置為true,它將無法正常工作,因此Vue會警告我們使用錯誤。
接著添加一個rating到我們的Camera組件中,該 rating 類型為 Number:
- export default {
- name: 'Camera',
- props: {
- name: {
- type: String,
- },
- img: {
- type: String,
- },
- rating: {
- type: Number,
- },
- }
- }
然后在 template 中顯示 rating:
- <template>
- <div class="camera">
- <h2 class="camera__name">{{ name }}</h2>
- <span class="camera__rating">{{ rating }}</span>
- <img class="camera__image" src="img" />
- </div>
- </template>
在外層調用:
- <template>
- <Camera
- name="Sony A7RIV"
- img="../sony-a7riv.jpg"
- :rating="9"
- />
- </template>
必填的 props
不是所有的 props 都是一樣的,為了使組件正常工作,其中一些要求必填的。
對于我們的Camera組件,我們肯定需要一個name,但 img 和 rating 不是必需的。
- export default {
- name: 'Camera',
- props: {
- name: {
- type: String,
- required: true,
- },
- img: {
- type: String,
- },
- rating: {
- type: Number,
- },
- }
- }
export default { name: 'Camera', props: { name: { type: String, required: true, }, img: { type: String, }, rating: { type: Number, }, }}
通過設置 required: true 要求我們的 name 是必需要傳入的,相反,required 為false 對應的props可傳可不傳。
默認值
對于不是每次都傳入的 props,我們可以為其,添加默認值。
- export default {
- name: 'Camera',
- props: {
- name: {
- type: String,
- required: true,
- },
- img: {
- type: String,
- default: '../no-camerage-found.jpg',
- },
- rating: {
- type: Number,
- },
- }
- }
前面我們通過邏輯或為img添加默認值,這次我們使用 default 屬性為img設置默認值。
同樣也需要為我們的rating設置默認值。如果沒有設置也沒有從外部傳入,我們訪問的時候就會得到undefined,這可能會給我們帶來一些問題
在模板外使用 props
雖然能夠在template中使用props很棒,但是真正強大的功能來自于在方法、計算屬性和組件中在使用其他 JS 中使用它們。
在我們的template中,我們看到我們只需要props名稱,例如:{{rating}}。但是,在Vue組件的其他任何地方,我們都需要使用this.rating訪問我們的props。
讓我們重構應用程序,以便為圖像使用標準的URL結構。這樣,我們不必每次都將其傳遞給Camera組件,而只需從名稱中找出即可。
我們將使用以下結構:./images/cameras/${cameraName}.jpg
因此,如果 camera 是Sony A6400,則URL將變為./images/cameras/Sony%20A6400.jpg。%20來自對空格字符的編碼,因此我們可以在URL中使用它。
首先,我們將移除不再需要的img props
- export default {
- name: 'Camera',
- props: {
- name: {
- type: String,
- required: true,
- },
- rating: {
- type: Number,
- default: 0,
- },
- }
- }
然后,我們將添加一個計算屬性,該屬性將為我們生成圖像URL:
并非所有字符都可以在URL中使用,因此encodeURIComponent會為我們轉換這些字符。
因為我們可以使用與常規props相同的方式來訪問此計算 props,所以我們根本不需要更改模板,并且模板可以像以前一樣保持不變:
- <template>
- <div class="camera">
- <h2 class="camera__name">{{ name }}</h2>
- <span class="camera__rating">{{ rating }}</span>
- <img class="camera__image" src="img" />
- </div>
- </template>
這樣,您可以在以下位置使用組件的props:
- watch 中
- 生命周期 hook
- method
- computed 中
以及組件定義中的其他任何地方!
總結
以上,這些是關于 props 的知識點,但是,總會有更多東西要學習。Vue 也是一個永無止境的學習過程。keep going !