0%

背景介紹

  • 高雄大學資管系,中央大學資管所,成績中間,程式能力一般。
  • 專案經驗是大學畢業專題,還有像是學校的一些課堂作業,沒有其他額外的 Side Project。
  • 多益成績 765。
  • 社團經驗登山社社長。
  • 實習經驗到一家做醫療資訊系統的新創公司實習,擔任網頁前後端開發。還有擔任系上的網管,也是負責網頁前後端開發。
  • 碩士論文主題是 COVID-19 假新聞辨識,研究使用機器學習和深度學習來進行自然語言處理。
  • 有在 Coursera 修過一些課程,並且拿到修課證書。
  • 有參加過 IT 鐵人競賽。
  • 有成立一個自己的技術部落格。
  • 沒有什麼特殊的校外比賽經驗。
    閱讀全文 »

題目原文



翻譯蒟蒻

  1. 題目給你兩個陣列 a 和 b 裡面包含一些數字
  2. 找出一個特定數字符合以下兩個條件
  3. 條件一,特定數字除上陣列 a 裡面的數字都要整除
  4. 條件二,陣列 b 裡面的所有數字除上特定數字都要整除
  5. 特定數字的區間剛好落在 a, b 陣列之間
  6. 算出符合這些條件的特定數字總共有幾個回傳
    閱讀全文 »

前言

Node.js 可以想像成是一種可以在後端運行的 JS 語言,因此對於如果原本就熟悉 JS 來做前端開發的人,算是一個進入後端門檻相對較親近的語言,因此本篇文章主要分享如何第一次使用 Node.js 就可以開啟一個自己的 API,包含基本資料庫的新增、修改、刪除、查看功能。廢話不多說,就讓我們看下去。

準備工作

安裝 Node.js

Node.js 官方網址

安裝 VSCode 套件

安裝 Thunder Client 來測試 API

安裝環境

本次練習採用 Node.js 裡面的 Express 框架,首先我們先透過 npm 來安裝 Express 框架。

1
npm install express-generator -g  

建立專案

使用 Express 框架建立自己的應用程式,資料夾名稱 myapp,並且將使用 EJS 當成 View 的模板。

1
express --view=ejs myapp

安裝套件

下載此專案所需套件。

1
npm  install

測試環境

使用以下指令來啟動我們 local 端的 server

1
npm start

進入網址 http://localhost:3000,如果看到以下畫面,代表成功在本地建好一個 Node.js 的Server

檔案結構介紹

  • bin:檔案 www 是 server 的設定。
  • node_modules:使用 npm install 後所安裝的套件。
  • public:裡面放置 images 、 js 與 css 檔案。
  • routes:裡面的檔案是路由的設定。
  • view:網頁頁面渲染呈現方式,裡面放 EJS 模板。
  • app.js:執行程式時的進入點。
  • package-lock.json:紀錄使用 npm install 後所安裝的套件資訊。
  • package.json:紀錄專案所需的套件資訊。

基本網路概念

如果我們前端瀏覽器要透過網路向 server 取資料,它需要發出一個要求 request ,當 server 收到請求後,會回應 response 我們的請求。而這一來一往之間也規定了一些方法。以下列舉比較常見的 http 方法:

  • GET:client 端想要獲得 server 端的資料。
  • POST:client 端想要新增資料到 server 端。
  • DELETE:client 端想要刪除 server 端的一筆資料。
  • PATCH:client 端想要修改 server 端的一筆資料。

程式實作

新增路由

在 routes 裡面新增檔案 api.js ,檔案內容可以先複製 user.js 並稍微修改如下:

1
2
3
4
5
6
var express = require('express');
var router = express.Router();
router.get('/', function(req, res, next) {
res.send('API');//修改裡面的文字成 API
});
module.exports = router;

修改 app.js 內容將 api.js 導入並使用。

1
2
3
4
5
6
7
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var apiRouter = require('./routes/api');// 新增這行來導入 api.js

app.use('/', indexRouter);
app.use('/users', usersRouter);
app.use('/api',apiRouter);//新增這行來使用 api.js,並且設定使用路徑為 /api

關閉 server 後重啟,並進入 http://localhost:3000/api ,看到畫面顯示文字 API 代表新增路由成功。

模擬後端資料

我們在 api.js 裡面新增變數 data 來模擬後端 DB 裡面的資料。

1
2
3
4
5
6
var data =[
{
id:1,
name: '手機'
}
]

POST 方法(新增)

