用Nodejs完成自己的个人博客

本文分享了一位开发者使用Node.js创建个人博客的过程,包括技术选型、项目结构、难点解析及截图展示。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

开始这个个人小项目已经有一段时间了,一直断断续续的,直到今天总算是初见雏形,所以就很想和大家分享一下实现的过程。首先这个的初衷就是学习nodejs,看了几天的书,自己就照着书上的代码来敲,可是由于自己安装的node是最新版,然而书比较旧,好多都不能正确运行,我想了解node的都知道它几乎每天都在更新,出现这样的情况也是必然的。所以想了下,还是在github上找个别人的项目拿来练练手,看一下项目是如何搭建的,经过仔细的琢磨总算是慢慢搭起来了。下来讲一下自己是如何实现的。


一. 项目所用到的技术

express框架:

(1)可以设置中间件来响应 HTTP 请求;
(2)定义路由表用于执行不同的 HTTP 请求动作;

ejs模板

用过Java的jsp的就知道,这和jsp的作用完全相同,动态生成html元素。

mongodb数据库

这和熟悉的mysql数据库不同,mysql是关系型数据库,没一个表的每一项时一条记录,而mongodb是集合类型的,每个集合里存储的是对象,想象一下json,就明白mongodb里存储的数据类型。

mongoose数据库操作

这个是针对mongodb的数据库驱动,里面封装了对数据库的各种基本操作。

二. 项目目录

这里写图片描述

下面介绍下,每个目录都是干什么的:
(1)node_modules:存放各种node插件和express框架;
(2)schemas:在这个文件里用mongoose封装的对象来指定,数据库里要存储的数据结构。
如下,这是一个user的数据集合里面存储的数据项的结构:


> schemas/user.js

var Schema = require('mongoose').Schema;

var userSchema = new Schema({
    name: String,
    password: String,
    icon: String,
    sex: String,
    tel: String,
    qq: String,
    weixin: String,
    weibo: String,
    email: String
});

module.exports = userSchema;

(3)models:此文件夹下的每一个js文件都映射一个对应的schemas里的文件,然后将类型暴露出去,就可以让外界进行各种数据库操做了。

> models/user.js

var mongoose = require('mongoose');
var User = require('../schemas/user');

module.exports = mongoose.model('User', User);

(3)routes:看见名字就知道这个里面是对路由的各种操作,相当于Java里面的servlet要做的事情,进行页面的跳转和数据的传送。下面看routes的目录:
这里写图片描述

在这个文件夹下,index.js是最重要的,里面是所有路由的接口,其他的都是每个路由跳转所要执行的操作。下面的代码是index.js里的部分内容:


> routes/index.js

var login = require('./login');
var blog = require('./blog');
module.exports = function (app){
    app.get('/bloglist', blog.getAllBlog);  //跳到文章列表页
    app.post('/doLogin', login.checkLogin); //验证登录信息
};

可以看到我们传入了app参数,这个是express实例化的对象,所有http的get和post请求都是用app对象来完成的。
(4)static:里面存放的是所有静态资源,比如js,css还有图片等文件。
(5)views:里面存的是所有的html页面。
(6)app.js:这个无疑是express框架中最重要的了,是等个项目的入口文件,在这个项目中只有该文件的生命周期是直到关闭服务器,所以可见它的重要性。在这个文件中需要引入所要使用的:

  • 各种中间件:用于设置session和cookie的express-session和cookie-parser,还有body-parser,用于处理
    JSON和application/x-www-form-urlencoded 编码的数据。
  • 驱动程序包:mongodb的驱动包mongoose;
  • 页面的模板引擎:ejs;

连接并启动数据库,监听端口等都在这个入口文件中。如下代码所示:


> app.js

var express = require('express');
var ejs = require('ejs');
var bodyParser = require('body-parser');
var session = require('express-session');
var cookieParser = require('cookie-parser');
var mongoose = require('mongoose');

//将路由文件引入
var route = require('./routes/index');

//设置端口
var port = process.env.PORT || 3000;

var app = express();

//设置试图的根目录
app.set('views', './views/pages');

//设置试图的模板引擎
app.engine('.html', ejs.__express);
app.set('view engine', 'html'); 

//设置静态资源路径
app.use(express.static('./static'));  

// 解析 application/x-www-form-urlencoded 
app.use(bodyParser.urlencoded({ extended: false })); 
// 解析 application/json 
app.use(bodyParser.json()); 

