iT邦幫忙

2025 iThome 鐵人賽

DAY 19
0
Vue.js

從零開始的Vue之旅系列 第 19

vue小專案-計畫進度追蹤part2

  • 分享至 

  • xImage
  •  

好的今天繼續用長期專案進度追縱的部分
先來處理進度條的功能
進度條會依據子任務總數和完成的子任務數呈現整個專案的進度
先在<script setup>寫好功能

// === 計算專案進度 ===
function projectProgress(project) {
  if (project.subtasks.length === 0) return 0
  const doneCount = project.subtasks.filter(s => s.done).length
  return Math.round((doneCount / project.subtasks.length) * 100)
}

if (project.subtasks.length === 0) return 0 如果沒有子任務,直接回傳0

const doneCount = project.subtasks.filter(s => s.done).length 計算已完成的子任務數量
.filter建立一個新陣列,飽含所有符合條件的元素
而條件就是(s=>s.done) s.done就是 done: true 的子任務

return Math.round((doneCount / project.subtasks.length) * 100) 計算並回傳完成度的百分比
百分比=(完成數/子任務總數)*100

然後到<template>加入進度條將進度可視化

  <!-- 進度條 -->
      <div class="progress-bar">
        <div
          class="progress"
          :style="{ width: projectProgress(project) + '%' }"
        ></div>
      </div>
      <p>{{ projectProgress(project) }}%</p>

<div class="progress-bar">先設定好一個空的進度條
<div class="progress" :style="{ width: projectProgress(project) + '%' }"></div>
這是主要顯示進度的部分,就是要將空的進度條填滿多少
:style="{ width: projectProgress(project) + '%' projectProgress(project)會回傳整數百分比,後面加%再套到CSS的width屬性,進度條就會根據任務完成的動態比例改變width

<style scoped>設置樣式

/* 進度條 */
.progress-bar {
  width: 100%;
  background: #ddd;
  border-radius: 8px;
  height: 16px;
  margin: 6px 0;
  overflow: hidden;
}
.progress {
  height: 100%;
  background: #2ecc71;
  transition: width 0.3s ease;
}

最終畫面呈現
https://ithelp.ithome.com.tw/upload/images/20251001/201786903QoQvQREqz.png
那假如我們需要刪除專案或子任務,就再添加兩項函式
一樣在<script setup>先寫好函式

// === 刪除專案 ===
function deleteProject(pIndex) {
  projects.value.splice(pIndex, 1)
}

.splice(pIndex, 1)可以看成.splice(從第幾個元素開始,拿掉幾個元素)
表示從第pIndex開始,拿掉1個元件

// === 刪除子任務 ===
function deleteSubtask(pIndex, sIndex) {
  projects.value[pIndex].subtasks.splice(sIndex, 1)
}

projects.value[pIndex].subtasks.splice(sIndex, 1)
從指定的pIndex專案中,從第sIndex開始,拿掉1個元件

<template>添加刪除功能

 <!-- 專案清單 -->
    <div v-for="(project, pIndex) in projects" :key="pIndex" class="project-box">
      <h3>{{ project.title }}  
        <!-- 刪除專案按鈕 -->
        <button  class="deletProjectButton"  @click="deleteProject(pIndex)">❌ 刪除專案</button>
      </h3>
<!-- 子任務清單 -->
      <ul class="task-list">
        <li
          v-for="(subtask, sIndex) in project.subtasks"
          :key="sIndex"
          :class="{ done: subtask.done }"
        >
          <span @click="toggleSubtask(pIndex, sIndex)">  
            <input
              type="checkbox"
              v-model="subtask.done"
          />{{ subtask.text }}</span>
           <!-- 刪除子任務按鈕 -->
          <button class="deletSubtaskButton" @click="deleteSubtask(pIndex, sIndex)">🗑 刪除</button>

寫好按鈕樣式

/*刪除按鈕*/
.deletProjectButton {
  padding: 8px;
  border: none;
  background-color: rgb(101, 119, 146);
  border-radius: 6px;
  cursor: pointer;
  margin-left: 15px;
}
.deletProjectButton:hover{
  background-color: rgb(54, 70, 94);
}
.deletSubtaskButton{
  margin-left: 6px;
  padding: 8px;
  border: none;
  background-color: #408281;
  color: white;
  border-radius: 6px;
  cursor: pointer;
}
.deletSubtaskButton:hover{
   background-color: #1b4746;
}

好的今天先寫好大致的功能和排版
https://ithelp.ithome.com.tw/upload/images/20251001/20178690gIFmlMDSuS.png

我覺得有必要調整一下色調了,目前的配色太隨便我實在不滿意
明天繼續完善
各位明天見~


上一篇
vue小專案-專案進度追蹤part1
系列文
從零開始的Vue之旅19
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言