帮助你简易起步一个BLOG(博客搭建)项目

Blog项目

  • 后端
    • 项目结构
    • 1. 项目初始化
    • 2. 详细步骤
    • 3.postman测试
  • 前端
    • 1. 项目初始化
    • 2. 详细步骤

本章节是为了帮助你起步一个完整的前后端分离项目。
前端技术栈: react、vite、mantine、tailwind CSS、zustand、rxjs、threejs

后端技术栈:nodemon、nodejs、vite

后端

项目结构

blog-backend/
│
├── server/
│   ├── index.js
│   └── routes/
│       └── posts.js
├── package.json
└── vite.config.js

1. 项目初始化

  • 创建项目文件夹并初始化 Node.js 项目。
  • 安装必要的依赖项。

2. 详细步骤

  1. 创建项目文件夹并初始化 Node.js 项目
mkdir blog-backend
cd blog-backend
npm init -y
  1. 安装必要的依赖项
    安装 Express.js 作为我们的 web 框架,安装 Nodemon 作为开发依赖,用于监控文件变化并自动重启服务器。
npm install express
npm install --save-dev nodemon
  1. 创建 Express.js 服务器
    在 server 文件夹中创建 index.js 入口文件。
// server/index.js
const express = require('express');
const path = require('path');
const postsRouter = require('./routes/posts');const app = express();
const PORT = process.env.PORT || 3000;// 中间件
app.use(express.json());
app.use(express.urlencoded({ extended: true }));// 路由
app.use('/api/posts', postsRouter);// 启动服务器
app.listen(PORT, () => {console.log(`Server is running on http://localhost:${PORT}`);
});
  1. 创建路由文件
    在 server/routes 文件夹中创建 posts.js 路由文件。
// server/routes/posts.js
const express = require('express');
const router = express.Router();// 模拟的博客帖子数据
let posts = [{ id: 1, title: 'First Post', content: 'This is the first post.' },{ id: 2, title: 'Second Post', content: 'This is the second post.' }
];// 获取所有博客帖子
router.get('/', (req, res) => {res.json(posts);
});// 获取单个博客帖子
router.get('/:id', (req, res) => {const post = posts.find(p => p.id === parseInt(req.params.id));if (post) {res.json(post);} else {res.status(404).json({ message: 'Post not found' });}
});// 创建新的博客帖子
router.post('/', (req, res) => {const newPost = {id: posts.length + 1,title: req.body.title,content: req.body.content};posts.push(newPost);res.status(201).json(newPost);
});// 更新博客帖子
router.put('/:id', (req, res) => {const post = posts.find(p => p.id === parseInt(req.params.id));if (post) {post.title = req.body.title || post.title;post.content = req.body.content || post.content;res.json(post);} else {res.status(404).json({ message: 'Post not found' });}
});// 删除博客帖子
router.delete('/:id', (req, res) => {posts = posts.filter(p => p.id !== parseInt(req.params.id));res.status(204).end();
});module.exports = router;
  1. 更新 package.json 脚本
    在 package.json 中更新脚本,以便在开发过程中使用 Nodemon 监控文件变化。
{"name": "blog-backend","version": "1.0.0","description": "A blog backend using Node.js and Express.js","main": "server/index.js","scripts": {"start": "node server/index.js","dev": "nodemon server/index.js"},"dependencies": {"express": "^4.17.1"},"devDependencies": {"nodemon": "^2.0.7"}
}
  1. 运行项目
    运行以下命令启动开发服务器:
npm run dev

通过以上步骤,我们已经创建了一个基本的博客后端项目,使用 Node.js 和 Express.js 提供 API 接口。这个后端支持获取、创建、更新和删除博客帖子。你可以在前端使用任何框架或工具与这个 API 进行交互。
a. 为这些 API 添加单元测试来验证其功能。
b. 增加用户认证和授权,以保护博客帖子数据。

3.postman测试

3.1 获取所有博客帖子

方法: GET
URL: http://localhost:3000/api/posts

点击 “Send” 按钮,你应该会看到类似下面的响应:

[{ "id": 1, "title": "First Post", "content": "This is the first post." },{ "id": 2, "title": "Second Post", "content": "This is the second post." }
]

3.2. 获取单个博客帖子

方法: GET
URL: http://localhost:3000/api/posts/1

点击 “Send” 按钮,你应该会看到类似下面的响应:

{ "id": 1, "title": "First Post", "content": "This is the first post." }

3.3. 创建新的博客帖子

方法: POST
URL: http://localhost:3000/api/posts

