0%

Alex宅幹嘛ReVue-Day10-元件props

這個單元在說明 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 喔。
這個傳入資料的小細節要特別注意優~