本系列將介紹 Rails with Vue 的基本概念,並且以一個簡單的專案 Todo 來說明如何使用 Rails with Vue。我將透過這一系列的文章記錄我學習的過程,並且將我所學到的知識分享給大家。
- 【Day 01】淺入淺出 Rails with Vue - Before We Begin
- 【Day 02】淺入淺出 Rails with Vue - Vue 的基本概念 - 1
- 【Day 03】淺入淺出 Rails with Vue - Vue 的基本概念 - 2
- 【Day 04】淺入淺出 Rails with Vue - Vue 的基本概念 - 3
- 【Day 05】淺入淺出 Rails with Vue - Vue 的基本概念 - 4
- 【Day 06】淺入淺出 Rails with Vue - Vue 的基本概念 - 5
- 【Day 07】淺入淺出 Rails with Vue - Vue 的基本概念 - 6
- 【Day 08】淺入淺出 Rails with Vue - Vue 的基本概念 - 7
- 【Day 09】淺入淺出 Rails with Vue - Vue 的基本概念 - 8
- 【Day 10】淺入淺出 Rails with Vue - Vue 的基本概念 - 9
- 【Day 11】淺入淺出 Rails with Vue - Vue 的基本概念 - 10
- 【Day 12】淺入淺出 Rails with Vue - Vue 的基本概念 - 11
- 【Day 13】淺入淺出 Rails with Vue - Vue 的基本概念 - 12
- 【Day 14】淺入淺出 Rails with Vue - Vue 的基本概念 - 13
- 【Day 15】淺入淺出 Rails with Vue - Vue 的基本概念 - 14
- 【Day 16】淺入淺出 Rails with Vue - Vue 的基本概念 - 15
- 【Day 17】淺入淺出 Rails with Vue - Vue 的基本概念 - 16
- 【Day 18】淺入淺出 Rails with Vue - Vue 的基本概念 - 17
- 【Day 19】淺入淺出 Rails with Vue - Vue 的基本概念 - 18
- 【Day 20】淺入淺出 Rails with Vue - Vue 的基本概念 - 19
- 【Day 21】淺入淺出 Rails with Vue - Vue 的基本概念 - 20
- 【Day 22】淺入淺出 Rails with Vue - Vue 的基本概念 - 21
- 【Day 23】淺入淺出 Rails with Vue - Vue 的基本概念 - 22
- 【Day 24】淺入淺出 Rails with Vue - Vue 的基本概念 - 23
- 【Day 25】淺入淺出 Rails with Vue - Vue 的基本概念 - 24
- 【Day 26】淺入淺出 Rails with Vue - Vue 的基本概念 - 25
在 Vue 中,盡量保持資料是單向流動 (one-way-down binding) 的,也就是說,父元件傳遞給子元件的資料,子元件無法直接修改,只能透過事件傳遞給父元件,由父元件修改資料,再傳遞給子元件。
這麼做的好處是可以避免 child component 修改 parent component 的資料,造成資料的不一致性。
除此之外,當 parent component 的資料改變時,也可以透過 props 傳遞給 child component,讓 child component 重新渲染。
以下舉例兩種比較常見可能會在 child component 中修改 props 的情況:
類似這樣的 use case,可以透過在 child component 中宣告一個 data,並將 props 傳入的值指定給這個 data,這樣就可以在 child component 中修改這個 data,而不會影響到 props 傳入的值。
如以下例子中,我們在 child component 中宣告一個 counter
,並將 initialCounter
傳入的值指定給 counter
,這樣就可以在 child component 中修改 counter
,而不會影響到 initialCounter
傳入的值。
props: ['initialCounter'],
data: function () {
return {
counter: this.initialCounter
}
}
類似這樣的 use case,可以透過在 child component 中宣告一個 computed,並將 props 傳入的值指定給這個 computed,這樣就可以在 child component 中修改這個 computed,而不會影響到 props 傳入的值。
如以下例子中,我們在 child component 中宣告一個 normalizedSize
computed property,並在這個 computed property 中將 size
傳入的值指定給 normalizedSize
function 運算,這樣就可以在 child component 中修改 normalizedSize
,而不會影響到 size
傳入的值。
props: ['size'],
computed: {
normalizedSize: function () {
return this.size.trim().toLowerCase()
}
}
需特別注意的是假如你在 child component 中修改了 props 傳入的值,並且這個值是一個 object 或 array,那麼你修改的值也會影響到 props 傳入的值
在 Vue 中,我們可以針對傳入的 props 進行驗證,這樣可以避免傳入錯誤的 props,並且可以在開發階段就發現錯誤。
例如在前先章節使用的 type
屬性,就是用來驗證傳入的 props 的型別,
除此之外,Vue 還提供了許多其他的驗證方式,例如 required
、default
、validator
等等,
要在 props 中使用這些驗證方式,我們必須使用 props
object 的方式來宣告 props,如以下範例:
Vue.component('my-component', {
props: {
// Basic type check (`null` and `undefined` values will pass any type validation)
propA: Number,
// Multiple possible types
propB: [String, Number],
// Required string
propC: {
type: String,
required: true
},
// Number with a default value
propD: {
type: Number,
default: 100
},
// Object with a default value
propE: {
type: Object,
// Object or array defaults must be returned from
// a factory function
default: function () {
return { message: 'hello' }
}
},
// Custom validator function
propF: {
validator: function (value) {
// The value must match one of these strings
return ['success', 'warning', 'danger'].includes(value)
}
}
}
})
當驗證失敗後,若為開發階段,Vue 會在 Browser 的 Console 中發出警告,但在 production 時會忽略這些警告。
需特別注意的是,Prop Validation 是在 component 初始化
前
進行驗證,所以像是data
或computed
中的值,是無法在驗證中使用的。
在 Vue 中,props 的 type
可為以下幾種型別:
除此之外,type
也可以是一個自訂的 constructor,例如:
function Person (firstName, lastName) {
this.firstName = firstName
this.lastName = lastName
}
Vue.component('blog-post', {
props: {
author: Person
}
})
需特別注意的是,當使用自訂的 constructor 作為
type
時,Vue 會使用instanceof
來驗證傳入的 props 是否為該 constructor 的實例,所以如果你使用Object.create(null)
來建立一個空的 object,那麼這個 object 就不會通過驗證。
如同字面上的意思,所謂的 Non-Prop Attributes
就是指在 component 中的 props 沒有宣告的 attributes,
理論上明確的定義我們的 props 是 best practice,但有時侯我們不能確定 component 會被使用在哪裡,
所以我們可能會需要一些 Non-Prop Attributes
來讓 component 有更多的彈性,
這些 Non-Prop Attributes
會被加到 component 的 root element 上,例如:
<bootstrap-date-input data-date-picker="activated"></bootstrap-date-input>
在以上的範例中,data-date-picker
這個 attribute 並沒有在 component 中的 props
宣告,所以它是一個 Non-Prop Attributes
,
並且這個 props 會被自動的加到 component 的 root element 上,也就是 <bootstrap-date-input>
。