Andy's blog

If you always do what you've always done, you'll always get what you've always got.

0%

Vue Component(元件) - props使用注意細項(1)

參考資料


props型別介紹

我們知道Props是將外部資料傳入元件內,但你怎麼知道傳入的東西是否符合需求或安全呢?而這時就需要使用到型別驗證。而常見的型別如下:
參考資料:官網類型檢查

1
2
3
4
5
6
7
8
String
Number
Array
Object
Function
Boolean
Date
Symbol

提醒:型別字首要大寫 如:type: Number

範例:

完整內容請看codepen

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
props: {
parentMsg: null, // null 代表不檢查型別
propA: Number, // 限定數字(Number要大寫)
propB: [String, Number], // 多種條件可用 [ ] 隔開
propC: {
// 必要欄位,且限定字串型別
type: String,
required: true
},
// 带有默認值的數字
propD: {
type: Number,
default: 100
},
// 自定義驗證函數
propF: {
validator: function (value) {
// 这个值必须匹配下列字符串中的一个
return ['success', 'warning', 'danger'].indexOf(value) !== -1
}
}
}

提醒:因為props是在元件實體建立前進行驗證,所以實體內屬性(如data、computed等)在default或validator函數中是不可用的。(待補充)

若型別錯誤,會出現下面畫面
注意:檢查型別驗證是否錯誤,只有開發版本(development)上才會出現,production版本不會出現
https://ithelp.ithome.com.tw/upload/images/20191003/20114645Z5hC5XyObA.png

這邊特別注意:
1.驗證object時,default必須為一個function 如下

1
2
3
4
5
6
7
8
9
propE: {
// Object 型別,代表可接受的是個物件型別
type: Object,
default: function () {
return {
message: 'hello'
}
}
},

2.這兩種寫法相同喔!都是對型別不做任何驗證

1
2
3
4
props:['parentMsg']
props:{
parentMsg:null
}

小結論

型別驗證有助於我們在開發時候,提前了解哪邊資料錯誤。但實際上,即使資料傳入資料型別錯誤,畫面依舊會將傳入資料顯示在畫面上喔!


單向資料流

說明:
我們知道,Vue在傳遞資料時,是透過Props將資料由外部往內傳遞,而且所有的 props 都使得其父子 props 之間形成了一個單向下行綁定:父級prop 的更新會向下流動到子組件中,但是反過來則不行。

後記:仔細想想也蠻有道理,假設我們可以從子層更動父層實體內容,如此一來父層實體內容便會無法管理(或是說資料會不知道被誰更動過!)

錯誤範例示範

連結
HTML部分

1
2
3
4
5
6
<div id="app">
<p>
Child:
<my-component :parent-message="message"></my-component>
</p>
</div>

JavaScript部分

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Vue.component('my-component', {
template: `<span>
<input v-model="parentMessage"> 資料來源:父元素
</span>`,
props: {
parentMessage: String
},
});

new Vue({
el: '#app',
data: {
message: 'hello'
}
});

圖示

如果我們要修正錯誤,該如何解決呢?

  • 只要新宣告一個參數來接受外部修改資料就好~寫法如下
  • 或是在元件中使用computedgetset
  • 這兩種寫法目的:都是讓資料獨立存在於子層而非父層
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Vue.component('photo', {
    props: ['imgUrl'],
    template: '#photo',
    data: function () {
    return {
    newUrl: this.imgUrl
    }
    }
    })

    當V-model遇到props

    codepen示範
    範例如下:

    透過上方圖片講解,重點在於第四點,在component底下的data資料是無法改變上層父元素內容!也就是下方圖片中更改4號無法更改1、2、3的資料