nodejs3:koa框架全解

基本使用

依次执行命令
创建配置与说明JSON

npm init --y

下载koa框架

npm i koa

服务器逻辑

// 引入Koa类
const Koa = require("koa");
// 实例化koa类
const app = new Koa();

// ctx === context
app.use((ctx) => {
    ctx.body = "hello world";
});

app.listen(8080);

属性说明:

  1. ctx:context 上下文对象
  2. 请求对象,响应对象:ctx.request、ctx.response
  3. res,req:ctx.rex,ctx,req
  4. ctx.response.body简写为ctx.body
  5. body可接对象并自动转为json格式渲染

状态码的使用

302 临时重定向

  1. 设置返回的状态码ctx.status =
  2. 设置响应头,跳转到location字段中的地址去
app.use((ctx) => {
    // 设置返回的状态码
    ctx.status = 302;
    // 设置响应头
    ctx.set("location", "https://www.baidu.com");
});

内置对象总览

在这里插入图片描述

中间件

Koa 利用中间件 控制"上游",调用"下游“,通过next()将控制转交给另一个中间件
以下代码的执行顺序是什么

app.use((ctx, next) => {
    ctx.body = "first";
    next();
    console.log("first执行完毕");
});

app.use((ctx, next) => {
    ctx.body = "second";

    next();
    console.log("second执行完毕");
});
app.use((ctx) => {
    ctx.body = "third";

    console.log("third执行完毕");
});

app.listen(8080);

在这里插入图片描述
这就是中间件的洋葱模型,可以通过递归理解
在这里插入图片描述
异步写法

const Koa = require("koa");
const app = new Koa();

app.use(async (ctx, next) => {
    ctx.body = "first";
    await next();
    console.log("first执行完毕");
});
app.use(async (ctx, next) => {
    ctx.body = "second";
    await delay();
    console.log("second执行完毕");
});
function delay() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve();
        }, 2000);
    });
}
app.listen(8080);

中间件-router

  • 在未使用路由的原生js时代,判断不同路径做出不同处理很麻烦并且不美观,需要n多个if else 来实现
  • 路由是引导匹配之意,是匹配url到相应处理程序的活动。

安装

npm i koa-router

基本使用

const Koa = require("koa");
const Router = require("koa-router");

const app = new Koa();
const router = new Router();

// 重定向
router.redirect("/home", "/");

router.get("/", (ctx) => {
    ctx.body = "hello koa router";
});
router.get("/users/:id", (ctx) => {
    const { id } = ctx.params;
    ctx.body = `userID: ${id}`;
});

app.use(router.routes());

app.listen(8080);

RESTfull架构

  • 一般增删改查的实现
    通过写add,update,remove等函数实现

  • RESTfull风格则通过http请求语义化实现

    get
    post
    put
    delete
    
  • REST设计一般符合如下条件:

    • 程序或者应用的事物都应该被抽象为资源
    • 每个资源对应唯一的URI(uri是统一资源标识符)
    • 使用统一接口对资源进行操作
    • 对资源的各种操作不会改变资源标识
    • 所有操作都是无状态的

在这里插入图片描述

RESTfull api

数据

let users = [
    {
        id: 1,
        name: "小红",
        age: 19
    },
    {
        id: 2,
        name: "小明",
        age: 20
    },
];

router.get("/users/:id", (ctx) => {
    const { id } = ctx.params;
    const user = users.find((data) => data.id == id);
    ctx.body = user;
    console.log(user);
});

在这里插入图片描述
在这里插入图片描述

增, 通过postman工具模拟post请求

在这里插入图片描述

router.post("/users/", (ctx) => {
    const { id, name, age } = ctx.request.body;
    const user = {
        id,
        name,
        age
    };
    users.push(user);
    ctx.body = users;
    console.log(users);
});

改 put

router.put("/users/", (ctx) => {
    const { id, name, age } = ctx.request.body;
    const user = users.find((data) => data.id == id);
    if (name) {
        user.name = name;
    }
    if (age) {
        user.age = age;
    }
    ctx.body = user;
});

在这里插入图片描述

删除 delete

router.del("/users/:id", (ctx) => {
    const {id} = ctx.params;
    users = users.filter((data) => data.id != id);
    ctx.body = users;
})

在这里插入图片描述

中间件-koa-views

Koa-views用于加载html模板文件;

  • 安装 koa-views npm i koa-views -S
  • 安装 pugnpm i pug
const Koa = require("koa");
const views = require("koa-views");

const app = new Koa();
app.use(views(__dirname + "/views"), {
    extension: "pug"
});

app.use(async (ctx) => {
    await ctx.render("index", {
    	// msg将会通过变量的形式传入pug模板引擎中
        msg: "hello world"
    });
});

app.listen(8080);

快速查看GitHub源码的命令

npm repo xxx

中间件 koa-static

  • koa-static 是用于加载静态资源的中间件,通过它可以加载css、js等静态资源;

  • 安装 koa-static

    npm i koa-static

  • 使用koa-static

    const static = require("koa-static");
    app.use(static(__dirname+"/static")) //加载静态文件的目录
    

