iT邦幫忙

2022 iThome 鐵人賽

DAY 27
0
Modern Web

淺入淺出 Rails with Vue系列 第 27

【Day 27】淺入淺出 Rails with Vue - Vue 的基本概念 - 26

  • 分享至 

  • xImage
  •  

前言

本系列將介紹 Rails with Vue 的基本概念,並且以一個簡單的專案 Todo 來說明如何使用 Rails with Vue。我將透過這一系列的文章記錄我學習的過程,並且將我所學到的知識分享給大家。

Props

One-Way Data Flow

在 Vue 中,盡量保持資料是單向流動 (one-way-down binding) 的,也就是說,父元件傳遞給子元件的資料,子元件無法直接修改,只能透過事件傳遞給父元件,由父元件修改資料,再傳遞給子元件。
這麼做的好處是可以避免 child component 修改 parent component 的資料,造成資料的不一致性。
除此之外,當 parent component 的資料改變時,也可以透過 props 傳遞給 child component,讓 child component 重新渲染。
以下舉例兩種比較常見可能會在 child component 中修改 props 的情況:

  1. 傳入的 props 用來當作一個 initial value,但是 child component 需要修改這個值

類似這樣的 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
  }
}
  1. 傳入的 props 是一個 raw value,但是 child component 需要修改這個值

類似這樣的 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 傳入的值

Prop Validation

在 Vue 中,我們可以針對傳入的 props 進行驗證,這樣可以避免傳入錯誤的 props,並且可以在開發階段就發現錯誤。
例如在前先章節使用的 type 屬性,就是用來驗證傳入的 props 的型別,
除此之外,Vue 還提供了許多其他的驗證方式,例如 requireddefaultvalidator 等等,
要在 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 初始化 進行驗證,所以像是 datacomputed 中的值,是無法在驗證中使用的。

Type Checks

在 Vue 中,props 的 type 可為以下幾種型別:

  • String
  • Number
  • Boolean
  • Array
  • Object
  • Date
  • Function
  • Symbol

除此之外,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

如同字面上的意思,所謂的 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>

Reference


上一篇
【Day 26】淺入淺出 Rails with Vue - Vue 的基本概念 - 25
下一篇
【Day 28】淺入淺出 Rails with Vue - Vue 的基本概念 - 27
系列文
淺入淺出 Rails with Vue30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言