如果你觉得这篇文章帮助到了你,那就赏脸给个star吧, https://github.com/Ningjunhua/mini-blog
开发环境
- nodejs
v8.1.0
- koa
v2.3.0
- mysql
v5.7.0
准备工作
文中用到了promise、async await等语法,所以你需要一点es6的语法,传送门当然是阮老师的教程了http://es6.ruanyifeng.com/
如果你已经配置好node和mysql可以跳过
|
|
下载mysql,并设置好用户名和密码,默认可以为用户名:root,密码:123456
|
|
然后开启mysql
|
|
输入密码之后创建database
(数据库),nodesql
是我们创建的数据库
|
|
记住sql语句后面一定要跟;
符号,接下来看看我们创建好的数据库列表
|
|
启用创建的数据库
|
|
|
|
显示Empty set (0.00 sec)
,因为我们还没有建表,稍后会用代码建表
注释:
这是后面建表之后的状态
目录结构
- config 存放默认文件
- lib 存放操作数据库文件
- middlewares 存放判断登录与否文件
- public 存放样式文件
- routes 存放路由文件
- views 存放模板文件
- index 程序主文件
- package.json 包括项目名、作者、依赖等等
首先我们创建koa2-blog文件夹,然后cd koa2-blog
|
|
接着安装包,安装之前我们使用cnpm安装
|
|
|
|
各模块用处
koa node
框架koa-bodyparser
表单解析中间件koa-mysql-session
、koa-session-minimal
处理数据库的中间件koa-router
路由中间件koa-static
静态资源加载中间件ejs
模板引擎md5
密码加密moment
时间中间件mysql
数据库koa-views
模板呈现中间件
在文件夹里面新建所需文件
首先配置config
我们新建default.js
文件
|
|
这是我们所需的一些字段,包括端口和数据库连接所需,最后我们把它exports暴露出去,以便可以在别的地方使用
配置index.js文件
index.js
|
|
我们使用koa-session-minimal``koa-mysql-session
来进行数据库的操作
使用koa-static
配置静态资源,目录设置为public
使用ejs
模板引擎
使用koa-bodyparser
来解析提交的表单信息
使用koa-router
做路由
之前我们配置了default.js,我们就可以在这里使用了
首先引入进来 var config = require(‘./config/default.js’);
然后在数据库的操作的时候,如config.database.USERNAME,得到的就是root。
如果你觉得这篇文章帮助到了你,那就赏脸给个star吧,https://github.com/wclimb/Koa2-blog
配置lib的mysql.js文件
关于数据库的使用这里介绍一下,首先我们建立了数据库的连接池,以便后面的操作都可以使用到,我们创建了一个函数query
,通过返回promise的方式以便可以方便用.then()
来获取数据库返回的数据,然后我们定义了三个表的字段,通过createTable
来创建我们后面所需的三个表,包括posts(存储文章),users(存储用户),comment(存储评论),create table if not exists users()表示如果users表不存在则创建该表,避免每次重复建表报错的情况。后面我们定义了一系列的方法,最后把他们exports暴露出去。
这里只介绍注册用户insertData,后续的可以自行查看,都差不多
|
|
我们写了一个_sql的sql语句,意思是插入到users的表中(在这之前我们已经建立了users表)然后要插入的数据分别是name和pass,就是用户名和密码,后面values(?,?)意思很简单,你有几个值就写几个问号,最后调用query
函数把sql语句传进去
lib/mysql.js
|
|
下面是我们建的表
users | posts | comment |
---|---|---|
id | id | id |
name | name | name |
pass | title | content |
content | postid | |
uid | ||
moment | ||
comments | ||
pv |
- id主键递增
- name: 用户名
- pass:密码
- title:文章标题
- content:文章内容和评论
- uid:发表文章的用户id
- moment:创建时间
- comments:文章评论数
- pv:文章浏览数
- postid:文章id
现在感觉有点枯燥,那我们先来实现一下注册吧
实现注册页面
routers/singup.js
|
|
使用get方式得到’/signup’页面,然后渲染signup模板,这里我们还没有在写signup.ejs
views/signup.ejs
|
|
我们先安装supervisor
|
|
supervisor的作用是会监听文件的变化,而我们修改文件之后不必去重启程序
|
|
现在访问 localhost:3000/signup 看看效果吧。注意数据库一定要是开启的状态,不能关闭
完善注册功能
首先我们来完善一下样式吧,稍微美化一下
public/index.css
|
|
我们再把模板引擎的header和footer独立出来
/views/header.ejs
顺便引入index.css和jq
|
|
/views/footer.ejs
|
|
修改views/signup.ejs
|
|
修改routers/signup.js
|
|
- 我们使用md5实现密码加密
- 使用我们之前说的
bodyParse
来解析提交的数据,通过ctx.request.body
得到 - 我们引入了数据库的操作 findDataByName和insertData,因为之前我们在/lib/mysql.js中已经把他们写好,并暴露出来了。意思是先从数据库里面查找注册的用户名,如果找到了证明该用户名已经被注册过了,如果没有找到则使用insertData增加到数据库中
- ctx.body 是我们通过ajax提交之后给页面返回的数据,比如提交ajax成功之后
msg.data=1
的时候就代表用户存在,msg.data
出现在后面的signup.ejs
模板ajax请求中
我们使用ajax来提交数据,方便来做成功错误的处理
模板引擎ejs
我们使用的是ejs,语法可以见ejs官网
之前我们写了这么一段代码
|
|
这里就用到了ejs所需的session 我们通过渲染signup.ejs模板,将值ctx.session赋值给session,之后我们就可以在signup.ejs中使用了
ejs的常用标签为:
<% code %>
:运行 JavaScript 代码,不输出<%= code %>
:显示转义后的 HTML内容<%- code %>
:显示原始 HTML 内容
<%= code %>
和<%- code %>
的区别在于,<%= code %>不管你写什么都会原样输出,比如code为<strong>hello</strong>
的时候 <%= code %>
会显示<strong>hello</strong>
而<%- code %>
则显示加粗的hello
修改/views/signup.ejs
|
|
这里重点就在于ajax提交了,提交之后换回数据 1 2 3,然后分别做正确错误处理,把信息写在error和success中
修改/views/header.ejs
我们之前在/routers/signup.js get ‘/signup’ 中 向模板传递了session参数 session:ctx.session,存取的就是用户的信息,包括用户名、登录之后的id等,之所以可以通过ctx.session获取到,因为我们在后面登录的时候已经赋值 如ctx.session.user=res[0][‘name’]
|
|
我们可以看到,如果不存在用户,则只显示全部文章
注册
登录
,如果session.user存在则有登出的按钮
我们可以看到当状态data为 3 的时候window.location.href=”/signin”
为了方便跳转,我们先简单实现一下signin页面
修改 /routers/signin.js
|
|
修改 /views/signin.ejs
|
|
修改 index.js 文件 把下面这段代码注释去掉,之前注释是因为我们没有写signin的路由,以免报错,后面还有文章页和登出页的路由,大家记住一下
|
|
现在注册一下来看看效果吧
|
|
我们怎么查看我们注册好的账号和密码呢?打开mysql控制台
|
|
如果你觉得这篇文章帮助到了你,那就赏脸给个star吧,https://github.com/wclimb/Koa2-blog
登录页面
修改signin
routers/signin.js
|
|
我们进行登录操作,判断登录的用户名和密码是否有误,使用md5加密
我们可以看到登录成功返回的结果是result
然后处理一下 var res=JSON.parse(JSON.stringify(result))
为什么呢?
因为返回的结果是这样的一个数组:id:4 name:rrr pass:…
[ RowDataPacket { id: 4, name: ‘rrr’, pass: ‘44f437ced647ec3f40fa0841041871cd’ } ]
修改views/signin.ejs
signin.ejs
|
|
我们增加了ajax请求,在routers/singin.js里,我们设置如果登录失败就返回false,登录成功返回true
|
|
那我们登录成功后要做跳转,可以看到window.location.href="/posts"
跳转到posts页面
全部文章
修改routers/posts.js
posts.js
|
|
修改 index.js
app.use(require(‘./routers/posts.js’).routes())的注释去掉
修改 views/posts.ejs
|
|
现在看看登录成功之后的页面吧
接下来我们事先登出页面
登出页面
修改 router/signout.js
signout.js
|
|
把session设置为null即可
修改 index.js
app.use(require(‘./routers/posts.js’).routes())的注释去掉,现在把注释的路由全部取消注释就对了
然后修改 views/header.ejs
|
|
增加点击登出后的ajax 的提交,成功之后回到posts页面
发表文章
修改router/posts
在后面增加
|
|
修改 views/create.ejs
create.ejs
|
|
现在看看能不能发表吧
即使我们发表了文章,但是当前我们的posts的页面没有显示,因为还没有获取到数据
接下来
修改 routers/posts.js
修改 get ‘/posts’
|
|
if (ctx.request.querystring) {}这部分我们先不用管,后面会说。只需要看else后面的代码我们查找我们发表的全部文章然后将获取到的值定义为posts,传给模板posts.ejs,这样就可以渲染出来了
修改 Views/posts.ejs
posts.ejs
|
|
现在看看posts页面有没有文章出现了
我们看到是所有的文章,但是我需要点击单篇文章的时候,显示一篇文章怎么办呢?
修改 routers/posts.js
在posts.js后面增加
|
|
现在的设计是,我们点进去出现的url是 /posts/1 这类的 1代表该篇文章的id,我们在数据库建表的时候就处理了,让id为主键,然后递增
我们通过userModel.findDataById 文章的id来查找数据库
我们通过userModel.findCommentById 文章的id来查找文章的评论,因为单篇文章里面有评论的功能
单篇文章页
修改 views/sPost.ejs
sPost.ejs
|
|
现在点击单篇文章试试,进入单篇文章页面,但是编辑、删除、评论都还没有做,点击无效,我们先不做,先实现每个用户发表的文章列表,我们之前在 get ‘/posts’ 里面说先忽略if (ctx.request.querystring) {}里面的代码,这里是做了应该处理,假如用户点击了某个用户,该用户发表了几篇文章,我们需要只显示该用户发表的文章,那么进入的url应该是 /posts?author=xxx ,这个处理在posts.ejs 就已经加上了,就在文章的左下角,作者:xxx就是一个链接。我们通过判断用户来查找文章,继而有了ctx.request.querystring
获取到的是:author=XXX
注:这里我们处理了,通过判断 session.user === res['name']
如果不是该用户发的文章,不能编辑和删除,评论也是。这里面也可以注意一下包裹的<a href=""></a>
标签
编辑文章、删除文章、评论、删除评论
评论
修改routers/posts.js
在post.js 后面增加
|
|
现在试试发表评论的功能吧,之所以这样简单,因为我们之前就在sPost.ejs做了好几个ajax的处理,删除文章和评论也是如此
删除评论
修改routers/posts.js
继续在post.js 后面增加
|
|
现在试试删除评论的功能吧
删除文章
只有自己发表的文字删除的文字才会显示出来,才能被删除,
修改routers/posts.js
继续在post.js 后面增加
|
|
现在试试删除文章的功能吧
编辑文字
修改routers/posts.js
继续在post.js 后面增加
|
|
修改views/edit.js
|
|
现在试试编辑文字然后修改提交吧