庆祝你的胜利:是什么让你的一周难忘

发布: (2026年4月29日 GMT+8 09:08)
5 分钟阅读
原文: Dev.to

Source: Dev.to

作为开发者,我们常常关注哪些地方出了问题、接下来要做什么,或者哪些功能还没有上线。但当我们停下来反思那些已经奏效的事情时,成长就会发生——修复的小 bug、成功发布的功能,或是终于弄懂的新概念。

在本教程中,我们将使用 Node.js 和 Express,并将数据存储在 JSON 文件中,构建一个简易的 “每周成就追踪器”。它对初学者友好,代码量充足,非常适合一次一次地庆祝自己的进步——每周一次。

完成后,你将拥有一个可运行的 Web 应用,能够:

  • 添加本周的成就
  • 查看所有成就
  • 用表情符号彩带 🎉 庆祝你的进步

让我们开始吧!

第一步:设置项目

创建一个新目录并初始化一个 Node.js 项目:

mkdir weekly-wins-tracker
cd weekly-wins-tracker
npm init -y

安装 Express:

npm install express

安装 nodemon 以在开发期间自动重启(可选,但推荐):

npm install --save-dev nodemon

更新你的 package.json 脚本:

{
  "scripts": {
    "start": "node server.js",
    "dev": "nodemon server.js"
  }
}

Step 2: Create the Server

Create server.js:

const express = require('express');
const fs = require('fs');
const path = require('path');
const app = express();
const PORT = 3000;

// Middleware to parse JSON and serve static files
app.use(express.json());
app.use(express.static('public'));

我们使用:

  • express.json() 来解析传入的 JSON
  • express.static('public') 来提供 HTML、CSS 和 JS 文件

第 3 步:设置数据存储

我们将在一个名为 wins.json 的 JSON 文件中存储获胜记录。

在项目根目录创建 wins.json

[]

添加用于读取和写入获胜记录的辅助函数:

const WINS_FILE = path.join(__dirname, 'wins.json');

// 从文件读取获胜记录
function readWins() {
  const data = fs.readFileSync(WINS_FILE);
  return JSON.parse(data);
}

// 将获胜记录写入文件
function writeWins(wins) {
  fs.writeFileSync(WINS_FILE, JSON.stringify(wins, null, 2));
}

第 4 步:构建 API 端点

我们将创建三个路由:

  • GET /wins – 获取所有 win
  • POST /wins – 添加一个新的 win
  • GET / – 提供前端页面

添加路由:

// Get all wins
app.get('/wins', (req, res) => {
  try {
    const wins = readWins();
    res.json(wins);
  } catch (err) {
    res.status(500).json({ error: 'Failed to read wins' });
  }
});

// Add a new win
app.post('/wins', (req, res) => {
  const { text } = req.body;

  if (!text || text.trim() === '') {
    return res.status(400).json({ error: 'Win text is required' });
  }

  const newWin = {
    id: Date.now().toString(),
    text: text.trim(),
    date: new Date().toISOString().split('T')[0]
  };

  const wins = readWins();
  wins.push(newWin);
  writeWins(wins);

  res.status(201).json(newWin);
});

别忘了在 server.js 的末尾启动服务器:

app.listen(PORT, () => {
  console.log(`Server is running on http://localhost:${PORT}`);
});

第5步:创建前端

创建一个 public 文件夹并添加 index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Weekly Wins Tracker</title>
  <style>
    body {
      font-family: 'Segoe UI', sans-serif;
      max-width: 600px;
      margin: 40px auto;
      padding: 20px;
      background: #f9f9ff;
      color: #333;
    }
    h1 { color: #4a4a98; text-align: center; }
    input, button {
      padding: 10px;
      margin: 10px 0;
      width: 100%;
      box-sizing: border-box;
    }
    button {
      background: #4a4a98;
      color: white;
      border: none;
      cursor: pointer;
    }
    ul {
      list-style: none;
      padding: 0;
    }
    li {
      background: white;
      margin: 8px 0;
      padding: 12px;
      border-radius: 6px;
      box-shadow: 0 1px 3px rgba(0,0,0,0.1);
    }
    .confetti {
      font-size: 1.5em;
      margin-right: 8px;
    }
  </style>
</head>
<body>
  <h1>🎉 Celebrate Your Wins</h1>

  <input type="text" id="winInput" placeholder="What did you achieve this week?" />
  <button onclick="addWin()">Add Win</button>

  <ul id="winsList"></ul>

  <script>
    // Load wins on page load
    window.onload = loadWins;

    async function loadWins() {
      const res = await fetch('/wins');
      const wins = await res.json();
      const list = document.getElementById('winsList');
      list.innerHTML = '';
      wins.forEach(win => {
        const li = document.createElement('li');
        li.innerHTML = `🎊${win.text} (${win.date})`;
        list.appendChild(li);
      });
    }

    async function addWin() {
      const input = document.getElementById('winInput');
      const text = input.value.trim();
      if (!text) return;

      const res = await fetch('/wins', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ text })
      });

      if (res.ok) {
        input.value = '';
        loadWins();
      } else {
        const err = await res.json();
        alert(err.error);
      }
    }
  </script>
</body>
</html>

现在运行应用:

npm run dev   # or npm start

在浏览器中打开 http://localhost:3000,添加几条成就,并观看列表伴随彩纸屑一起增长! 🎉

0 浏览
Back to Blog

相关文章

阅读更多 »

消息与通知工具比较 (2026)

PostgreSQL LISTEN/NOTIFY ✅ 优点 - 内置于数据库,无需额外安装。 - 严格事务化:只有在数据满足条件时才会发送消息。