這個單元在說明 props 的特性
Passing a Boolean
當某個元件的 props 限定傳入的值的型別是布林型別。 那我們直接將該 props 放在該元件的標籤中不用傳入任何值,它預設傳入的值會是 true 。
ex:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| ---HTML--- <div id="app"> <basic-component :basic-name="name" active></basic-component> </div>
---JavaScript--- const BasicComponent = { template:`<div>{{ basicName }}</div>`, props: { basicName: String, active: Boolean, } } Vue.component('basic-component', BasicComponent)
|
你可以看到 active 這個 props 我們沒有為它設入任何值,他預設會傳入 true 。
當要綁定很多屬性時,使用 v-bind
當我們在某一個元件標籤上要傳入很多屬性時,我們可以將這些屬性都加到某一個物件中,並用 v-bind 來達成一樣的效果。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| ---HTML--- <div id="app"> <basic-component v-bind="basicBind"></basic-component> </div>
---JavaScript--- const BasicComponent = { template:`<div>{{ basicName }}</div>`, props: { basicName: String, active: Boolean, 'is-active': Boolean } } Vue.component('basic-component', BasicComponent)
new Vue ({ el: '#app', data: { name: 'Landy' }, computed: { basicBind () { return { 'basic-name': this.name, active: true, 'is-active': true } } } })
|
你可以看到以上的範例,我們直接用 basicBind 將我們要傳入的屬性包起來,並用 v-bind 來將這個物件內容傳進來。 就等同於我們一個屬性一個屬性綁定的效果是一樣的。
Vue 元件的 props 定義寫法
Alex 大大是比較常使用最完整的寫法
props 自身其實有以下幾種屬性,分別為
type: 傳入資料型別
required: 是否為必填,若 true 則必填,若 false 則非必填
default: 預設內容
validator: 藉由傳進來的值,判斷是否符合內容,藉此來回傳 true 或 false
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| const BasicComponent = { template: `<div></div>`, props: { propC: { type: String, default: 'default' }, propC: { type: String, required: true }, } } Vue.component('basic-component', BasicComponent)
|
props 的 validator 屬性
這個屬性上面有講過,可以判斷傳進來的值,是否符合內容。
這種功能可以將使用者輸入的內容控制在自己可以預期的狀態內容,若輸入預期外的內容,就可以發現了。
ex:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| ---HTML--- <basic-component basic-name="danger"></basic-component
---JavaScript--- const BasicComponent = { template:`<div>{{ basicName }}</div>`, props: { basicName: { type: String, default: 'XXX', validator: function (value) { return ['success', 'danger'].indexOf(value) !== -1 } }
} } Vue.component('basic-component', BasicComponent)
|
上面這個範例我們直接傳入字串 danger,就會符合 validator 的陣列內容,並回傳 true。
Non-Prop Attributes
這種 attribute 被寫在 Vue 元件上,但沒有被定義在這個 Vue 的 props 中。
ex:
1 2 3 4 5 6 7 8 9 10
| ---HTML--- <input-component checked></input-component>
---JavaScript--- const InputComponent = { template: `<label> <input type="checkbox"> </label>` } Vue.component('input-component', InputComponent)
|
以上這個範例中的 checked 屬性就沒有被定義在元件 input-component 的 props 中,但我們還是將他加在 input-component 上,此時,這個屬性會自動的被加在這個這個元件的 template 中的第一層 DOM 上,
以上面這個範例為例,第一層 DOM 是 label ,所以,該 checked 的屬性會直接被加在 label 但這不是我們要的效果,我們希望它加在內層的 input 元素上,所以,這時候我們就要引入 inheritAttrs: false 和 $attrs 的功用了。
移除繼承元件屬性的效果
我們利用 inheritAttrs: false 和 $attrs 的功用來達到移除繼承元件屬性的效果。
ex:
1 2 3 4 5 6 7 8 9 10 11
| ---HTML--- <input-component checked="checked"></input-component>
---JavaScript--- const InputComponent = { template: `<label> <input type="checkbox" v-bind="$attrs"> </label>`, inheritAttrs: false } Vue.component('input-component', InputComponent)
|
可以看到我們加上了 inheritAttrs: false 在該元件的定義中,並把 v-bind = “$attrs” 加在想繼承該元件屬性的 input 元素上。
另外,也要注意我們在元件上的 checked 就有為它再賦值 checked ,而不是只有單純寫一個 checked 在上面而已。
經過以上的處理我們就能將 checked=”checked” 的效果傳到 input 元素中了,不然,在你將自動繼承的。功能關掉的時候, Vue 會預設將元件上所加的屬性值設為空值。
Replacing/Merging with Existing Attributes
class 的合併情況
在使用手冊上有說 Vue 會將加在 component 上的 class 和在該 component 中的 元素的 class 合併在一起。
style 的合併情況
那 style 的部分也是會合併在一起,但是要特別注意的是,如果你的 component 上的 style 和 template 中的第一層 DOM 的 style 有相同的 css 樣式的時候,template 內的 style 會被 component 上的樣式給覆蓋掉喔。
ex:
1 2 3 4 5 6 7 8 9 10 11 12
| ---HTML--- <basic-component basic-name="danger" style="background-color: blue;"></basic-component>
---JavaScript--- const BasicComponent = { template:`<div style="background-color: red;"> <div> {{ basicName }} </div> </div>` } Vue.component('basic-component', BasicComponent)
|
上面這個範例中,在 component 上的 background-color: blue 會覆蓋掉第一層 DOM 的 background-color: red 。
Alex 宅幹嘛 - 眉眉角角
props 自動轉成字串型別
如果沒有將 v-bind 加到元件的 props 的話,傳入的資料型別會自動被轉為字串型別
ex:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| ---HTML--- <div id="app"> <basic-component basic-name="Landy"></>basic-component </div>
---JavaScript--- const BasicComponent = { template: `<div>{{ basicName }}</div>`, props: ['basicName'] } Vue.component('basic-component', BasicComponent)
new Vue({ el: '#app' })
|
以上這個範例 basicName 的 props 部分直接傳入 Landy,因為它沒有被用 v-bind 做綁定,所以這筆 Landy 資料會直接被轉為字串型別。
限定傳入的 props 資料型別
限定傳入的 props 資料型別,卻沒有為該 props 用 v-bind 綁定
ex:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| ---HTML--- <div id="app"> <basic-component basic-name="Landy"></basic-component> </div>
---JavaScript--- const BasicComponent = { template:`<div>{{ basicName }}</div>`, props: { basicName: Number } }
Vue.component('basic-component', BasicComponent)
|
你可以看到以上的範例,我們限制 BasicComponent 的 basicName 傳入的資料型別要為 Number,但我們卻沒有為這個 props 加上 v-bind ,此時,你的瀏覽器就會報錯囉。
也就是說,若你今天希望傳入的資料型別改變可能改成數字型別、陣列 或 物件型別,那你就一定要為該 props 加上 v-bind 喔。
這個傳入資料的小細節要特別注意優~