使用koa+mysql写一个简易论坛(二)

首先,感谢 夕雅y的“❤️”。

上篇文章因为没有评论,我并不知道反响如何,不知道这种写作方式对于读者来说是否适合,也没有读者的建议给我参考,让我改进我的写作方式,但是我从一个“大佬”哪里得到了一些建议,我将在今后的文章中将其运用起来:

1、 每一段代码不光要有注释,还应该加上自己的想法,解决思路等
2、 写一些自己在项目中遇到的坑,并且详细的阐述自己的思考过程和最终解决办法

好了,扯的废话也不少了,下面进入本篇文章的正文

一、本期目标及知识点概况

1. 目标概括
  • 使用bootstrap4 + koa-ejs 搭建论坛的首页、用户注册与登录界面
  • 使用koa-router实现界面之间的相互跳转
2. 主要涉及到的知识点:
  • 模版引擎的使用  ==> koa-ejs

https://github.com/koajs/ejs

  • 路由模块的使用 ==> koa-router

https://github.com/ZijianHe/koa-router

  • bootstrap4

中文文档 ==> https://www.qdskill.com/docs/bootstrap/docs/4.0/getting-started/introduction/
英文文档 ==> https://getbootstrap.com/docs/4.3/getting-started/introduction/

二、准备工作

1、 目录及文件

在项目根目录新建两个文件夹 ==>

  • routes ---- 存放路由文件
  • views ----存放.html文件
  • 在views目录下新建index.html文件作为论坛主页
  • 在views目录下新建layouts目录,用来存放模版文件
  • 在views目录下新建partials目录,存放导航条
  • 在views目录下新建signUpIn目录,用来存放登录注册界面的html文件

下图是本期项目在Webstorm中的目录结构


2. 中间件的安装与引用

  • 打开终端,进入项目目录:

npm install koa-router
npm install koa-ejs

  • 编辑器打开app.js文件,在页首输入:

