iT邦幫忙

2022 iThome 鐵人賽

DAY 10
0
自我挑戰組

新手前端與真實世界的開發 feat.React 與他的夥伴系列 第 10

Day-10 專案演練 - UI 建置(下) charkra UI & tailwind CSS

  • 分享至 

  • xImage
  •  

Day-10 專案演練 - UI 建置(下) charkra UI & tailwind CSS

承上一章節,分析過設計稿,清楚元件結構關係,就可以實際把它做出來看看,我會把每一頁的程式碼都做好給大家,相信想要學習的更深的人也會自己找到很棒的資源做學習,官方文件跟各路大神的文章也會很有幫助。

新增 pages 資料夾

在 src 中新增一個 pages 資料夾,這個資料夾內容的架構會與網站的架構息息相關,通常我會將它設計成跟網址能夠完全對應。

因為接下來要開始來切 TodoPage,在 pages 裡面新增一個 TodoPage.tsx :

import React from "react";
const TodoPage: React.FC = () => {
  return <>TodoPage</>;
};

export default TodoPage;

並且把它引入到 app.tsx :

import React from "react";
import TodoPage from "./pages/TodoPage";

function App() {
  return (
    <div className="App">
      <TodoPage />
    </div>
  );
}

export default App;

接著確認畫面是否出現 TodoPage 字樣,測試看看有沒有引入成功。

tailwind CSS 切版

要開始 tailwind CSS 切版,用傳統 css 切版的經驗是一定要有的,對很熟切版的人來講,連 RWD 都不用的這個畫面,真的是很簡單,熟的話可以跟我一樣直接開幹就行了。

用這個 cheat sheet 可以快速找到 tailwind 的 class 有哪些,很方便,推薦給大家。

  1. 撰寫外框

我習慣在頁面的最外層使用 <section> 標籤,包裹元素,之所以這麼做,是因為這樣的 HTML 架構 <section>會與<div>相鄰,我就能一目了然的區分兩個塊是屬於哪裡,在這裡我就先把外框呈現一下。

<section>
    <div className="flex justify-between items-center shadow px-[20px] py-[20px]">
    // 標題與導航列表內容
    </div>
    <div className="pt-[20px] max-w-[1280px] mx-auto my-0">
    // 新增待辦的工具區域
    <div>
    <div className="flex justify-between py-[20px] max-w-[1280px] mx-auto my-0">
    // 表格的分頁工具區域
    </div>
    ...
</section>

tip : max-w-[1280px] 對應 css 的 max-width: 1280px;mx-auto my-0 則對應到 margin:0 auto;。這樣就可以達到讓元素寬度不超過 1280px 的狀況下置中於頁面中間。

  1. 切版 header

header 的架構有兩個部分,左邊是 MyNote 文字,右邊是含兩個按鈕的導航列,使用flex justify-between items-center 來做到左右邊的排版,設定 padding 間距px-[20px] py-[20px],最後做個陰影上去shadow

<section>
  <div className="flex justify-between items-center shadow px-[20px] py-[20px]">
    // 第一部分: MyNote 文字區域
    <h1 className="text-[30px] font-medium">MyNote</h1>
    // 第二部分: 按鈕導航
    <div>
      <button className="px-[8px] py-[2px] border rounded mr-[8px]">
        Dashboard
      </button>
      <button className="px-[8px] py-[2px] border rounded">Todos</button>
    </div>
  </div>
  ...
</section>
  1. 加上新增待辦區塊
<section>
    ...
    <div className="pt-[20px] max-w-[1280px] mx-auto my-0">
    <div className="flex justify-end items-center">
        <svg
        width="32"
        height="32"
        viewBox="0 0 32 32"
        fill="none"
        xmlns="http://www.w3.org/2000/svg"
        >
        <rect width="32" height="32" rx="6" fill="#EDF2F7" />
        <path
            d="M23.7918 16.5416H17.5418V22.7916H15.4585V16.5416H9.2085V14.4583H15.4585V8.20831H17.5418V14.4583H23.7918V16.5416Z"
            fill="black"
        />
        </svg>
        <span className="ml-[8px]">新增待辦</span>
    </div>
    </div>
    ...
<section>

因為接下來會碰到 charkra UI,就一邊查看文件,一邊把要用的元件放上來吧。

使用 charkra UI

終於要來切跟表格有關的內容,先來引入需要的工具,再來把頁面組裝起來。

這邊使用到三個元件,TableNumber InputCheckbox,可以先進去認識一下。

私心覺得 Checkbox 真好看,以後想多用(欸)

  1. 引入必要的工具