Body: 选择 raw 和 JSON,然后输入以下内容:

{"title": "New Post","content": "This is a new post."
}

点击 “Send” 按钮,你应该会看到类似下面的响应:

{"id": 3,"title": "New Post","content": "This is a new post."
}

3.4. 更新博客帖子

方法: PUT
URL: http://localhost:3000/api/posts/1

Body: 选择 raw 和 JSON,然后输入以下内容:

{"title": "Updated First Post","content": "This is the updated first post."
}

点击 “Send” 按钮,你应该会看到类似下面的响应:

{"id": 1,"title": "Updated First Post","content": "This is the updated first post."
}

3.5. 删除博客帖子

方法: DELETE
URL: http://localhost:3000/api/posts/1

点击 “Send” 按钮,你应该会看到类似下面的响应:

{}

你已经使用 Postman 成功地测试了这个博客 API 的所有基本功能,包括获取所有帖子、获取单个帖子、创建新帖子、更新帖子和删除帖子。

a. 在 API 请求中添加身份验证以保护博客内容。

b. 为 API 添加更多的功能,例如评论功能或者用户管理功能

前端

1. 项目初始化

  • 创建一个新的 Vite 项目并选择 React 作为框架。
  • 安装必要的依赖项。

2. 详细步骤

  1. 创建项目文件夹并初始化 Vite 项目
    首先,创建项目文件夹并初始化 Vite 项目:
mkdir blog-frontend
cd blog-frontend
npm init vite@latest

选择 react 作为模板:

# Project name: blog-frontend
# Select a framework: react
# Select a variant: react

然后安装项目依赖:

cd blog-frontend
npm install
  1. 安装必要的依赖项
    安装 Mantine、Tailwind CSS、Zustand、RxJS 和 Three.js:
npm install @mantine/core @mantine/hooks @emotion/react @emotion/styled zustand rxjs three
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
npm install react-router-dom
  1. 配置 Tailwind CSS
    编辑 tailwind.config.js 文件以包含所有文件:
/** @type {import('tailwindcss').Config} */
export default {content: ["./index.html","./src/**/*.{js,ts,jsx,tsx}",],theme: {extend: {},},plugins: [],
}

在 src 文件夹中创建 index.css 文件,并添加 Tailwind 的基本样式:

/* src/index.css */
@tailwind base;
@tailwind components;
@tailwind utilities;

确保在 main.jsx 中导入 index.css 文件:

// src/main.jsx
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';ReactDOM.render(<React.StrictMode><App /></React.StrictMode>,document.getElementById('root')
);
  1. 创建主要组件和结构
    在 src 文件夹中创建以下文件和文件夹结构:
src/
├── components/
│   ├── Header.jsx
│   ├── PostList.jsx
│   └── Post.jsx
├── hooks/
│   └── usePosts.js
├── pages/
│   ├── Home.jsx
│   └── PostDetail.jsx
├── App.jsx
└── main.jsx

App.jsx:

import React from 'react';
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';
import { MantineProvider } from '@mantine/core';
import Home from './pages/Home';
import PostDetail from './pages/PostDetail';
import Header from './components/Header';function App() {return (<MantineProvider withGlobalStyles withNormalizeCSS><Router><Header /><Routes><Route path="/" element={<Home />} /><Route path="/post/:id" element={<PostDetail />} /></Routes></Router></MantineProvider>);
}export default App;

Header.jsx:

import React from 'react';
import { Link } from 'react-router-dom';function Header() {return (<header className="bg-blue-600 p-4 text-white"><nav className="container mx-auto"><Link to="/" className="text-lg font-bold">My Blog</Link></nav></header>);
}export default Header;

Home.jsx:

import React from 'react';
import PostList from '../components/PostList';function Home() {return (<div className="container mx-auto p-4"><h1 className="text-3xl font-bold mb-4">Blog Posts</h1><PostList /></div>);
}export default Home;

PostDetail.jsx:

import React from 'react';
import { useParams } from 'react-router-dom';function PostDetail() {const { id } = useParams();// Fetch post detail using idreturn (<div className="container mx-auto p-4"><h1 className="text-3xl font-bold mb-4">Post Detail</h1>{/* Render post detail here */}</div>);
}export default PostDetail;

PostList.jsx:

import React from 'react';
import { Link } from 'react-router-dom';
import usePosts from '../hooks/usePosts';function PostList() {const posts = usePosts();return (<div>{posts.map(post => (<div key={post.id} className="mb-4 p-4 border rounded"><h2 className="text-2xl font-bold"><Link to={`/post/${post.id}`}>{post.title}</Link></h2><p>{post.content}</p></div>))}</div>);
}export default PostList;