cosnt render = require('koa-ejs);

  • 在routes目录下新建index.js文件,打开并输入:

const router = require('koa-router');

3、bootstrap4的使用

https://www.qdskill.com/docs/bootstrap/docs/4.0/getting-started/introduction/

直接进入打开链接,将如图所示部分代码拷贝到你的layout.html文件中,如图:

image.png

PS:其实为了美观的话也可以将<body>里的是三个<script>里的内容写到<head>标签里面,虽然这样可能会影响一点速度,因为这种引用方式是需要网络的,不过你可以将文件下载下来,直接从本地引用就没有这个问题了。在这里,我使用的是上面这种引用方式,但将<script>里的内容移到了<head>里。

4. 目标预览

我们这一期的目标是:
1、首页 ==> 顶部是导航条,中间是正文部分(无内容),底部暂时用不到,如图。

index.png

在上图中我将正文部分分为了2个区域,左边准备用来显示帖子、右边显示个人信息及其它的一些东东。具体的页面布局使用了bootstrap4

2、注册与登录界面(暂时不写注册与登录的功能),如图:

signUp.png

signIn.png

PS:看到这两张图是不是感觉很熟悉? 没错,这就是“照抄”Github的登录界面的,就连图标都没换,当然你也可以自己设计。

三、koa-ejs模版引擎

  • 初学者可能无法很快理解这个东东(也不排除有牛人),不知道它是干什么的、怎么使用,当然,这很正常,因为我当初也这样,一脸懵逼,不知道语法怎么写,后来用的多了再结合一下官方文档,才逐渐熟悉。这个东西倒其实不是很难,用几次很快就能懂个大概。

下面我来说说我对模版引擎的理解吧,希望这会对读者们有所帮助 == >

1、众所周知: 在一个大型Web项目里是有着很多很多的网页的,而大部分网页跟网页之间又存在着很多 相同 的部分,这样的案例在生活中是随处可见的
2、程序员有一个很重要的优点-----懒,当然不了解的人可能会觉得很奇怪,为什么“懒”也可以是优点了,难道是世界变了?工作时偷懒不会被吊(骂)?当然不是,此懒非彼懒,程序员的懒在于:当有一个功能或者一段代码块需要使用2遍或以上,那我们就将其封装起来,便于多次使用,因为懒,才能优化,想要偷懒就得进步。
3、结合以上两点,模版引擎的作用其实也就出来十之八九了:
==> 它就是用来保存我们网页中的公有内容的。当我们有很多个页面有着相同的地方,那么把它写到一个模版文件里吧,要用的时候只需要使用特定的模版引擎语法直接调用就可以了。

4、模版引擎的作用都差不多,区别应该只是语法不同,而koa-ejs的语法是:

  • 引入

<%- %>

例如:当我们要将index.html的body包含在layout.html中的<div class="container"></div> 中
就可以在b.html中这样写 ==>

<div class="container">
  <%-  body %>
</div>

PS: 而在index.html中我们就可以省略<head>等其它内容,只写body里的东西,并且也不需要加一个<body>标签

  • 赋值

<%= %>

我们可以给一个指定页面(index.html)传数据,例如传一个 user(user === ' Tom '), 如果我们想将 user 的值 传给传到 <p></p>里,可以这样写:

<p> <%= user  %> </p>

当然我们也可以写各种循环语句,判断语句什么的 ==>

例1:
普通JS --> if....else....

if (a === 1) {
    console.log('早上好');
} else {
    console.log('晚上好');
}

模版语法 -->:

<% if(a === 1) { %>
    console.log('早上好');
<% } else { %>
    console.log('晚上好');
<% } %>        

例2: 数组遍历
假如我们有数组array,我们要遍历打印每一个元素到控制台:
普通的方法:

array.forEach(a => {
   console.log(a);
})

模版语法:

<% array.forEach(a => { %>
    console.log(a); 
<% }) %>

备注: 当然,这里不用forEach,使用for循环也是可以的

koa-ejs的具体使用方法(项目文件中也有):

// 安装
npm install koa-ejs
// 引包
const render = require('koa-ejs');
// 配置
render(app, {  //app就是前面实例化的Koa==>  const app = new Koa();
 //这一行配置的是模版引擎的路径,__dirname:获得当前执行文件所在目录的完整目录名,views 就是之前创建的那个文件夹了
   root: path.join(__dirname, 'views'), 
// 设置默认的模版文件为layouts目录下的layout文件,如果你不指定模版就会使用这个
   layout: 'layouts/layout',
//格式为html
   viewExt: 'html',
//cache: 是否缓存编译模版,默认为true,这里设为false,不缓存
   cache: false,
//调试标记,默认为false
   debug: false
});
5. koa-ejs还支持include引入文件:

例如,在本项目中我们就需要将导航栏引入布局文件layout.html中,
==>


image.png

四、koa-router

1、下面的是官方的解释

Router middleware for koa
---> 针对koa框架的路由中间件

  • Express-style routing using app.get, app.put, app.post, etc.
  • Named URL parameters.
  • Named routes with URL generation.
  • Responds to OPTIONS requests with allowed methods.
  • Support for 405 Method Not Allowed and 501 Not Implemented.
  • Multiple route middleware.
  • Multiple routers.
  • Nestable routers.
  • ES7 async/await support.
    不知道你们看到这一大串英文是什么样的感受,反正我是不怎么想看的。不过我们也不需要看这些,我们需要知道的是如何使用它:

2、官方给出的基本用法


image.png

在我们这个项目中,一半就只需要用到get和post请求,所以其它的我也没怎么用过,不过应该都差不多。

==>

Get请求:

假定我们的目标是在主页点击注册按钮,然后页面跳转到注册页面,那么==>

需要在导航栏上的 <a>注册</a> 上添加href属性,例如


image.png

然后在路由模块(即本项目中routes目录下的index.js文件)中这样写==>


image.png

PS:请注意,上面两张图中使用红色方框圈住的路径内容必须相等,而且它就是在浏览器地址栏中显示的地址,只不过在它们前面还得加个前缀,例如:
因为我们是在本机上启动的服务,所以注册页面的地址就是 --->

http://localhost:3000/signUp

一般来说我们想要有几个跳转的页面就得写几个路由,包括请求主页。在本期中我们总共有三个页面需要跳转,所以路由模块应有三个请求,即:


index.png

Post请求

其实post跟get差不多,只不过post相比于get多了一个表单提交及数据处理==>
关于表单 form ==>


image.png

1、action中的地址应该填写你 提交数据的目标页面
2、method 就是提交方式,本项目中写post就可以了,想知道别的HTTP请求可以去学习一下HTTP相关知识,挺重要的

MDN https://developer.mozilla.org/zh-CN/docs/Web/HTTP

然后我们如何在后段接收表单提交的数据呢? 可以在input输入框中增加一个name="xxx" 的属性,然后我们需要根据这个来获取用户在输入框中输入的值。
假设我们有这样的一个表单


image.png

我暂时把它放在主页(index.html文件中), 其
action="/" --> 提交数据到主页
method="post" --> 方法为post


image.png

那么现在我们可以得到上图的这样一个东西(一个输入框,一个提交按钮),不好看但请不要在意这些细节,我们现在要完成的东西就是 ==>

在输入框中输入一些内容,例如 Koa 然后点击提交,我们能在后端拿到Koa这个字符串,所以我们现在要去路由模块index.js中写一些东西了 ==>

router.post("/", async (ctx) => {
    const title = ctx.request.body.title;
    console.log(title);
});
image.png

如图所示,在输入框中输入koa,然后点击提交,会跳转到下图所示界面,不要管它,这是正常的,因为我们并没有在post请求里写别的东西,使提交结束后页面跳转到其它地方

image.png

image.png

好了,post请求的基础东西大概也就这么多了,如果你想看一下请求的body的内容,可以把ctx.request.body.title中的title去掉,同理你也可以将body去掉看整个请求的内容。

我这里使用的编辑器是WebStorm ,我们可以免费使用一个月,如果之后还想再用就得花钱了,而且不便宜。它自带终端,有时候会显得比较方便,当然VScode也是带终端的,并且完全免费,也可以考虑这个。如果不想用工具自带的终端,本机的终端当然也是可以的了,只不过你需要手动cd进入到你的工作目录而已。

下期预告

  • 用户的注册与登录(包括数据库操作)
  • 帖子的发表
  • 主页子论坛和帖子的展示
    这些内容好像有点多,先这样计划吧,具体写多少到时候再说,我尽量写完。如果每次写这么多的话,大概还有个3、4篇文章大概也就差不多了。

结束语

好了,本篇文章到这里也就结束了,源代码我会上传到我的Github

文章代码同步仓库
https://github.com/ShyGodB/Forum-Code-Synchronize-

我自己的项目仓库
https://github.com/ShyGodB/BBS-by-Koa-Mysql

推荐阅读更多精彩内容