// 表格
import {
  Table,
  Thead,
  Tbody,
  Tfoot,
  Tr,
  Th,
  Td,
  TableCaption,
  TableContainer,
} from "@chakra-ui/react";
// 數字 input
import {
  NumberInput,
  NumberInputField,
  NumberInputStepper,
  NumberIncrementStepper,
  NumberDecrementStepper,
} from "@chakra-ui/react";
// 選擇框 Checkbox
import { Checkbox, CheckboxGroup } from "@chakra-ui/react";
  1. 組裝表格工具區
<section>
  ...
  <div className="flex justify-between py-[20px] max-w-[1280px] mx-auto my-0">
    <div className="flex items-center">
      <span>Show rows per page</span>
      <NumberInput className="w-[80px] ml-[8px]" min={1} max={10} size="sm">
        <NumberInputField />
        <NumberInputStepper>
          <NumberIncrementStepper />
          <NumberDecrementStepper />
        </NumberInputStepper>
      </NumberInput>
    </div>
    <div className="flex items-center">
      <span>1-8 of 32</span>
      <div className="flex">
        <span>
          <svg
            width="32"
            height="32"
            viewBox="0 0 32 32"
            fill="none"
            xmlns="http://www.w3.org/2000/svg"
          >
            <g opacity="0.5">
              <path
                d="M15.2188 16L18.5188 19.3L17.5762 20.2427L13.3335 16L17.5762 11.7573L18.5188 12.7L15.2188 16Z"
                fill="#2D3748"
              />
            </g>
          </svg>
        </span>
        <span>
          <svg
            width="32"
            height="32"
            viewBox="0 0 32 32"
            fill="none"
            xmlns="http://www.w3.org/2000/svg"
          >
            <path
              d="M16.7814 16L13.4814 12.7L14.4241 11.7573L18.6668 16L14.4241 20.2427L13.4814 19.3L16.7814 16Z"
              fill="#2D3748"
            />
          </svg>
        </span>
      </div>
    </div>
  </div>
  ...
</section>
  1. 組裝表格區域