//设置session和cookie
app.use(cookieParser());
app.use(session({
secret: '12345',
    name: 'testapp',
    resave: false,
    saveUninitialized: true,
}));

//监听端口 
app.listen(port);

console.log("Server is runnng on " + port);

//连接mongodb数据库
mongoose.Promise = global.Promise;  //不加这句会报错
mongoose.connect('mongodb://127.0.0.1/myblog'); 
mongoose.connection.on('open', function (){
    console.log('Connected to Mongoose');
});

route(app);  //初始化所有路由

三. 项目的难点

写这个项目最大的感受就是,node是异步的,和之前一直使用的java有很大区别,很容易出错,可是node页提供了很强大的机制,Promise,他让所有的异步操作看起来更像是顺序的,也让代码变得可读性更强了。下面是获得某条博客信息的具体代码,来看看Promise的魅力:

//获得某条博客的信息,并更新浏览次数
exports.getBlog = function (req, res){
    var blogid = req.params.id;
    var error = '';
    var user = req.session.user || null;
    Blog.findOne({_id: blogid}, function (err, blog){
        if (blog == null){
            error = '该文章被主人删除!';
            res.render({
                error: error
            });
        }else{

            //更新文章阅读次数
            var promise1 = updateLook_num(blogid);
            //查找文章作者的信息
            var promise2 = findUser(blog.authorid);
            //查找该博客的所有评论信息
            var promise3 = findReview(blogid);
            //查看未读消息总数
            var promise4 = message.totalUnreadMess(blog.authorid);

            Promise.all([promise1, promise2, promise3, promise4]).then(function (result){
                res.render('blogdetail', {
                    title: blog.title,
                    error: error,
                    blog: blog,
                    user: user,
                    author: result[1],
                    reviewlist: result[2],
                    totalmess: result[3],
                }); 
            }).catch(function (err){
                console.log(err);
            });
        }   
    });
}

上面的每个promise对象都代表了一个异步操作,如果不适用Promise就会陷入代码嵌套的无底洞,那将会是灾难,可以有了Promise将每个异步操作都分开书写,然后在用all方法去执行,代码就很容易理解,可读性和可维护性都会大大提高。

四. 截图
附上自己的最终截图吧:

博客列表页
这里写图片描述

文章详情页

这里写图片描述

这里写图片描述

评论消息提醒页

这里写图片描述


在这篇博客中,我并没有多说代码如何编写,而是主要说了项目的架构,我想对大多数人来说明白项目的架构,就会有个整体的概念,心里就会有个模板,至于代码的具体实现就看自己的js功底了。

代码已上传至github:https://github.com/lwjcode/myblog
欢迎fork and star.

