勉強履歴(と雑記)

プログラミング初心者のメモ書きです

Vue.js学習メモ(コンポーネントの分割)

Vue.jsとrailsでタスク管理アプリを作りながら勉強してます。 今回はタスクを3つ(TODO、DOING、DONE)に分けて、 なおかつタスクの一覧(TaskList)とタスク単体(TaskItem)を別のコンポーネントに分割していきたいと思います。 コンポーネント間の関係:index(親)→TaskList(子)→TaskItem(孫)

 変更前

index.vue

<div class="h4">TODO</div>
  <div
    v-for="task in tasks"
    :key="task.id"
    :id="'task-' + task.id"
    class="bg-white border shadow-sm rounded my-2 p-4 d-flex align-items-center"
    @click="handleShowTaskDetailModal(task)"
  >
    <span>{{ task.title }}</span>
</div>

 変更後

index.vue(TODOのみ)

<TaskList
  :tasks="todoTasks"  
  // v-bindでTaskListにtasksプロパティを与える。todoTasksはcomputedで定義。
  taskListId="todo-list"
  @handleShowTaskDetailModal="handleShowTaskDetailModal"
>
  <template v-slot:header>  
   // slotでは親で差し替えたい部分の表記を書く
    <div class="h4">TODO</div> 
  </template>
</TaskList>

 computed: {
   todoTasks() {
     return this.tasks.filter(task => {
       return task.status == "todo"
     })
  },
}

TaskList.vue

<div :id="taskListId" class="bg-light rounded shadow m-3 p-3">
  <slot name="header">タスク区分</slot>  
  //子では<slot></slot>と書くだけ
  <template v-for="task in tasks">  
  //v-forでtasks内のtaskを表示していく
    <TaskItem :key="task.id" :task="task" @handleShowTaskDetailModal="$listeners['handleShowTaskDetailModal']" /> 
    // taskItemにtaskプロパティを渡す
    // $listenersで全てのtaskItem(孫)からのデータを受け取り、index(親)に渡す(Vue3では$attrsに統合)
  </template>
</div>

TaskItem.vue

<div
  :id="'task-' + task.id"
  class="bg-white border shadow-sm rounded my-2 p-4 d-flex align-items-center"
  @click="handleShowTaskDetailModal(task)"
>
  <span>{{ task.title }}</span>
</div>

methods: {
  handleShowTaskDetailModal(task) {
    this.$emit('handleShowTaskDetailModal', task)
  }
}

今回はなかなかどう分割したらいいのかがわからず、上手いこと行きませんでした。 まだまだvueの理解が不十分ですね。勉強を継続していきたいと思います。

土日も書くと言っておきながら結局やってませんでした。 いきなり週3でブログ更新は荷が重かったのかもしれないので、最低でも週1にハードル下げてやっていきます。