usePosts.js:

import { useEffect, useState } from 'react';function usePosts() {const [posts, setPosts] = useState([]);useEffect(() => {fetch('/api/posts').then(response => response.json()).then(data => setPosts(data));}, []);return posts;
}export default usePosts;
  1. 配置 Vite 代理
    在 vite.config.js 文件中配置代理,以将 API 请求转发到后端服务器:
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';export default defineConfig({plugins: [react()],server: {proxy: {'/api': 'http://localhost:3000'}}
});
  1. 运行前端项目
    在项目根目录下运行以下命令启动开发服务器:
npm run dev

通过以上步骤,我们已经创建了一个使用 React、Vite、Mantine、Tailwind CSS、Zustand、RxJS 和 Three.js 的博客前端。这个前端项目通过 Vite 开发服务器代理 API 请求,并与之前创建的 Node.js 和 Express.js 后端进行交互。

a. 在前端添加更多组件,例如博客详情页和评论功能。

b. 使用 Three.js 创建炫酷的 3D 动画效果,并将其集成到博客前端中。

前后端都起起来,就可以在浏览器中访问前端页面了。
在这里插入图片描述
这一章主要是帮助小伙伴迅速起一个前后端分离的blog项目,后续可以自行diy。
后续我可能会继续更新自己的项目。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/35428.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Transformer教程之神经网络和深度学习基础

在当今的人工智能领域&#xff0c;Transformer已经成为了一个热门的词汇。它不仅在自然语言处理&#xff08;NLP&#xff09;领域取得了巨大的成功&#xff0c;还在计算机视觉等其他领域展现出了强大的潜力。然而&#xff0c;要真正理解Transformer&#xff0c;我们首先需要扎实…

gdb用法

创建文件 // main.cpp文件 // 稳态误差 void pid_test_wentaiwucha() {float p 1.5;int t 1; // t 1s;int target 5; // 5m/sfloat output 0;float radis 3; // 稳态误差std::cout << "output: " << std::endl;fo…

并发 多线程

目录 thread thread 类总览 构造函数 join joinable ​编辑 detach swap yield swap 成员函数的调用 namespace::this_thread 线程同步--锁 互斥锁mutex 递归锁recursive_mutex 定时锁 Lock 锁辅助类 lock_guard​编辑 unique_lock std::lock 解决死锁问题 消息…

浅谈逻辑控制器之随机顺序控制器

浅谈逻辑控制器之随机顺序控制器 随机顺序控制器&#xff08;Random Order Controller&#xff09;作为一个独特的逻辑控制器&#xff0c;为测试脚本的执行增添了一层随机性&#xff0c;特别适用于模拟用户行为中不确定的访问模式。 随机顺序控制器概述 随机顺序控制器&…

代码随想录算法训练营第三十六天|62.不同路径、 63. 不同路径 II、343.整数拆分(可跳过)、96.不同的二叉搜索树(可跳过)

62.不同路径 题目链接&#xff1a;62.不同路径 文档讲解&#xff1a;代码随想录 状态&#xff1a;还行 思路&#xff1a;当前状态的只有可能是从上面或者左边过来的&#xff0c;所以 dp[i][j] dp[i-1] dp[j-1] 题解&#xff1a; public int uniquePaths(int m, int n) {if (…

Docker 安装Nginx部署网站 防火墙端口 数据卷挂载

拉取镜像 docker pull nginx#不写版本号 表示最新版本查看是否拉取成功 docker images#成功 nginx latest 605c77e624dd 2 years ago 141MB mysql 8.0 3218b38490ce 2 years ago 516MB mysql latest 3218b38490ce 2 years ago 5…

virtualbox(7.0) ubuntu(22) 和win11共享文件夹

在虚拟机中安装增强功能。在virtualbox中配置 执行命令将用户加入vboxsf组 sudo adduser your_usrname vboxsf 重启ubuntu即可

LeetCode 585, 438, 98

目录 585. 2016年的投资题目链接表要求知识点思路代码 438. 找到字符串中所有字母异位词题目链接标签思路代码 98. 验证二叉搜索树题目链接标签合法区间思路代码 中序遍历思路代码 585. 2016年的投资 题目链接 585. 2016年的投资 表 表Insurance的字段为pid、tiv_2015、tiv…

Charles网络抓包工具手机抓包配置(二)