<think>首先,用户的问题是基于参考站内引用的内容,他们想要知道如何用Node.js和Vue构建个人博客系统。引用的内容提供了有关Node.js和Vue的区别,以及一个基于Node.js和Vue的个人博客网站的描述。关键点从引用中提取:-引用[1]:区分Node.js(服务器端JavaScript运行环境,异步、事件驱动)和Vue.js(前端框架,视图层,数据驱动、组件化)。-引用[2]:使用Node.js后端(如Express框架),Vue.js前端,连接MySQL数据库。技术栈包括Express、Vue等。-引用[3]:讨论浏览器端和Node.js的不同API环境。-引用[4]:详细描述了基于Node.js和Vue的个人博客网站的功能:用户管理、博客管理(写、编辑、发布、删除)、博客分类、用户互动(评论、点赞、分享)、数据统计等。用户的上一次问题:"我想使用Node.js和Vue实现个人博客的功能或架构请问如何用Node.js和Vue构建个人博客系统"。我需要基于这个回答。系统指令要求:-所有行内数学表达式使用$...$格式,但在这个上下文中,可能没有数学表达式,所以可能不需要。-独立公式使用$$...$$并单独成段,同样可能不适用。-LaTeX语法正确:确保如果使用数学,正确格式。-使用中文回答:整个回答必须是中文。-生成相关问题:在回答结束时,生成相关问题。-回答中引用的段落末尾添加引用标识:例如[^1]。用户提供了引用[^1]到[^4],所以我需要正确引用它们。在回答中,我需要自然地引用这些内容。例如,如果我提到某个点来自引用,就在末尾加[^数字]。回答结构:我需要提供一个清晰的结构,解释如何构建个人博客系统使用Node.js和Vue。基于引用:-后端用Node.js,框架如Express。-前端用Vue.js(可能是VueCLI或类似)。-数据库用MySQL(从引用[2]中)。-功能包括用户管理、博客管理、分类、互动等(从引用[4])。计划回答的结构:1.**介绍整个架构**:解释前端和后端的分离,Node.js做后端API,Vue做前端。2.**技术栈选择**:-后端:Node.js+Express(处理HTTP请求,业务逻辑)。-数据库:MySQL(存储用户、博客、评论等)。-前端:Vue.js(SPA,组件化)。可能使用一些工具:如Node.js的npm包管理器、Vue的VueCLI。3.**核心功能实现**:基于引用[4]:-用户系统:注册、登录、权限(使用JWT或session)。-博客系统:CRUD操作(创建、读取、更新、删除博客)。-博客分类:标签或分类系统。-互动功能:评论、点赞、分享。-数据统计:如访问量。-界面设计:前端Vue组件。4.**开发步骤**:逐步讲解:-设置项目:创建后端项目(Node.js)、前端项目(Vue)。-后端开发:Express路由定义API端点(如GET/posts,POST/login)。-数据库集成:使用sequelize或mysql2包连接和操作MySQL。-前端开发:Vue组件用于页面(如博客列表、单个博客、登录表单)。-连接前端和后端:前端调用后端API(使用axios)。-部署:简要提到部署到服务器。5.**注意事项**:如安全(XSS防护)、性能优化。在回答中,我需要引用引用的内容。例如:-当提到Node.js和Vue的区别时,引用[^1]。-当描述技术栈时,引用[^2]。-当讲数据库连接时,从[^2]。-当讲博客功能时,详细引用[^4]。生成相关问题:在最后,类似示例,添加几个相关问题。回答的整体语言:中文,清晰易懂。最终输出结构:-回答主体:分成小节。-结尾:§§相关问题§§,列出相关问题。确保引用正确:在回答中,如果在描述某个点源自引用,就在末尾加[^n],不要在每个段落都加,只在引用时加。</think> ### 基于 Node.js 和 Vue 构建个人博客系统的完整方案 基于您提供的引文和需求(使用 Node.js 和 Vue 实现个人博客的功能或架构),我将详细解释如何一步步构建一个完整的个人博客系统。该方案基于引文中提到的核心技术栈:Node.js 作为后端服务器运行环境,处理业务逻辑和数据交互;Vue.js 作为前端框架,构建用户界面;MySQL 作为数据库,存储数据(引用[^2])。博客系统核心功能包括用户管理(注册、登录、权限)、博客管理(撰写、编辑、发布、删除)、博客分类(按时间、主题等)、用户互动(评论、点赞、分享)以及数据统计(引用[^4])。系统采用前后端分离架构,前端通过 API 与后端通信,确保高效性和可维护性(引用[^1])。以下是一个结构化的实现指南,逐步帮助您完成搭建。 #### 1. **整体架构设计** 个人博客系统采用典型的“前端-后端-数据库”三层架构: - **前端 (Vue.js)**:基于 Vue 的单页面应用(SPA),负责用户界面渲染、交互逻辑和 API 调用。Vue.js 的数据驱动和组件化特性可高效实现博客列表、编辑器和用户面板等模块(引用[^1])。 - **后端 (Node.js + Express)**:Node.js 作为服务器,利用 Express 框架处理 HTTP 请求,实现业务逻辑(如用户验证、博客操作)。Node.js 的非阻塞异步模型确保了高并发性能(引用[^1], [^3])。 - **数据库 (MySQL)**:存储结构化数据(用户、博客、评论等),通过 Sequelize(Node.js ORM 库)进行增删改查操作,简化数据库交互(引用[^2], [^4])。 架构图示意: ``` 前端 (Vue.js) <-- HTTP API (axios) --> 后端 (Node.js/Express) <-- Sequelize --> MySQL ``` #### 2. **技术栈和工具选择** 基于引文推荐和社区标准,技术栈包括: - **后端工具**:Node.js + Express(核心框架)、MySQL(数据库)、Sequelize(ORM 库)、JWT(JSON Web Token,用于用户认证)、Nodemon(开发热重载)。Node.js 通过其文件系统等 API 支持后端逻辑(引用[^2], [^3])。 - **前端工具**:Vue.js + Vue Router(路由管理)+ Vuex(状态管理)+ Axios(API 调用)。Vue CLI 可用于快速初始化项目。 - **开发环境**:NPM(包管理器)管理依赖(如安装 Express 和 Vue 相关包),VS Code 作为 IDE。 安装示例: ```bash # 后端初始化 mkdir blog-backend && cd blog-backend npm init -y npm install express sequelize mysql2 jsonwebtoken body-parser cors nodemon # 前端初始化 (使用 Vue CLI) vue create blog-frontend cd blog-frontend npm install axios vue-router vuex ``` #### 3. **核心功能实现步骤** 实现过程分解为后端开发、前端开发和数据库集成。核心功能参考引用[^4],确保覆盖用户管理、博客操作、分类和互动模块(引用[^4])。 **A. 后端开发(Node.js/Express)** 后端负责 API 端点和业务逻辑。创建 `server.js` 文件作为入口。 - **步骤 1:设置 Express 服务器** 定义一个基本 HTTP 服务器,处理跨域(CORS)和 JSON 数据(引用[^2])。 ```javascript // server.js (后端代码) const express = require('express'); const bodyParser = require('body-parser'); const cors = require('cors'); const app = express(); const port = 3001; // 中间件设置 app.use(cors()); // 解决跨域问题 app.use(bodyParser.json()); // 解析JSON请求 // 测试API app.get('/', (req, res) => { res.send('Node.js后端运行正常!'); }); // 监听端口 app.listen(port, () => { console.log(`Server running at http://localhost:${port}`); }); ``` **运行后端:** `nodemon server.js`(启动热重载)。 - **步骤 2:数据库模型定义(使用 Sequelize)** 连接 MySQL,定义数据模型(用户、博客、评论)。MySQL 数据库需先在本地安装并创建数据库(如 `blog_db`)。 ```javascript // models/index.js (数据库模型) const Sequelize = require('sequelize'); const sequelize = new Sequelize('mysql://user:password@localhost:3306/blog_db'); // 定义用户模型 const User = sequelize.define('User', { username: { type: Sequelize.STRING, unique: true }, password: Sequelize.STRING, role: Sequelize.STRING // 如 'user' 或 'admin' }); // 定义博客模型 const Blog = sequelize.define('Blog', { title: Sequelize.STRING, content: Sequelize.TEXT, category: Sequelize.STRING, // 用于博客分类,如“技术”或“生活” views: Sequelize.INTEGER // 访问量统计 }); // 定义评论模型 const Comment = sequelize.define('Comment', { content: Sequelize.TEXT }); // 模型关联 (Blog 属于 User; Comment 属于 Blog 和 User) User.hasMany(Blog); Blog.belongsTo(User); User.hasMany(Comment); Blog.hasMany(Comment); Comment.belongsTo(User); Comment.belongsTo(Blog); // 同步数据库表 sequelize.sync().then(() => console.log('Database tables created!')); ``` 此模型支持博客分类(通过 `category` 字段)和数据统计(如 `views` 访问量)(引用[^4])。 - **步骤 3:实现API端点** 创建路由处理具体的业务逻辑,包括用户认证(JWT)、博客 CRUD、评论操作和分类查询(引用[^2], [^4])。 ```javascript // routers/userRouter.js const express = require('express'); const bcrypt = require('bcrypt'); const jwt = require('jsonwebtoken'); const { User } = require('../models'); const router = express.Router(); // 用户注册API router.post('/register', async (req, res) => { const { username, password } = req.body; const hashedPassword = await bcrypt.hash(password, 10); try { await User.create({ username, password: hashedPassword }); res.status(201).json({ message: '注册成功!' }); } catch (error) { res.status(500).json({ error: '用户已存在' }); } }); // 用户登录API (返回JWT) router.post('/login', async (req, res) => { const { username, password } = req.body; const user = await User.findOne({ where: { username } }); if (!user) return res.status(401).json({ error: '用户不存在' }); const isValid = await bcrypt.compare(password, user.password); if (!isValid) return res.status(401).json({ error: '密码错误' }); const token = jwt.sign({ id: user.id, role: user.role }, 'secret_key'); res.json({ token }); }); module.exports = router; ``` 其他路由(如 `blogRouter.js`)处理博客操作: ```javascript // routers/blogRouter.js const express = require('express'); const { Blog } = require('../models'); const authMiddleware = require('../middleware/auth'); // JWT验证中间件 const router = express.Router(); // 创建博客 (需要认证) router.post('/', authMiddleware, async (req, res) => { const { title, content, category } = req.body; try { await Blog.create({ title, content, category, UserId: req.user.id }); res.status(201).json({ message: '博客创建成功!' }); } catch (error) { res.status(500).json({ error: '创建失败' }); } }); // 获取博客列表 (支持分类过滤) router.get('/', async (req, res) => { const { category } = req.query; // 通过查询参数分类,如?category=技术 const whereClause = category ? { category } : {}; const blogs = await Blog.findAll({ where: whereClause, include: 'User' }); res.json(blogs); }); // 更新博客访问量 (数据统计) router.patch('/:id/view', async (req, res) => { const blog = await Blog.findByPk(req.params.id); blog.views += 1; await blog.save(); res.json({ views: blog.views }); }); ``` **关键点:** - 用户互动功能(评论、点赞)可通过类似路由实现,例如在 `commentRouter.js` 中添加 POST /comment 端点(引用[^4])。 - 分类逻辑通过查询参数实现(如按时间、主题),确保数据驱动(引用[^1], [^4])。 **B. 前端开发(Vue.js)** 前端项目用于用户界面,使用 Vue CLI 初始化。 - **步骤 1:项目结构和组件设计** 创建主要组件: - `src/views/BlogList.vue`:博客列表页面。 - `src/views/BlogDetail.vue`:单个博客详情页(含评论和点赞)。 - `src/views/Login.vue`:用户登录和注册。 - `src/components/Header.vue`:导航栏(含分类筛选)。 在 `src/router/index.js` 配置路由: ```javascript import BlogList from '../views/BlogList.vue'; import BlogDetail from '../views/BlogDetail.vue'; import Login from '../views/Login.vue'; const routes = [ { path: '/', component: BlogList }, { path: '/blog/:id', component: BlogDetail }, { path: '/login', component: Login }, // 其他路由... ]; ``` - **步骤 2:API 集成(使用 Axios)** 在前端调用后端 API。在 `src/services/api.js` 创建 Axios 实例: ```javascript import axios from 'axios'; const api = axios.create({ baseURL: 'http://localhost:3001/api', // 假设后端API根路径 }); // 设置请求拦截器(用于添加JWT) api.interceptors.request.use(config => { const token = localStorage.getItem('token'); if (token) config.headers.Authorization = `Bearer ${token}`; return config; }); export default { // 博客相关API getBlogs(category) { return api.get('/blogs', { params: { category } }); }, createBlog(blogData) { return api.post('/blogs', blogData); }, // 用户API login(credentials) { return api.post('/login', credentials); }, // 评论API postComment(commentData) { return api.post('/comments', commentData); } }; ``` - **步骤 3:实现核心页面** 以 `BlogList.vue` 为例,展示博客列表并支持分类筛选: ```vue <template> <div> <Header @category-change="setCategory" /> <div v-for="blog in blogs" :key="blog.id"> <h3>{{ blog.title }}</h3> <p>{{ blog.content.substring(0, 100) }}...</p> <button @click="viewBlog(blog.id)">查看详情</button> </div> </div> </template> <script> import Header from '../components/Header.vue'; import api from '../services/api'; export default { components: { Header }, data() { return { blogs: [], selectedCategory: 'all', }; }, methods: { setCategory(category) { this.selectedCategory = category; this.loadBlogs(); }, async loadBlogs() { const response = await api.getBlogs(this.selectedCategory === 'all' ? null : this.selectedCategory); this.blogs = response.data; }, viewBlog(id) { this.$router.push(`/blog/${id}`); }, }, mounted() { this.loadBlogs(); } }; </script> ``` **关键点:** - 用户互动功能(如点赞)可在 `BlogDetail.vue` 中添加按钮和 API 调用(如 POST /like)。 - 界面设计需简洁美观,使用 Vue 组件化确保复用性(引用[^4])。 **C. 数据库和集成测试** - **数据库连接:** 确保 MySQL 运行并配置 Sequelize(参考后端步骤 2),处理数据持久化。 - **前后端联调:** 启动后端(`nodemon server.js`)和前端(`npm run serve`)。测试注册、登录、博客发布等功能。 - **安全优化:** 在 Node.js 后端添加输入验证(如 express-validator),防止 XSS 攻击(引用[^3])。 #### 4. **部署和维护建议** - **部署方式**:前端使用 Vercel 或 Netlify(静态托管),后端部署到云服务器(如 AWS EC2)或 Serverless(Node.js 兼容)。 - **性能优化:** Node.js 后端使用集群模式(如 PM2),Vue 前端启用代码分割(Vue Router 懒加载)(引用[^1])。 - **扩展功能:** 引用[^4] 提到的数据统计(如访问量地域分布)可集成 Google Analytics 或自定义日志系统(引用[^4])。 ### 相关问题
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值