超簡單學習 Vue.js 系列 | 點陣繪圖 Vue Pixel Darwer

2021-12-16

Vue.js 簡單的示範專案,使用 Vue CLI 搭配常用 Vue Directive,例如 v-if、v-bind 以及 v-on 等等,並使用 Bootstrap 5 作為 CSS Frameworks,搭配 Vue Component 的設計方式,實作各式應用。

logo

點陣繪圖 Vue Pixel Drawer

技術關鍵字 說明
v-for 用於迭代渲染各個繪圖點 (dot)
v-bind 用於綁定資料至 DOM Element 以程式化控制
v-on 用於綁定互動行為,例如著色繪圖點
Calculated Style Property 根據動態計算的方式決定 Element 屬性
Mounted 在元件初始化過程優先執行的內容
Methods 定義可以執行的方法函式

定義 Vue Compoenet 的 Template,用途為顯示所有的 Dot Elements 於 Body。

使用 v-for 的方式渲染,並搭配 v-bind 簡寫 :key 的方式綁定識別鍵。對於每個 Element 在綁定上 v-on Click 事件並使用簡寫的方式 @click

在 Element 的 Id 以及 Style Property 同樣使用了 v-bind,而在 style 中,顏色是配合使用者行為動態計算了,因此使用 Grave Key 符號搭配 ${...} 進行屬性值計算。

<template>
  <div v-for="dot in dots" :key="dot" class="box" @click="colorIt"
    :id="`dot-${dot.index}`"
    :style="{ 'width': `${dot.size}px`, 'height': `${dot.size}px`,
      'background-color': `rgb(${dot.cR},${dot.cG},${dot.cB})` }">
  </div>
</template>

另使用 HTML 5 Color Input Type 的方式,作為繪色選擇的挑選工具,由於 input 的 Value 色號必須雙向綁定在 currentColor 上,因此使用 v-model,同時將選擇的顏色 Hex 顯示於 Input 之下。

<input type="color" id="colorPicker" v-model="currentColor"><br><br>
<div> {{ currentColor }}</div>

在 Script 中 Data 的部分以函數方式表示,包含全部的繪圖點 (dot) 的 width & height size,並有一個 empty array dots 用來收納所有的 dot,此外還有 currentColor 表示目前 colorPicker 所選擇的顏色以及要用於著色點選所使用。

mounted 的部分,在 Component 的建立之初,新建 dot 物件,並加入於 dots array 之中,要注意的 JS 的 Array 加入 Element 有 push 以及 unshift 兩種方式,其中 push Append last,而 unshift 則是 insert first。

methods 定義了著色互動,當使用者點選 dot 會藉由 v-on:click="colorIt" 觸發 colorIt function,其中 event 參數會指向被點選 (click) 的 Element。

藉由取得 element 的 Id 從而可以在 dots 索引的方式找到 dot,並根據目前 currentColor 的值以 RGB 轉換後更新被點選 Element 的值,從而實現畫面上的 dot 發生顏色變化。

export default {
  name: 'App',
  data() {
    return {
      size: 30,
      dots:[],
      currentColor: '#ff0000'
    }
  },
  
  mounted() {
    for (let index = 0; index < 301; index++) {
      this.dots.push({index, size: this.size, cR: 221, cG: 221, cB: 221})
    }
  },

  methods: {
    colorIt(event) {
      let dotIndex = parseInt(event.target.id.replace('dot-', ''));
      this.dots[dotIndex].cR = parseInt(this.currentColor.substr(1,2), 16);
      this.dots[dotIndex].cG = parseInt(this.currentColor.substr(3,2), 16);
      this.dots[dotIndex].cB = parseInt(this.currentColor.substr(5,2), 16);
    }
  } // end of methods
}

在 Scoped CSS 部分僅做下列設置,控制 box 的顯示方式。

.box{
  border-radius: 15px;
  margin: 5px;
  display: inline-block;
  cursor: pointer;
}