做者:Michael Thiessen前端
譯者:前端小智vue
來源:Michaelreact
若是你一直在閱讀有關"props"內容,你會發現咱們可能也一直在使用它們(即便沒有意識到),但也許你並不徹底肯定它們是什麼。或者如何正確使用它們,並充分利用它們。git
當你讀完這篇指南時,你就會知道成爲一名高效的Vue開發者所須要知道的關於props的一切。github
在本指南中,咱們將介紹關於 props 的最重要的事情:面試
props
是咱們在不一樣組件之間傳遞變量和其餘信息的方式。這相似於在 JS 中,咱們能夠將變量做爲參數傳遞給函數:數組
const myMessage = "I'm a string";
function addExclamation(message) {
return message + '!';
}
console.log(addExclamation(myMessage)); // I'm a string!
複製代碼
這裏,咱們將變量myMessage
做爲參數message
傳遞給函數。在函數內部,咱們能夠將該值做爲message
訪問。微信
props
的工做原理與此很是類似。咱們將props
傳遞給另外一個組件,而後該組件可使用該值。可是首先須要瞭解一些規則。函數
在處理props
時,有兩件事須要特別注意:工具
props
經過組件樹傳遞給後代(而不是向上傳遞)
props
是隻讀的,不能修改
Vue 使用單向數據流,這意味着數據只能從父組件流向子組件,不能將數據從子對象傳遞到父對象。由於父組件「擁有」它傳遞的值,因此子組件不能修改它。若是隻容許一個組件更改它,那麼跟蹤bug就更容易了,由於咱們確切地知道應該從哪裏查找。
在開發確保沒有違反這兩條規則,開發就會變得更容易些,出問題也比較好找緣由。接着來看看如何將 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
綁定到 prop name
。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>
複製代碼
在此代碼實際起做用以前,咱們須要獲取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 能夠有不少不一樣的類型:
經過添加類型,咱們能夠設置咱們指望收到的數據類型。若是咱們將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 都是同樣的,爲了使組件正常工做,其中一些要求必填的。
對於咱們的Camera
組件,咱們確定須要一個name
,但 img
和 rating
不是必需的。
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
,這可能會給咱們帶來一些問題
雖然可以在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:
export default {
name: 'Camera',
props: {
name: {
type: String,
required: true,
},
rating: {
type: Number,
default: 0,
},
},
computed: {
img() {
return `./images/cameras/${encodeURIComponent(this.name)}.jpg`;
}
}
}
複製代碼
並不是全部字符均可以在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:
以及組件定義中的其餘任何地方!
以上,這些是關於 props 的知識點,可是,總會有更多東西要學習。 Vue 也是一個永無止境的學習過程。keep going !
代碼部署後可能存在的BUG無法實時知道,過後爲了解決這些BUG,花了大量的時間進行log 調試,這邊順便給你們推薦一個好用的BUG監控工具 Fundebug。
文章每週持續更新,能夠微信搜索「 大遷世界 」第一時間閱讀和催更(比博客早一到兩篇喲),本文 GitHub github.com/qq449245884… 已經收錄,整理了不少個人文檔,歡迎Star和完善,你們面試能夠參照考點複習,另外關注公衆號,後臺回覆福利,便可看到福利,你懂的。