prop
組件實例的作用域是孤立的。這意味着不能 (也不應該) 在子組件的模板內直接引用父組件的數據。要讓子組件使用父組件的數據,需要通過子組件的 props 選項
一個組件默認可以擁有任意數量的 prop,任何值都可以傳遞給任何 prop。
在上述模板中,你會發現我們能夠在組件實例中訪問這個值,就像訪問 data 中的值一樣。
使用Prop傳遞數據包括靜態和動態兩種形式。
1.靜態props
//父組件
<template> <div id="app"> <v-child info="message"></v-child> </div> </template> <script> import Child from './components/Child' export default { components:{ 'v-child':Child }, data(){ return{ message:'' } } } </script>
//子組件
<template> <div>{{info}}</div> </template> <script> export default { props:['info'] } </script>
2.動態props
使用v-bind綁定要傳遞的數據。每當父組件的數據變化時,該變化也會傳導給子組件。
<template>
<div id="app">
<div>父級:<input type="text" v-model="message"></div>
<v-child info="message"></v-child>
</div>
</template>
<script>
import Child from './components/Child'
export default {
components:{
'v-child':Child
},
data(){
return{
message:''
}
}
}
</script>
<template>
<div>{{info}}</div>
</template>
<script>
export default {
props:['info']
}
</script>
3.單向數據流
prop 是單向綁定的:當父組件的屬性變化時,將傳導給子組件,但是不會反過來。這是為了防止子組件無意修改了父組件的狀態——這會讓應用的數據流難以理解。
每次父組件更新時,子組件的所有 prop 都會更新為最新值。這意味着不應該在子組件內部改變 prop。如果這么做了,Vue 會在控制台給出警告
//父
<template> <div id="app"> <div>父級:<input type="text" v-model="message"></div> <v-child :info="message"></v-child> </div> </template> <script> import Child from './components/Child' export default { components:{ 'v-child':Child }, data(){ return{ message:'' } } } </script>
//子 <template> <div>子:<input type="text" v-model="info"></div> </template> <script> export default { props:['info'] } </script>
控制台彈出警告
[Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value.
4.實現組件屬性的雙向綁定方式
修改prop中的數據,通常有以下原因
- 組件內部需要修改props。
- 組件需要可以由外部在運行時動態控制,而非單純初始化。
- 組件外部需要讀取組件內的狀態來進行處理
[注意]JS中對象和數組是引用類型,指向同一個內存空間,如果 prop 是一個對象或數組,在子組件內部改變它會影響父組件的狀態
解決方式:
1. 在組件內的data對象中創建一個props屬性的副本
2. 創建針對props屬性的watch來同步組件外對props的修改
3. 創建針對props副本的watch,通知到組件外
5.prop驗證
為組件的 prop 指定驗證要求,例如你知道的這些類型。如果有一個需求沒有被滿足,則 Vue 會在瀏覽器控制台中警告你。
props: { // bookList: Array 正確的props傳入的bookList類型是數組,但是下面定義的是對象 bookList: Object },
當prop驗證類型錯誤時,提示

prop 可驗證的數據類型
StringNumberBooleanArrayObjectDateFunctionSymbol
props: { // 基礎的類型檢查 (`null` 和 `undefined` 會通過任何類型驗證) propA: Number, // 多個可能的類型 propB: [String, Number], // 必填的字符串 propC: { type: String, required: true }, // 帶有默認值的數字 propD: { type: Number, default: 100 }, // 帶有默認值的對象 propE: { type: Object, // 對象或數組默認值必須從一個工廠函數獲取 default: function () { return { message: 'hello' } } }, // 自定義驗證函數 propF: { validator: function (value) { // 這個值必須匹配下列字符串中的一個 return ['success', 'warning', 'danger'].indexOf(value) !== -1 } } }
注意:vue props 設置的默認值和類型檢查之類的只檢測第一層,而里層的內容是不檢測的
props: { messageA: { type: String, required: true }, // 上邊的是可以的,而下邊的是不可以的 下面的data是第一層,prop會檢測類型為對象,第二次為type 類型為數組,prop不會檢測第二層 messageB: { data:{ type: Array, default: 100 }, } }
//父組件 <v-chapter :chapter-name="chapter_name"></v-chapter> data(){ return{ book_id:'', chapter_name:[], } }, //子組件 export default { name:'chapter', props: { chapterName: Array, }, } //父組件使用chapter-name 子組件需要使用駝峰 chapterName
6.prop傳遞函數
