第12屆鐵人賽Day 20 Rails專案開發 - 建立Vue元件: Ticket component

昨天的鐵人賽我們終於開始真正把手上在開發的系統變成,Vue.js x Rails專案了,可喜可賀!

今天,我想開給自己兩張票ticket,包括明後兩天要製作的ticket拖拉功能以及改寫vuex狀態管理

想像中的畫面大概會長醬子:

(一種開票給自己做的概念XD)

該如何設計Ticket元件呢?

首先:建立第4個Model: Ticket

  • 使用者註冊登入系統
  • 使用者可以建立很多Kanban
  • 看板Kanban可以有很多Column
  • 每個Column可以有很多張票Ticket

kanban.rb

每個kanban有很多columns, 根據dependent,如果刪掉了kanban,column也就一起刪掉

class Kanban < ApplicationRecord
  has_many :columns, dependent: :destroy
  belongs_to :user
  validates :name, presence: true
end

column.rb

每個column有很多ticket, 根據dependent,如果刪掉了column,ticket也就一起刪掉

class Column < ApplicationRecord
  has_many :tickets, dependent: :destroy
  belongs_to :kanban
  validates :name, presence: true  
end

ticket.rb

class Ticket < ApplicationRecord
  belongs_to :column
  validates :name, presence: true  
end

在rails console先建立幾筆ticket資料

c1.tickets.create(name: "ticket拖拉功能")
c1.tickets.create(name: "改寫vuex狀態管理data")

設計ticket元件

Step 1. 確定ticket元件的資料要從哪裡得到

jbuilder會幫我們把資料輸出為json格式。如果我們想把column下面的所有tickets也一起抓回來,可以_column.json.jbuilder這份檔案裡,後面再加上:tickets

json.extract! column, :id, :name, :kanban_id, :tickets

如此一來,/kanbans/2/columns.json的路徑下的json檔資料變成如下:

[
  {
    "id": 1,
    "name": "Backlog",
    "kanban_id": 2,
    "tickets": [
      {
        "id": 1,
        "name": "ticket拖拉功能",
        "column_id": 1,
        "position": 1
      },
      {
        "id": 2,
        "name": "改寫成vuex 管理狀態",
        "column_id": 1,
        "position": 2
      }
    ]
  },
  {
    "id": 2,
    "name": "Sprint Backlog",
    "kanban_id": 2,
    "tickets": [
      
    ]
  },
  //略
]

Step 2. Vue app的掛載點,改寫:

我們要在column元件裡面再包含ticket元件,因此掛載點的template會需要使用到<Ticket></Ticket>,並透過v-for把column裡面的tickets用迴圈轉出來

:ticket="ticket的意思是 是v-for迴圈的每個ticket值,透過:ticket傳給子元件

最後,別忘了 引入import Ticket from "components/kanban/ticket" 並註冊子元件components: { Ticket }

<template>
  <div class="column">
    <div class="column-name"></div>
    <div class="ticket-list">
      <Ticket v-for="ticket in column.tickets" :ticket="ticket" :key="ticket.id"></Ticket>
    </div>
  </div>
</template>

<script>
  // 讓用元件的父層,餵資料給子元件
  import Ticket from "components/kanban/ticket"  
  export default {              
    name: 'Column',
    props: ["column"],
    components: { Ticket }
  }
</script>

<style lang="scss" scoped>
<!-- 略 -->
</style>

Step 3. 設計ticket元件

與父元件相比,子元件相對單純的多,透過props拿到父元件傳進來的值,即可透過鬍子語法把票印出來。

<template>
  <div class="ticket">
    
  </div>
</template>

<script>
  export default {              
    name: 'Ticket',
    props: ["ticket"]
  }
</script>

<style lang="scss" scoped>
  .ticket {
    @apply .bg-yellow-100 .mb-2 .rounded-md .px-2 .py-2 .font-thin .text-sm .shadow-lg;
  }
</style>

Vuedevtool所示,ticket component順利掛在column component下囉!

明天來做拖拉功能!

最後,以一句我很喜歡的話送給大家~共勉之:)

Mapping our work allows us to navigate our life.
將工作視覺化在看板上,使我們能夠駕馭生活 - Jim Banson