iT邦幫忙

2022 iThome 鐵人賽

DAY 28
0
Modern Web

淺入淺出 Rails with Vue系列 第 28

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

  • 分享至 

  • xImage
  •  

前言

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

Props

Non-Prop Attributes

Replacing/Merging with Existing Attributes

接續上一篇文章的 bootstrap-date-input component,假設這個 component 的 template 屬性如下

<input type="date" class="form-control">

假設我們現在想要改變 date picker plugin 的 theme,我們或許會想要傳入指定的 class style,
如下面例子中的 date-picker-theme-dark class

<bootstrap-date-input
  data-date-picker="activated"
  class="date-picker-theme-dark"
></bootstrap-date-input>

在這個範例中,共會有兩種不同的 classes 被定義:

  • form-control:這個 class 是由 component 的 template 定義的
  • date-picker-theme-dark:這個 class 是由 parent 透過 props 傳入的

對於大部分的 attributes,component 會將 parent 傳入的 attributes 取代原本的 attributes,
例如如果我們在 parent 中傳入 type="text" 時,component 的 type 屬性會被取代為 text 如下:
這樣的直接取代有可能會造成 component break,

<input type="text" class="form-control">

但是對於 class 這種 attribute,Vue 會將 parent 傳入的 class 和 component 的 class 進行合併,
例如在上面的範例中,component 的 class 屬性會變成 form-control date-picker-theme-dark

Disabling Attribute Inheritance

如果我們不想要讓 parent 的 attributes 進行取代或合併,我們可以在 component 中使用 inheritAttrs: false
這樣的話,parent 傳入的 attributes 就不會被傳入 component 中,例如:

Vue.component('my-component', {
  inheritAttrs: false,
  // ...
})

我們可以在 component 中使用 $attrs instance property 來取得 parent 傳入的 attributes,
這個 property 會回傳一個 object,其中包含了所有的 attributes,例如:

{
  required: true,
  placeholder: 'Enter your username'
}

有了 inheritAttrs: false$attrs,我們就可以自行決定要如何處理 parent 傳入的 attributes,

Vue.component('base-input', {
  inheritAttrs: false,
  props: ['label', 'value'],
  template: `
    <label>
      {{ label }}
      <input
        v-bind="$attrs"
        v-bind:value="value"
        v-on:input="$emit('input', $event.target.value)"
      >
    </label>
  `
})

需特別注意的是,$attrs 並不包含 classstyle,因為這兩個屬性是會被合併的

透過 inheritAttrs: false$attrs 這兩個屬性,可以讓 component 使用的更像 raw HTML element,
例如在上面的範例中,我們可以這樣使用 base-input component

<base-input
  label="Username:"
  v-model="username"
  required
  placeholder="Enter your username"
></base-input>

Custom Events

Event Names

在 Vue 中,event name 不像 component 和 props 的 name,even name 不會自動轉換,
當我們在 component 中使用 $emit 時,必須和定義的 event name 完全符合
舉例來說,當我們 emit 一個 camelCased 格式的 event name 時如下:

this.$emit('myEvent')

當我們在 DOM 中使用 my-event 監聽這個 event 時,將會無法監聽到,

<!-- Won't work -->
<my-component v-on:my-event="doSomething"></my-component>

不像 component 和 props,event 不會當作 variable 或 property name 來使用,
所以我們不需要使用 camelCase 或 PascalCase,
除此之外,在 DOM 的 event listener 中,由於 HTML’s case-insensitivity 特性,
當我們使用 v-on:myEvent 時,也會監聽到 v-on:myevent

所以對於 event name,我們推薦使用 kebab-case 格式來命名 event name

Reference


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

尚未有邦友留言

立即登入留言