iT邦幫忙

2022 iThome 鐵人賽

DAY 14
0
Modern Web

淺入淺出 Rails with Vue系列 第 14

【Day 14】淺入淺出 Rails with Vue - Vue 的基本概念 - 13

  • 分享至 

  • xImage
  •  

前言

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

v-for with a Component

在上一篇文章中,我們介紹了 v-for 的用法,並且使用了 v-for 來產生一個 list。但是,如果我們想要使用 v-for 來產生一個 list,並且這個 list 中的每一個 item 都是一個 component,該怎麼做呢?
你可以直接使用 v-for在 component 上,如下面的範例中所示:

<my-component v-for="item in items" :key="item.id"></my-component>

這邊的 key 是必要的,因為 Vue 會使用 key 來判斷是否要重新渲染,如果沒有 key,Vue 會使用預設的 index 來判斷,這樣會造成效能上的問題。

但是這樣做會有一個問題,就是你無法傳遞 itemmy-component 中,因為每個 my-component 都是 isolated 的 component,所以你無法傳遞 itemmy-component 中,這樣的話,你就無法在 my-component 中使用 item
為了解決這樣的問題,我們必須使用 props 來傳遞 itemmy-component 中,如下面的範例所示:

<my-component
  v-for="(item, index) in items"
  v-bind:item="item"
  v-bind:index="index"
  v-bind:key="item.id"
></my-component>

v-for 中無法自動傳遞 item 到 component 的原因是不想讓 component tight coupling 到 v-for,所以你必須自己透過 prop 明確的傳遞 item 到 component 中。

<div id="todo-list-example">
  <form v-on:submit.prevent="addNewTodo">
    <label for="new-todo">Add a todo</label>
    <input
      v-model="newTodoText"
      id="new-todo"
      placeholder="E.g. Feed the cat"
    >
    <button>Add</button>
  </form>
  <ul>
    <li
      is="todo-item"
      v-for="(todo, index) in todos"
      v-bind:key="todo.id"
      v-bind:title="todo.title"
      v-on:remove="todos.splice(index, 1)"
    ></li>
  </ul>
</div>
Vue.component('todo-item', {
  template: '\
    <li>\
      {{ title }}\
      <button v-on:click="$emit(\'remove\')">Remove</button>\
    </li>\
  ',
  props: ['title']
})

new Vue({
  el: '#todo-list-example',
  data: {
    newTodoText: '',
    todos: [
      {
        id: 1,
        title: 'Do the dishes',
      },
      {
        id: 2,
        title: 'Take out the trash',
      },
      {
        id: 3,
        title: 'Mow the lawn'
      }
    ],
    nextTodoId: 4
  },
  methods: {
    addNewTodo: function () {
      this.todos.push({
        id: this.nextTodoId++,
        title: this.newTodoText
      })
      this.newTodoText = ''
    }
  }
})

在上面的範例中,我們使用了 is attribute 來指定 todo-item component,並且使用 v-for 來產生一個 list,使用 v-bind 來傳遞 titletodo-item component 中,並且使用 v-on 來監聽 remove 事件,並且在 remove 事件中,使用 splice 來移除 todo
這樣的話,我們就可以在 todo-item component 中使用 title 了。

特別注意的是 is attribute,這個 attribute 是用來指定 component 的。

Event Handling

Listening to Events

在 Vue 中,你可以使用 v-on 來監聽事件,如下面的範例中,我們使用 v-on 來監聽 click 事件,並且在 click 事件中,將 counter 加 1 並即時渲染到畫面上。

<div id="example-1">
  <button v-on:click="counter += 1">Add 1</button>
  <p>The button above has been clicked {{ counter }} times.</p>
</div>
var example1 = new Vue({
  el: '#example-1',
  data: {
    counter: 0
  }
})

Reference


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

尚未有邦友留言

立即登入留言