iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 1
3
Modern Web

從比入門再往前一點開始,一直到深入React.js系列 第 1

【Day.01】為什麼需要框架 - 從全部塞在一起開始頭痛

(2024/04/06更新) 因應React在18後更新了許多不同的語法,更新後的教學之後將陸續放在 新的blog 中,歡迎讀者到該處閱讀,我依然會回覆這邊的提問


這個系列和我在11屆鐵人賽的React.js系列文,已經在修訂後和深智數位合作出版成實體書,在天瓏開始預購了,想學React的朋友可以參考看看:
https://www.tenlong.com.tw/products/9789860776188?list_name=srh

前言

近年在學習前端技能時,三大框架是尋找工作不可或缺的技能。也因為這樣,學習框架的動機就不再一定是為了「專案需求」,而是「跟著職缺走」。

本系列一開始將用原生Javascript實現「元件化」的過程,先帶領讀者理解為什麼需要框架。再進入近年流行的React hook世界。以故事化的方式,從發現問題的過程,學習目前業界開發React.js專案一定會用到的工具。

系列開始

你是一位剛進入前端領域的新手,學習了HTML、CSS、Javascript後,有一天你收到了一份UI稿,它長這個樣子:

雖然這可以用html+css刻死在網頁上,但因為你想練習JS基礎的前端api,所以你決定要完全用Javascript來完成這份介面。

從完全以Javascript自製一個Menu

研究官方文件一段時間後,你終於想出如何用document.函式創造出所有的東西(也就是DOM api)。

  • index.html
<!DOCTYPE html>
<html lg="zh-tw">
    <head>
        <meta charset="utf-8"/>
        <title>12屆鐵人賽</title>
        <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
        <link rel=stylesheet type="text/css" href="./css/index.css">
    </head>
    <body>
        <div id="root">
        </div>
    </body>
    <script src="./js/index.js" type="text/javascript"></script>
</html>
  • js/index.js
// 文字
let menuItemWording=[
    "Like的發問",
    "Like的回答",
    "Like的文章",
    "Like的留言"
];

//外層container
let menuContainer = document.createElement('div');
menuContainer.setAttribute('class',"menu-container");

//藍色標題
let title = document.createElement('p')
title.setAttribute('class',"menu-title")
title.textContent="Andy Chang的Like";
menuContainer.appendChild(title);

//列表的container
let menu = document.createElement('ul');
menu.setAttribute('class',"menu")

//列表
menuItemWording.forEach((item)=>{
    let menuItem = document.createElement('li');
    menuItem.setAttribute('class',"menu-item");
    menuItem.textContent = item;
    menu.appendChild(menuItem);
});

//控制「列表的container」開關的按鈕
let menuBtn = document.createElement('button');
let isOpen = false;
menuBtn.setAttribute('class',"menu-btn");
menuBtn.textContent="V";
menuBtn.onclick = function() {
    // 「!」會把true變false,false變true
    isOpen = !isOpen;

    if(isOpen){
        menu.style.display = "block";
        menuBtn.textContent="^";
    }
    else{
        menu.style.display = "none";
        menuBtn.textContent="V";
    }  
}

menuContainer.appendChild(menuBtn);
menuContainer.appendChild(menu);

document.getElementById('root').appendChild(menuContainer);
  • css/index.css
.menu-container{
    position: relative;
    width: 300px;
    padding: 14px;
    font-family: "Microsoft JhengHei";
    padding-bottom: 7px;
    background-color: white;
    border: 1px solid #E5E5E5;
    transition: height 0s;
}

.menu-title{
    margin-bottom: 7px;
    font-weight: bold;
    color: #00a0e9;
    cursor: pointer;
}

.menu-btn{
    position: absolute;
    right: 7px;
    top: 33px;
    background-color: transparent;
    border:none;
    color: #00a0e9;
    outline: none;
}

.menu{
    display: none;
}

.menu-item{
    margin-bottom: 7px;
    padding-left: 26px;
    list-style: none;
}


恩,雖然不完全一樣,但看起來還行啦

然後你就被同事罵了

原因是這份程式碼:

  • 所有的code都塞在同一個JS檔案裡,很髒
  • 每個地方都刻死在對應的位置,當別的地方想共用這裡的程式碼的時候,hen不方便
  • 很難一眼看出來架構,修改不易
  • 同事只是不爽你

怎麼辦?

在接下來的這幾天中,我們將會利用Javascript本身的特性,加上少許Design Pattern的概念,試著讓這份程式碼更乾淨,同時學習前端工程中最重要的「元件化」的概念,最後再來把它轉成React。


下一篇
【Day.02】為什麼需要框架 - 用工廠模式,開始重新思考共用架構
系列文
從比入門再往前一點開始,一直到深入React.js30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言