<section>
...
      <div className="max-w-[1280px] mx-auto my-0">
        <TableContainer className="m-2">
          <Table variant="striped">
            <Thead>
              <Tr>
                <Th>
                  <Checkbox />
                </Th>
                <Th>任務標題</Th>
                <Th>詳情</Th>
                <Th>操作</Th>
              </Tr>
            </Thead>
            <Tbody>
              <Tr>
                <Td>
                  <Checkbox />
                </Td>
                <Td>購物</Td>
                <Td>日用品</Td>
                <Td className="flex items-center">
                  <span>
                    <svg
                      width="20"
                      height="20"
                      viewBox="0 0 30 30"
                      fill="none"
                      xmlns="http://www.w3.org/2000/svg"
                    >
                      <path
                        d="M3.75 21.825V25.625C3.75 25.975 4.025 26.25 4.375 26.25H8.175C8.3375 26.25 8.5 26.1875 8.6125 26.0625L22.2625 12.425L17.575 7.73748L3.9375 21.375C3.8125 21.5 3.75 21.65 3.75 21.825V21.825ZM25.8875 8.79998C26.375 8.31248 26.375 7.52498 25.8875 7.03748L22.9625 4.11248C22.475 3.62498 21.6875 3.62498 21.2 4.11248L18.9125 6.39998L23.6 11.0875L25.8875 8.79998Z"
                        fill="black"
                      />
                    </svg>
                  </span>
                  <span>
                    <svg
                      width="25"
                      height="25"
                      viewBox="0 0 30 30"
                      fill="none"
                      xmlns="http://www.w3.org/2000/svg"
                    >
                      <path
                        d="M8.39946 24.6985C8.39946 26.0848 9.53373 27.2191 10.9201 27.2191H21.0024C22.3888 27.2191 23.523 26.0848 23.523 24.6985V9.57494H8.39946V24.6985ZM11.4998 15.7252L13.2768 13.9482L15.9612 16.62L18.6331 13.9482L20.4101 15.7252L17.7383 18.397L20.4101 21.0689L18.6331 22.8459L15.9612 20.174L13.2894 22.8459L11.5124 21.0689L14.1842 18.397L11.4998 15.7252ZM20.3723 5.79404L19.112 4.53374H12.8105L11.5502 5.79404H7.13916V8.31464H24.7833V5.79404H20.3723Z"
                        fill="black"
                      />
                    </svg>
                  </span>
                </Td>
              </Tr>
              <Tr>
                <Td>
                  <Checkbox />
                </Td>
                <Td>鐵人賽</Td>
                <Td>day-10</Td>
                <Td className="flex items-center">
                  <span>
                    <svg
                      width="20"
                      height="20"
                      viewBox="0 0 30 30"
                      fill="none"
                      xmlns="http://www.w3.org/2000/svg"
                    >
                      <path
                        d="M3.75 21.825V25.625C3.75 25.975 4.025 26.25 4.375 26.25H8.175C8.3375 26.25 8.5 26.1875 8.6125 26.0625L22.2625 12.425L17.575 7.73748L3.9375 21.375C3.8125 21.5 3.75 21.65 3.75 21.825V21.825ZM25.8875 8.79998C26.375 8.31248 26.375 7.52498 25.8875 7.03748L22.9625 4.11248C22.475 3.62498 21.6875 3.62498 21.2 4.11248L18.9125 6.39998L23.6 11.0875L25.8875 8.79998Z"
                        fill="black"
                      />
                    </svg>
                  </span>
                  <span>
                    <svg
                      width="25"
                      height="25"
                      viewBox="0 0 30 30"
                      fill="none"
                      xmlns="http://www.w3.org/2000/svg"
                    >
                      <path
                        d="M8.39946 24.6985C8.39946 26.0848 9.53373 27.2191 10.9201 27.2191H21.0024C22.3888 27.2191 23.523 26.0848 23.523 24.6985V9.57494H8.39946V24.6985ZM11.4998 15.7252L13.2768 13.9482L15.9612 16.62L18.6331 13.9482L20.4101 15.7252L17.7383 18.397L20.4101 21.0689L18.6331 22.8459L15.9612 20.174L13.2894 22.8459L11.5124 21.0689L14.1842 18.397L11.4998 15.7252ZM20.3723 5.79404L19.112 4.53374H12.8105L11.5502 5.79404H7.13916V8.31464H24.7833V5.79404H20.3723Z"
                        fill="black"
                      />
                    </svg>
                  </span>
                </Td>
              </Tr>
              <Tr>
                <Td>
                  <Checkbox />
                </Td>
                <Td>折棉被</Td>
                <Td></Td>
                <Td className="flex items-center">
                  <span className="cursor-pointer">
                    <svg
                      width="20"
                      height="20"
                      viewBox="0 0 30 30"
                      fill="none"
                      xmlns="http://www.w3.org/2000/svg"
                    >
                      <path
                        d="M3.75 21.825V25.625C3.75 25.975 4.025 26.25 4.375 26.25H8.175C8.3375 26.25 8.5 26.1875 8.6125 26.0625L22.2625 12.425L17.575 7.73748L3.9375 21.375C3.8125 21.5 3.75 21.65 3.75 21.825V21.825ZM25.8875 8.79998C26.375 8.31248 26.375 7.52498 25.8875 7.03748L22.9625 4.11248C22.475 3.62498 21.6875 3.62498 21.2 4.11248L18.9125 6.39998L23.6 11.0875L25.8875 8.79998Z"
                        fill="black"
                      />
                    </svg>
                  </span>
                  <span className="cursor-pointer">
                    <svg
                      width="25"
                      height="25"
                      viewBox="0 0 30 30"
                      fill="none"
                      xmlns="http://www.w3.org/2000/svg"
                    >
                      <path
                        d="M8.39946 24.6985C8.39946 26.0848 9.53373 27.2191 10.9201 27.2191H21.0024C22.3888 27.2191 23.523 26.0848 23.523 24.6985V9.57494H8.39946V24.6985ZM11.4998 15.7252L13.2768 13.9482L15.9612 16.62L18.6331 13.9482L20.4101 15.7252L17.7383 18.397L20.4101 21.0689L18.6331 22.8459L15.9612 20.174L13.2894 22.8459L11.5124 21.0689L14.1842 18.397L11.4998 15.7252ZM20.3723 5.79404L19.112 4.53374H12.8105L11.5502 5.79404H7.13916V8.31464H24.7833V5.79404H20.3723Z"
                        fill="black"
                      />
                    </svg>
                  </span>
                </Td>
              </Tr>
            </Tbody>
          </Table>
        </TableContainer>
...
</section>

repo

附上進度程式碼

結語

基本畫面出來之後,要做什麼事情都已經呈現在畫面上,感覺前方的景色變得清晰許多。

如果不太會切版的人用 tailwind 可能會有點辛苦,沒關係,切版這種事情就是如果沒有要求非得要用什麼工具,只要能夠呈現設計稿的畫面,功能做得出來,就可以了。

參考資料


上一篇
Day-9 專案演練 - UI 建置(上) charkra UI & tailwind CSS
下一篇
Day-11 專案演練 - 路由建置 react-router-dom
系列文
新手前端與真實世界的開發 feat.React 與他的夥伴30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言