目录 事前配置 配置手机连接 代理设置 Https请求设置 手机安装根证书 手机连接代理 证书获取​编辑 证书安装 成果 前言-与正文无关 ​ 生活远不止眼前的苦劳与奔波&#xff0c;它还充满了无数值得我们去体验和珍惜的美好事物。在这个快节奏的世界中&#xff0c;我们…

CesiumJS【Basic】- #020 加载glb/gltf文件(Primitive方式)

文章目录 加载glb/gltf文件(Primitive方式)1 目标2 代码实现3 资源文件加载glb/gltf文件(Primitive方式) 1 目标 使用Primitive方式加载glb/gltf文件 2 代码实现 import * as Cesium from "cesium";const viewer = new Cesium.Viewer

ElementPlus Combogrid 组件

效果图: 1.声明 Props类型 export type comboGridPropType { modelValue: any; url: string; keyField?: string; labelField?: string; filterOptions?: Array<ISearchOption>; tableColumns?: Array<TableColumns>; enableField?: string; multiple?: …

Psychtoolbox 脑电实验范式之mp4视频绘制

1. 读取 首先需要使用到Screen(‘OpenMovie’)函数&#xff0c;该函数可以读取mp4、gif格式的数据&#xff0c;具体方式如下&#xff1a; clear; clc; Screen(Preference, SkipSyncTests, 1); screens Screen(Screens); screenNum max(screens); [window, screenRect] Scr…

C++语法20 一维数组及其相关问题详解

这是《C算法宝典》语法入门篇的第20节文章啦~ 如果你之前没有太多C基础&#xff0c;请点击&#x1f449;专栏&#xff1a;C语法入门&#xff0c;如果你C语法基础已经炉火纯青&#xff0c;则可以进阶算法&#x1f449;专栏&#xff1a;算法知识和数据结构&#x1f449;专栏&…

串口通信中字符和16进制显示的区别分析,串口发送数据

分析的原因 在对串口传送数值时&#xff0c;不想再进行一步字符转化&#xff0c;想要直接传送数值。但查看时就需要以16进制的数值形式查看数据&#xff0c;否则将不能看到正确的数据显示 下图是对串口寄存器发送一个16bit位的数据 void uart0Senduint16(UINT16 dat){SBUFdat…

element-plus 日期选择添加确定按钮

需求&#xff1a;选择日期后&#xff0c;点击确定按钮关闭面板 思路&#xff1a; 使用shortcuts自定义确定和取消按钮选择日期后使用handleOpen()强制开启面板点击确定后使用handleClose()关闭面板 <template><el-date-pickerref"pickerRef"v-model"…

【Android11】开机启动日志捕捉服务

一、前言 制作这个功能的原因是客户想要自动的记录日志中的报错和警告到设备的内存卡里面。虽然开发者模式中有一个“bug report” 会在/data/user_de/0/com.android.shell/files/bugreports/目录下生成一个zip包记录了日志。但是客户觉得这个日志很难获取到他们需要的信息&am…

基于盲信号处理的声音分离——基于自然梯度的ICA算法

基于自然梯度的ICA算法主要利用相互独立的随机信号的联合概率密度是各自概率密度的乘积这一特性&#xff0c;建立了等独立性度量原则&#xff0c;具体实现如下。 首先&#xff0c;输出信号 相互独立&#xff0c;则其概率密度满足 上式中 表示 的概率密度函数&#xff0c;可以…

怎么扫描图片变成pdf格式?办公人士值得收藏的宝藏工具

将图片扫描并转换为PDF格式可以通过多种途径实现&#xff0c;无论是使用专业的扫描仪还是智能手机&#xff0c;都有相应的方法。 PDF 是什么&#xff1f; PDF&#xff0c;全称为 Portable Document Format&#xff08;便携式文档格式&#xff09;&#xff0c;是由Adobe System…

12,SPI

Flash芯片&#xff1a;W25Q64&#xff0c;可以看成一个储存器 W25Q64芯片和单片机之间的通信方式是SPI SPI:串行同步全双工&#xff0c;主从通信 判断一个设备是不是SPI通信&#xff0c;看是否有这几个线&#xff1a;SCK&#xff0c;CS&#xff0c;MISO&#xff0c;MOSI SCK…

Altium Designer软件下载安装「PCB设计软件」安装包资源获取

Altium Designer作为一款集成化的电子产品开发系统&#xff0c;它主要适用于Windows操作系统&#xff0c;为电子设计工程师们提供了一个高效、便捷的工作平台。 在Altium Designer中&#xff0c;原理图设计、电路仿真、PCB绘制编辑、拓扑逻辑自动布线、信号完整性分析和设计输出…