## Prop
### 使用Prop傳遞數據
組件實例的作用域是孤立的。這意味著不能(也不應該)在子組件的模板內直接引用父組件的數據。要讓子組件使用父組件的數據,我們需要通過子組件的props選項。
子組件要顯式地用 props 選項聲明它期待獲得的數據:
~~~
Vue.component('child', {
// 聲明 props
props: ['message'],
// 就像 data 一樣,prop 可以用在模板內
// 同樣也可以在 vm 實例中像 “this.message” 這樣使用
template: '<span>{{ message }}</span>'
})
~~~
然后我們可以這樣向它傳入一個普通字符串:
~~~
<child message="hello!"></child>
~~~
>[info]完整代碼示例:
~~~
<div id="app">
<child message="hello!"></child>
</div>
<script type="text/javascript">
Vue.component('child', {
// 聲明 props
props: ['message'],
// 就像 data 一樣,prop 可以用在模板內
// 同樣也可以在 vm 實例中像 “this.message” 這樣使用
template: '<span>{{ message }}</span>'
})
new Vue({
el:'#app'
});
</script>
~~~
頁面顯示效果為:hello
### camelCase vs.kebab-case
HTML 特性是不區分大小寫的。所以,當使用的不是字符串模版,camelCased (駝峰式) 命名的 prop 需要轉換為相對應的 kebab-case (短橫線隔開式) 命名:
~~~
Vue.component('child', {
// camelCase in JavaScript
props: ['myMessage'],
template: '<span>{{ myMessage }}</span>'
})
~~~
~~~
<!-- kebab-case in HTML -->
<child my-message="hello!"></child>
~~~
如果你使用字符串模版,則沒有這些限制。
>[info]完整代碼示例:
~~~
<div id="app">
<child my-message="hello!"></child>
</div>
<script type="text/javascript">
Vue.component('child', {
// camelCase in JavaScript
props: ['myMessage'],
template: '<span>{{ myMessage }}</span>'
})
new Vue({
el:'#app'
});
</script>
~~~
### 動態Prop
在模板中,要動態地綁定父組件的數據到子模板的props,與綁定到任何普通的HTML特性相類似,就是用 v-bind。每當父組件的數據變化時,該變化也會傳導給子組件:
~~~
<div>
<input v-model="parentMsg">
<br>
<child v-bind:my-message="parentMsg"></child>
</div>
~~~
使用 v-bind 的縮寫語法通常更簡單:
~~~
<child :my-message="parentMsg"></child>
~~~
>[info]完整代碼示例:
~~~
<div id="app">
<input v-model="parentMsg">
<br>
<child v-bind:my-message="parentMsg"></child>
</div>
<script type="text/javascript">
new Vue({
el:'#app',
data: {
parentMsg: 'Message from parent'
},
components: {
child: {
props: ['myMessage'],
template: '<span>{{myMessage}}</span>'
}
}
});
</script>
~~~
### 字面量語法 VS 動態語法
初學者常犯的一個錯誤是使用字面量語法傳遞數值:
~~~
<!-- 傳遞了一個字符串 "1" -->
<comp some-prop="1"></comp>
~~~
因為它是一個字面 prop ,它的值是字符串 "1" 而不是number。如果想傳遞一個實際的number,需要使用 v-bind ,從而讓它的值被當作 JavaScript 表達式計算:
~~~
<!-- 傳遞實際的 number -->
<comp v-bind:some-prop="1"></comp>
~~~
### 單向數據流
prop 是單向綁定的:當父組件的屬性變化時,將傳導給子組件,但是不會反過來。這是為了防止子組件無意修改了父組件的狀態——這會讓應用的數據流難以理解。
另外,每次父組件更新時,子組件的所有 prop 都會更新為最新值。這意味著你不應該在子組件內部改變 prop 。如果你這么做了,Vue 會在控制臺給出警告。
為什么我們會有修改prop中數據的沖動呢?通常是這兩種原因:
- prop 作為初始值傳入后,子組件想把它當作局部數據來用;
- prop 作為初始值傳入,由子組件處理成其它數據輸出。
對這兩種原因,正確的應對方式是:
- 1.定義一個局部變量,并用 prop 的值初始化它:
~~~
props: ['initialCounter'],
data: function () {
return { counter: this.initialCounter }
}
~~~
- 2.定義一個計算屬性,處理 prop 的值并返回。
~~~
props: ['size'],
computed: {
normalizedSize: function () {
return this.size.trim().toLowerCase()
}
}
~~~
>[danger]注意在 JavaScript 中對象和數組是引用類型,指向同一個內存空間,如果 prop 是一個對象或數組,在子組件內部改變它會影響父組件的狀態。
### Prop驗證
我們可以為組件的 props 指定驗證規格。如果傳入的數據不符合規格,Vue 會發出警告。當組件給其他人使用時,這很有用。
要指定驗證規格,需要用對象的形式,而不能用字符串數組:
~~~
Vue.component('example', {
props: {
// 基礎類型檢測 (`null` 意思是任何類型都可以)
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 value > 10
}
}
}
})
~~~
type 可以是下面原生構造器:
- String
- Number
- Boolean
- Function
- Object
- Array
type 也可以是一個自定義構造器函數,使用 instanceof 檢測。
當 prop 驗證失敗,Vue會在拋出警告 (如果使用的是開發版本)。
- 前端新手村
- 前言
- 第1章 遇見Vue.js
- 第一個Vue.js程序
- vue嘗鮮
- 第2章 概念理解
- 漸進式框架
- 虛擬DOM
- MVVM模式
- MVX模式是什么
- 第3章 Vue基礎概覽
- 第4章 Vue內置指令詳解
- vue-text
- vue-html
- v-show
- v-if
- v-else
- v-else-if
- v-for
- v-on
- v-bind
- v-model
- v-pre
- v-cloak
- v-once
- 第5章 基礎demo小練習
- 圖書管理系統
- 頁面布局
- 列表渲染
- 功能實現
- 基于BootStrap+Vuejs實現用戶信息表
- 功能描述
- 布局實現
- 星座判斷
- 第6章 組件
- 什么是組件
- 使用組件
- Prop
- 自定義事件
- 使用Slot分發內容
- 動態組件
- 雜項
- 第7章-過渡
- 過渡效果
- 概述
- 單元素/組件的過渡
- 初始渲染的過渡
- 多個元素的過渡
- 多個組件的過渡
- 列表過渡
- 可復用的過渡
- 動態過渡
- 過渡狀態
- 狀態動畫與watcher
- 動態狀態轉換
- 通過組件組織過渡
- Render函數
- 基礎
- createElement參數
- 使用JavaScript代替模板功能
- JSX
- 函數化組件
- 模板編譯
- 自定義指令
- 簡介
- 鉤子函數
- 鉤子函數參數
- 函數簡寫
- 對象字面量
- Vuex狀態管理
- Vuex是什么?
- Vuex的安裝
- Vuex起步
- data的替代品-State和Getter
- 測試Getter
- Action-操作的執行者
- 測試Action
- 只用Mutation修改狀態
- 測試Mutations
- Vuex的基本結構
- 子狀態和模塊
- 用服務分離外部操作
- Vue-router
- Vue-router是什么
- Vue-router安裝
- 基本用法1
- 基本用法2
- Vue-cli
- Vue中的Node.js
- Vue中的npm、cnpm
- Vue中的webpack
- 安裝
- 基本使用
- 模板
- 全局API
- Vue.extend
- Vue.nextTick
- Vue.set
- Vue.delete
- Vue.directive
- Vue.filter
- Vue.component
- Vue.use
- Vue.mixin
- Vue.compile
- 附錄
- 相關網站
- 尤雨溪
- 第10章 webpack
- webpack安裝
- webpack基本使用
- webpack命令行
- webpack配置文件
- 單頁面應用SPA
- 第1章 Vue.js簡介
- 1.1 Vue.js簡介
- 1.1.1 Vue.js是什么
- 1.1.2 為什么要用Vue.js
- 1.1.3 Vue.js的發展歷史
- 1.1.4 Vue.js與其他框架的區別
- 1.2 如何使用Vue.js
- 1.2.1 第一個Vue.js程序
- 1.2.2 Vue.js小嘗鮮
- 1.3 概念詳解
- 1.3.1 什么是漸進式框架
- 1.3.2 虛擬DOM是什么
- 1.3.3 如何理解MVVM
- 第2章 基礎概覽
- 2.1 Vue實例
- 2.1.1 構造器
- 2.1.2 屬性與方法
- 2.1.3 實例生命周期
- 2.1.4 生命周期圖示
- 2.2 模板語法
- 2.2.1 插值
- 2.2.2 指令
- 2.2.3 過濾器
- 2.2.4 縮寫
- 第3章 Class與Style的綁定
- 第4章 模板渲染
- 第5章 事件詳解
- 第6章 表單控件綁定
- 第7章 指令詳解
- 7.1 內部指令
- 7.2 自定義指令
- 7.3 指令的高級選項
- 第8章 計算屬性
- 第9章 過濾器
- 第10章 組件
- 10.1 什么是組件
- 10.2 注冊組件
- 10.3 組件選項
- 10.4 組件間的通信
- 10.5 內容分發
- 10.6 動態組件