修改 api.js ,我們使用 router.post(‘/路徑’,方法) 來新增 http 的 post 方法,路徑設定成 /products ,裡面的方法有兩個個參數 req 代表前端使用者的要求(request),res 代表後端伺服器的回應(response)。

我們使用變數 product 來接收前端的要求 req.body,然後我們將 product 與一個變數 id 包成一個物件,並且透過 push 將這個物件加入我們所模擬的後端資料 data 中 ,變數 id 的值我們使用 ****new Date().getTime() 來生成一個時間戳記代表編號,由於我們 product 到時候會是接收一個 json 物件格式,如果我們要直接取出物件裡面的變數來使用,可以透過 ES6 的解構語法 … product 來取出值。

當後端成功接收到前端要求的東西,後端可以使用 res.send() 裡面加入要回傳給前端的資料,這邊是加入我們模擬資料庫的變數 data,並且加入一個變數 success 來代表是否有成功回應,如果有就是 true。最後記得要再加上 res.end() 來代表後端回應的動作結束。改完後記得要重啟~

1
2
3
4
5
6
7
8
9
10
11
12
router.post('/products', function(req, res) {
var product = req.body // 用一個變數接收請求
data.push({
id:new Date().getTime(),
...product
});
res.send({
success:true,
data
});
res.end();
});

使用 Thunder Client 選擇 POST 來測試 API 是否正常,輸入網址 http://localhost:3000/api/products,req 帶入一個 json 物件裡面屬性 name 代表商品名稱。

GET 方法(查詢)

修改 api.js ,之前我們顯示 API 在畫面的那幾行程式,其實就是使用 router.get() 來實作 http 的 get 方法,路由路徑和 post 方法是一樣的,程式邏輯其實就是 psot 方法裡面,後端一樣使用 res.send() 來回應資料給前端,裡面包含模擬資料庫的 data ,還有代表是否成功回應的 success 。記得回應結束後要加上res.end(),改完後記得要重啟~

1
2
3
4
5
6
7
8
router.get('/products', function(req, res) {
res.send({
success:true,
data
});
res.end();
});

使用 Thunder Client 選擇 GET 來測試 API 是否正常,輸入網址 http://localhost:3000/api/products

DELETE (刪除)

修改 api.js ,使用 router.delete() 來實作 http 的 delete 方法,路由路徑要新增 :id ,透過變數 id 來儲存前端使用者輸入的數字,這個數字代表前端使用者想要刪除的產品代號。 接下來我們宣告一個變數 deleteId,它的值我們透過 req.params.id 來取得前端輸入傳給後端的 id 數字,然後我們對 data 進行 forEach() 方法,如果當 data 裡面的 id 和使用者想刪除的 deleteId 是一樣的話,使用 splice(想刪除的位置,刪除數量,刪除要在那個位置新增的東西)來刪除資料,splice(key,1) 參數設定代表從 id 和 deleteId 相同的那個 item 它的 key 位置開始刪除,刪除數量設定 1 ,沒有第三個參數代表沒有新增東西。最後 res 回應的邏輯就和上面相同。改完後記得要重啟~

1
2
3
4
5
6
7
8
9
10
11
12
13
router.delete('/products/:id', function(req, res) {
var deleteId = req.params.id
data.forEach((item,key) => {
if(item.id==deleteId){
data.splice(key,1)
}
});
res.send({
success:true,
data
});
res.end();
});

使用 Thunder Client 選擇 DELETE 來測試 API 是否正常,輸入網址 http://localhost:3000/api/products/1 ,裡面的 1 就代表想要刪除的產品 id。成功執行後就會發現回應中的 data 裡面 id 為 1 ,商品 name 為手機商品已經被刪除 。

PATCH(修改)

修改 api.js ,使用 router.patch() 來實作 http 的 patch 方法,路徑一樣是比照刪除的方法,id 用來接收前端使用者想要刪除的商品編號。其實修改的邏輯可以想成刪除 DELETE 原本的資料,再新增POST 新的資料。所以我們結合新增和刪除的邏輯,product 代表修改的商品名稱,id 就是想要修改的商品編號,之後我們透過 products[key].name=product.name 修改商品的值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
router.patch('/products/:id', function(req, res) {
var deleteId = req.params.id;
var product = req.body;
data.forEach((item,key) => {
if(item.id==deleteId ){
data[key].name=product.name;
}
});
res.send({
success:true,
data
});
res.end();
});

使用 Thunder Client 選擇 PATCH 來測試 API 是否正常,輸入網址 http://localhost:3000/api/products/1 ,裡面的 1 就代表想要修改產品名稱的產品 id。成功執行後就會發現回應中 data 裡面 id 為 1 ,商品 name 為手機的商品已經被改名成電腦。