实例 serve的第二个参数是配置,可以配置默认的html文件入口

const Koa = require("koa");
const serve = require("koa-static");

const app = new Koa();
const serveOptions = {
  index: "main.html",
};
app.use(serve(__dirname + "/static", serveOptions));

app.listen(8080);

koa + pug 重写新闻页面

搭建主逻辑

所需配置

npm i koa koa-router koa-static koa-views pug

实例化

const Koa = require("koa");
const Router = require("koa-router");
const serve = require("koa-static");
const views = require("koa-views");

const news = require("./router/news");
const detail = require("./router/detail");

const app = new Koa();
const router = new Router();

配置静态文件夹

app.use(serve(__dirname + "/static"));

配置视图模板文件夹

app.use(views(__dirname + "/views", {
    extension: "pug",
}));

根据单一职责模式,配置各个路由,最后监听

router.redirect("/news", "/");
router.get("/", news);
router.get("/detail", detail);

app.use(router.routes());	/*启动路由*/

app.listen(8080);

进入news页面测试下是否成功

在这里插入图片描述
在这里插入图片描述
成功显示,进行下一步

渲染全部页面

先渲染所有数据试试,render整个data

const newsData = require("../data/data.json");

module.exports = async (ctx) => {
  await ctx.render("index", {
    newsData: newsData
  })
};
doctype html
html(lang='en')
  head
    meta(charset='UTF-8')
    meta(name='viewport' content='width=device-width, initial-scale=1.0')
    meta(http-equiv='X-UA-Compatible' content='ie=edge')
    title 新闻
    link(rel='stylesheet' type='text/css' href='views/css/index.css')
  body
    .wrap
      ul.news-list
      each data in newsData
        li.news
          a(href='javascript:;')
            img(src=data.imgUrl alt='')
          div
            h3
              a(href='javascript:;') #{data.title}
            .info
              span.tips
                span #{data.from}
              span.time |   #{data.newTime}
      .pagination
        a.prev(href='javascript:;')a(href='javascript:;') 1
        a(href='javascript:;') 2
        a(href='javascript:;') 3
        a(href='javascript:;') 4
        a(href='javascript:;') 5
        a.next(href='javascript:;')

成功拿到所有数据并渲染,接下来渲染css
因为设置了static,所以直接引入static文件夹下的css,前面会自动拼接

link(rel='stylesheet' type='text/css' href='css/index.css')

处理分页逻辑

数据存储的格式是数组,所以可以通过slice截取数组内的数据,然后传入模板中进行渲染

module.exports = async (ctx) => {
  const curPageData = getCurNewsData();
  await ctx.render("index", {
    newsData: curPageData
  });
};

function getCurNewsData() {
  return newsData.slice(0, 5);
}

在这里插入图片描述
截取成功!
现在设置分页路由,需要在后面拼接?p=index
设置一个全局变量:当前页:curPageIndex,进行分页处理

const pageSize = 5;
let curPageIndex;
module.exports = async (ctx) => {
  curPageIndex = +ctx.query.p || 1;	// 默认值为1
  console.log(ctx.query.p)
  const curPageData = getCurNewsData();
  await ctx.render("index", {
    newsData: curPageData
  });
};

function getCurNewsData() {
  const start = curPageIndex * pageSize;
  const end = start + pageSize;
  console.log(start)
  return newsData.slice(start, end);
}

在这里插入图片描述
成功!
现在设置底部切换分页按钮
将当前页p、总页数pageCnt、传入模板

  const pageCnt = Math.ceil(newsData.length / pageSize)
  await ctx.render("index", {
    newsData: curPageData,
    pageCnt,
    p: curPageIndex
  });
 .pagination
    a.prev(href='/?p=' + (Math.max(p - 1, 1)))- for (let i = 1; i<pageCnt;i++)
      a(href="/?p="+i) #{i}
    a.next(href="/?p="+(Math.min(p+1,pageCnt)))

成功!

处理详情页

逻辑很简单,直接通过a标签拼接的数据唯一标识id,返回对应数据,然后做出渲染

const newsData = require('../data/data.json');
module.exports = async (ctx) => {
  // 获取数据
  const id = +ctx.query.id;
  const currentPageData = getCurrentPageDataById(id);
  await ctx.render("detail", {
    data: currentPageData
  });
};

function getCurrentPageDataById(id) {
  return newsData.find((data) => data.id === id);
}

pug模板


doctype html
html(lang="en")
  head
    meta(charset="UTF-8")
    meta(name="viewport" content="width=device-width, initial-scale=1.0")
    meta(http-equiv="X-UA-Compatible" content="ie=edge")
    title Document
    link(rel="stylesheet" type="text/css" href="css/detail.css")
  body
    .text
      h1.title #{data.title}
      .article-info  #{data.from}: #{data.newTime}
      p.content #{data.title}


在这里插入图片描述
项目成功完成

展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 1024 设计师: 上身试试
应支付0元
点击重新获取
扫码支付

支付成功即可阅读