一个 Vue + Node + MongoDB 博客系统
源码
耗时半载(半个月)的大项目终于完成了。这是一个博客系统,使用 Vue 做前端框架,Node + express 做后端,数据库使用的是 MongoDB。实现了用户注册、用户登录、博客管理(文章的修改和删除)、文章编辑(Markdown)、标签分类等功能。
很早之前就想写一个个人博客。学了 Vue 之后,把前端部分写出来,然后 Node 一直拖拖拉拉的学了很久,中间又跑去实习了一段时间,所以直到回学校之后才列了个计划把这个项目实现了。
翻出之前写的前端部分,好丑啊,干脆推掉重写吧。前端模仿的是 hexo 的经典主题 NexT ,本来是想把源码直接拿过来用的,后来发现还不如自己写来得快,就全部自己动手实现成 vue components。
实现的功能
- 文章的编辑,修改,删除
- 支持使用
Markdown
编辑与实时预览 - 支持代码高亮
- 给文章添加标签
- 支持用户注册登录
使用到的技术
前端
- Vue.js
- vue-cli
- vue-router
- vue-resource
- element-ui
- marked
- highlight.js
后端
- Node.js
- Express
- Mongoose
基本思路
前端使用 vue-router
操作路由,实现单页应用的效果。使用 vue-resource
从后台获取数据,数据的处理全部都在前端,所以后端要做的事情很简单——把前端打包好的数据存进数据库中和从数据库中取出数据。前后端使用统一的路由命名规则。
项目目录
| app.js 后端入口
| index.html 入口页面
| .babelrc babel配置
| .gitignore git配置
| package.json
| webpack.config.js webpack配置
|
|-dist vue打包生成的文件
|
|-node_modules 模块
|
|-server 后端| check.js| db.js 数据库__| router.js 路由
|
|-src 前端|-assets 静态资源|-components 组件| App.vue| main.js
webpack 配置
webpack 大部分是 vue-cli 自动生成的,添加了让前后端http请求都转到node的3000端口,而不是前端的8080端口的配置。
devServer: {historyApiFallback: true,noInfo: true,//让前后端http请求都转到node的3000端口,而不是前端的8080端口proxy: {'/': {target: 'http://localhost:3000/'}}}
这里涉及一个新手可能会不明白的问题(我之前就捣鼓了半天)。
开发的时候要先打开数据库 MongoDB ,使用命令 mongod
。
然后打开后端服务器 node app
,后端监听 3000 端口。
最后打开前端开发模式 npm run dev
,前端启动了一个 webpack 服务器,监听 8080 端口用于热刷新。通过配置把前端的http请求转到 3000 端口。
前端部分
命名视图
所有页面都用到的元素可以写在 App.vue
上面,也可以写成公共组件。我在 App.vue 中使用了命名视图,因为 sidebar 这个组件有的页面需要有的不需要,不需要的时候就不用加载。
<!--App.vue-->
<template><div id="app"><div class="black_line"></div><div id="main"><router-view name="sidebar"></router-view><router-view></router-view></div></div>
</template>
router
路由的配置写在 main.js 中,分为前台展示和后台管理。后台管理统一以 ‘/admin’ 开头。注册页和登录页写在一起了,上面有两个按钮“注册”和“登录”(我好懒-_-)。
// main.js
const router = new VueRouter({routes: [{path: '/', components: {default: article, sidebar: sidebar}},{path: '/article', components: {default: article, sidebar: sidebar}},{path: '/about', components: {default: about, sidebar: sidebar}},{path: '/articleDetail/:id', components: {default: articleDetail, sidebar: sidebar}},{path: '/admin/articleList', components: {default: articleList, sidebar: sidebar}},{path: '/admin/articleEdit', component: articleEdit},{path: '/admin/articleEdit/:id', component: articleEdit},{path: '/admin/signin', component: signin}]
})
element UI
使用了 element 用于消息提醒和标签分类。并不需要整个引入,而是使用按需引入。
// main.js
// 按需引用element
import { Button, Message, MessageBox, Notification, Popover, Tag, Input } from 'element-ui'
import 'element-ui/lib/theme-default/index.css'const components = [Button, Message, MessageBox, Notification, Popover, Tag, Input]components.forEach((item) => {Vue.component(item.name, item)
})const MsgBox = MessageBox
Vue.prototype.$msgbox = MsgBox
Vue.prototype.$alert = MsgBox.alert
Vue.prototype.$confirm = MsgBox.confirm
Vue.prototype.$prompt = MsgBox.prompt
Vue.prototype.$message = Message
Vue.prototype.$notify = Notification
vue-resource
用于向后端发起请求。打通前后端的关键。
// GET /someUrlthis.$http.get('/someUrl').then(response => {// success callback}, response => {// error callback});
get 请求
前端发起 get 请求,当请求成功被返回执行第一个回调函数,请求没有被成功返回则执行第二个回调函数。
this.$http.get('/api/articleDetail/' + id).then(response => this.article = response.body,response => console.log(response)
)
后端响应请求并返回结果
// router.js
router.get('/api/articleDetail/:id', function (req, res) {db.Article.findOne({ _id: req.params.id }, function (err, docs) {if (err) {console.error(err)return}res.send(docs)})
})
post 请求
前端发起 post 请求,当请求成功被返回执行第一个回调函数,请求没有被成功返回则执行第二个回调函数。
// 新建文章
// 即将被储存的数据 obj
let obj = {title: this.title,date: this.date,content: this.content,gist: this.gist,labels: this.labels
}
this.$http.post('/api/admin/saveArticle', {articleInformation: obj
}).then(response => {self.$message({message: '发表文章成功',type: 'success'})// 保存成功后跳转至文章列表页self.refreshArticleList()},response => console.log(response)
)
后端存储数据并返回结果
// router.js
// 文章保存
router.post('/api/admin/saveArticle', function (req, res) {new db.Article(req.body.articleInformation).save(function (err) {if (err) {res.status(500).send()return}res.send()})
})
后端部分
后端使用 express 构建了一个简单的服务器,几乎只用于操作数据库。
app.js 位于项目根目录,使用 node app
运行服务器。
const express = require('express')
const fs = require('fs')
const path = require('path')
const bodyParse = require('body-parser')
const session = require('express-session')
const MongoStore = require('connect-mongo')(session)
const router = require('./server/router')
const app = express()const resolve = file => path.resolve(__dirname, file)app.use('/dist', express.static(resolve('./dist')))
app.use(bodyParse.json())
app.use(bodyParse.urlencoded({ extended: true }))
app.use(router)// session
app.set('trust proxy', 1) // trust first proxy
app.use(session({secret: 'blog',resave: false,saveUninitialized: true,cookie: {secure: true,maxAge: 2592000000},store: new MongoStore({url: 'mongodb://localhost:27017/blog'})
}))app.get('*', function (req, res) {let html = fs.readFileSync(resolve('./' + 'index.html'), 'utf-8')res.send(html)
})app.listen(3000, function () {console.log('访问地址为 localhost:3000')
})
给自己挖了一个坑。因为登录之后需要保存用户状态,用来判断用户是否登录,如果登录则可以进入后台管理,如果没有登录则不能进入后台管理页面。之前写 node 的时候用的是 session 来保存,不过spa应用不同于前后端不分离的应用,我在前端对用户输入的账号密码进行了判断,如果成功则请求登录在后端保存 session。不过不知道出于什么原因,session 总是没办法赋值。因为我 node 学的也是半吊子,所以暂时放着,等我搞清楚了再来填坑。
收获
- 学一个新模块,新框架第一步就是阅读官方文档。
- 不要觉得读文档费时间,认真的读一遍官方文档比你瞎折腾来得有效率。
- 阅读与你项目相关的优秀项目的源码,学习别人如何组织代码。
- 自己的解决方案不一定是最优解,不过在找到最优解之前不妨自己先试试。
- 框架模块的使用都不难,套API的活每个人都能干,只是快与慢的差别。
- 尝试思考这个API是如何实现的。
- 了解了完整的web应用是如何运作的,包括服务器,数据库,前端是如何联系在一起的。
博客首发地址:https://www.jianshu.com/u/13cd86311525
转载于:https://www.cnblogs.com/chaohangz/p/6748918.html
一个 Vue + Node + MongoDB 博客系统相关推荐
- 使用 ThinkJS + Vue.js 开发博客系统
编者注:ThinkJS 作为一款 Node.js 高性能企业级 Web 框架,收到了越来越多的用户的喜爱.今天我们请来了 ThinkJS 用户 @lscho 同学为我们分享他基于 ThinkJS 开发 ...
- 从零到一搭建一个属于自己的博客系统(弌)
前言:其实在很早之前就有这种想法了,只不过一直比较忙没有进行实践,最近写出来和大家分享分享,一起来实现一个属于自己的博客系统. 开发环境: 前端:webpack+vue, 后端:Django不懂的小伙 ...
- 基于SpringBoot和Vue的个人博客系统
基于SpringBoot和Vue的个人博客系统 前言 本期项目分享一个漫威主题的炫酷博客系统,基于SpringBoot和Vue开发的前端分离项目.博客系统分为博客前台和博客后台两部分,游客可以访问 ...
- 推荐一个基于Springboot+Vue的开源博客系统
简介 这是一个基于Springboot2.x,vue2.x的前后端分离的开源博客系统,提供 前端界面+管理界面+后台服务 的整套系统源码.响应式设计,手机.平板.PC,都有良好的视觉效果! 你可以拿它 ...
- 基于SpringBoot + Vue的个人博客系统12——使用vue-admin-template展示文章列表(后台管理)
简介 前面我们实现了博客系统的前台展示页面,还有留言功能没有实现,实现留言功能无非就是在后端增加留言表,对留言进行增删改查.和文章表类似,这里就不在赘述. 既然作为一款动态博客,那么后台管理是必不可少 ...
- 自己动手搭网站(六):javaweb搭建一个简单的个人博客系统
目录 前言 一.一点建网站的背景知识 二.个人博客系统介绍 1.核心功能和数据库 2.前端页面 3.后端 servlet service层 dao层 配置文件 参考资料 前言 这篇博主会介绍下我用ja ...
- 分享一个开源的Springboot博客系统,界面简洁精致,拿来即用
文章目录 系统简介 主要技术与框架 环境设置 页面展示 项目待优化 获取方式 系统简介 本期给大家带来一款基于Springboot的博客系统. 博客系统通过从零开始搭建整个项目,会带你了解整个开发流程 ...
- 推荐一个简洁优雅的博客系统,farbox
这是我用farbox搞的一个博客:http://www.jsnull.com/ 特点: 1.无数据库,数据存在dropbox里,需要自己注册一个dropbox帐号 2.静态文本文件即是文章,可以在任何 ...
- Node.js博客系统--1.学前要求、项目功能介绍、需求分析
本系列教程<Node.JS之"个人博客开发实战教程">你可以学会:深度了解 Nodejs+express+mongodb+mongoose,打造个人博客,娴熟掌握前台的 ...
最新文章
- 问价已损坏 文件服务器,由于检查点文件 (.chk) 丢失或已损坏,无法打开数据库...
- python基础类型
- linux日期日增,Linux日期
- 序列内置方法详解(string/list/tuple)
- 博客园模板 样式优化
- 醉酒删库:几杯红酒下肚,7小时数据消失...
- Hibernate HQL基础 投影查询
- ad电阻原理图_负载电阻的原理及应用
- Linux文件属性1——文件类型
- c 语言含移位的程序,c语言的移位练习题目.doc
- 【点阵液晶编程连载四】MenuGUI 菜单应用
- Java中常量定义在interface和class的区别(转)
- VS Code远程连接矩池云GPU主机
- html打印日志_Graylog(四)使用Log4j2发送日志到Graylog
- MES系统的功能详细以及应用价值介绍
- 不想更新计算机怎么办,联想笔记本电脑不想更新系统更新怎么办啊
- MATLAB 3d实时,MATLAB 3D 动画制作(三)- 实时随动3D动画设计
- JAVA新手,开始起航~~
- 【Android 仿微信通讯录 导航分组列表-下】自定义View为RecyclerView打造右侧索引导航栏IndexBar
- matlab中的delaunay,使用 Delaunay 三角剖分
热门文章
- 谈一谈CMU导师和学生的互动方式
- Python-OpenCV 处理图像(四)(五):图像直方图和反向投影 图像中边界和轮廓检测
- 洗牌算法shuffle
- 程序员面试题精选100题(51)-顺时针打印矩阵[算法]
- VMware Workstation中安装linux系统(CentOS)超详细
- 一个后端开发人员的node.js学习笔记(一)安装与第一个服务器
- Android:打造“万能”Adapter与ViewHolder
- 如何在 Ubuntu server 中设置 RainLoop Webmail
- OpenStack服务组件介绍
- TortoiseSVN status cache占用CPU高