webpack 運行邏輯


main.js 是主要的進入點(entry),webpack 會監控 main.js , 當main.js 有更動時 webpack 就自動編譯,編譯成 css,js 等遊覽器看得懂的語言。
由於 main.js 只是一個 js 檔案,無法看得懂 .vue 或者 .scss 檔,因此 webpack 有提供 loader 工具,來幫助 main.js 理解輸出這些檔案。

webpack 腳本檔案介紹

在 build 資料夾裡面有 webpack 腳本檔案,分別是:

  • webpack.base.conf.js
    • 主要核心
  • webpack.dev.conf.js
    • 給我們開發中預覽畫面用的
  • webpack.prod.conf.js

Vue Cli 介紹

  1. 基於 Webpack 所建置的開發工具
    • Webpack: 現在前端技術發展快速,多了很多 Preprocess (前處理器)工具與框架,像是Scss,Vue, 但是瀏覽器只看得懂(js,css,html),因此Webpack 就出現了,它幫我們編譯Preprocess 成瀏覽器得懂的內容然後打包成一包 dis 發布檔,直接讓後端上傳到 server。
      閱讀全文 »

display:block 區塊元素介紹

  • 特性
    • h1,ul,li,p
    • 占滿整個版面
    • 可設定寬高
    • 會另起一行來呈現
    • display: block
    • 可以包行內元素
    • div排版用區塊標籤
    • 範例

      display:inline 行內元素介紹

  • 特性
    • 不會換行
    • span排版用行內標籤
    • 不能設定寬高
    • 改成display: block(a標籤要讓人好點擊時)
    • 範例

我們也可以把解構方法用在物件裡面,把 family 的值傳到 Min ,並且用 Leo 的名稱來代替他,當我們使用 console 顯示 Leo 時,就會顯示小明。

1
2
3
4
5
6
7
let family = {
Min:'小明',
Mo:'媽媽'
}

let { Min:Leo} = family;
console.log(Leo);

如果我們的解構值後面只有一個值,那麼他會預設先給第一個值,小明就會被換成阿明,當我們console ming 時,他會顯示阿明。

1
2
let [ming = '小明',jay = '杰倫']=['阿明'];
console.log(ming,jay)

我們可以使用解構的方式,將右邊的值給映射到左邊,比如將 family 的值映射到變數 ming,father,mother 裡面。

1
2
3
let family = ['小明','爸爸','媽媽'];
let [ming,father,mother] = family
console.log(ming,father,mother)

我們也可以用這種方式來交換數值,而不用像先前一樣多宣告一個變數來交換值。

1
2
3
4
let mother = '媽媽';
let father = '爸爸';
[mother,father] = [father,mother];
console.log(mother,father);

我們也可以直接使用解構的方式,將 str 字串的值給取出來,映射到 a b c 變數中。

1
2
3
let str = '你好嗎';
let [a,b,c] = str;
console.log(a,b,c)

filter

當我們想要過濾陣列的資料,可以使用 filter 方法,它會return 條件相符合的陣列,比如我們設定 money 的條件 > 100 ,就可以篩選出兩個物件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
let people = [
{
name:'Leo',
money:200
},
{
name:'Peter',
money:200
}
];

let filterPeople = people.filter(function(item,index){
if(item.money>100){
return true
}
});
console.log(filterPeople)

find

和 filter 最大的差異在於,find 只回傳第一個符合條件的值,就此就算我們設定 money 的條件 > 100 ,也只會回傳第一個物件的值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
let people = [
{
name:'Leo',
money:200
},
{
name:'Peter',
money:200
}
];

let findPeople = people.find(function(item,index){
if(item.money>100){
return true
}
});
console.log(findPeople)

forEach

如果我們想存取陣列裡面每一個東西,通常會使用到 for 迴圈,如果我們今天想要讓程式更簡潔一些,可以使用 forEach 方法,他可以自動存取陣列裡面的值而不要設定初始值和條件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
let people = [
{
name:'Leo',
money:100
},
{
name:'Peter',
money:200
}
];

people.forEach(function(item,index){
item.icash = item.money + 100;
console.log(item)
});

map

與 forEach 和 map 最大的差異在於,map 必須回傳東西,除此之外他的功能就和 forEach 一樣,如果我們今天沒有 return 值,就會回傳 undefined。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
let people = [
{
name:'Leo',
money:100
},
{
name:'Peter',
money:200
}
];

let newpeople = people.map(function(item,index){
return {
...item,
icash:item.money+500
}
});

console.log(newpeople);