likes
comments
collection
share

express-generator脚手架的使用(二)

作者站长头像
站长
· 阅读数 51

1.前文回顾

2.实现一个案例

2.1案例整体规划

  • 1. 完成 书籍列表的展示。(完成)
  • 2. 列表的分页。(完成)
  • 2.1. 一页显示10条(完成)
  • 2.2. 上一页和下一页
  • 2.3. 首页和尾页
  • 2.4. 点击页码数字,跳转(完成)
  • 3. 新增功能
  • 4.删除功能
  • 5.修改功能
  • 6. 查询功能 在列表页面中添加一个搜索框,一个搜索按钮。在搜索框中输入书名,点击搜索,进行模糊匹配。

2.2实现列表上下页

2.2.1对book.js进行改造

//进入列表页面
 book.get("/list",async (req, res) => {
  //获取页码
  let {page} = req.query;

  if (!page) {
    page = 1;
  }
   //获取数据库中的书籍数据
   let sql = `select * from book limit ${(page-1)*5},5`;
   let data = await db.query(sql);
   //获取书籍的总数
   let countSql = `select count(*) as count from book`;
   let result = await db.query(countSql);
   let count = result[0].count;
   //根据总数计算总页数。
   let totalPage = Math.ceil(count / 5);
   res.render("bookList",{data,totalPage,page});
})

2.2.2对db.js文件进行改造

//添加一个query方法
let query = function (sql) {
  return new Promise((resolve, reject) => {
    pool.getConnection((err, conn) => {
      if (err) {
        console.log(err);
        return
      }
      conn.query(sql, (err, data) => {
        if (err) {
          console.log(err);
          return
        }
        resolve(data);
        conn.release();
      })
    })
  });

}

2.2.3对bookList.ejs文件进行改造

 <h1>起点排行榜</h1>
  <div class="container"> 
    <table class="table table-hover table-bordered">
      <tbody>
        <tr class="info">
          <th>排名</th>
         <th>书名</th>
         <th>作者</th>
         <th>分类1</th>
         <th>分类2</th>
         <th>简介</th>
         <th>时间</th>
         </tr>
         <% data.forEach((item,index) => { %>
           <tr>
             <td style="width: 60px;"><%= item.ranking %></td>
             <td class="book_table"><%= item.info2 %></td>
             <td class="book_table"><%= item.author %></td>
             <td class="book_table"><%= item.category1 %></td>
             <td class="book_table"><%= item.category2 %></td>
             <td class="book_table"><%= item.info1.length>100?item.info1.slice(0,100)+"...":item.info1  %></td>
             <td class="book_table"><%= item.booktime %></td>
           </tr>
         <% }) %>
      </tbody>
    </table>
    <ul class="pagination">
      <!-- 上一页 -->
      <% if (page != 1) { %>
        <li><a href="/book/list?page=<%= page-1 %> ">&laquo;</a></li>
       <% } %>

      <!-- 动态生成页码 -->
      <% for( let i = 1; i <= totalPage; i++ ) { %>
        <li><a href="/book/list?page=<%= i %> "><%= i %> </a></li>
      <% } %>

      <!-- 下一页 -->
      <% if (page<totalPage) { %>
        <li><a href="/book/list?page=<%= Number(page)+1 %>">&raquo;</a></li>
      <% } %>
      
    </ul>
  </div>

2.2.4 运行验证

输入指令 npm run start

express-generator脚手架的使用(二) 至此列表的分页功能已经完成。

2.3用户点击添加功能

2.3.1 在booklist.ejs里面添加新增按钮

//这里a标签的路径为接下来要写的路由路径
    <a href="/book/addPage" class="btn btn-success">新增</a>

效果如下:

express-generator脚手架的使用(二)

2.3.2在book.js里面写入路由

//进入新增页面
book.get("/addPage",(req,res)=>{
  res.render("book_add") //这里的路径为接下来要写的添加页面
})

2.3.3在views新建一个book_add.ejs

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>新增书籍</title>
  <link rel="stylesheet" href="/css/bootstrap.min.css">
  <link rel="stylesheet" href="/css/book_add.css">
</head>

<body>
  <div class="container">
    <h1>新增书籍</h1>
    <form method="post" action="/book/add">
      <div class="form-group">
        <label for="exampleInputEmail1">书名</label>
        <input type="text" class="form-control" name="info2" placeholder="请输入书名">
      </div>
      <div class="form-group">
        <label>作者</label>
        <input type="text" class="form-control" name="author" placeholder="请输入作者">
      </div>
      <div class="form-group">
        <label>分类1</label>
        <select class="form-control" name="category1">
          <!-- <option value="">---请选择---</option> -->
          <option value="玄幻">玄幻</option>
          <option value="都市">都市</option>
          <option value="历史">历史</option>
          <option value="科幻">科幻</option>
          <option value="仙侠">仙侠</option>
          <option value="轻小说">轻小说</option>
          <option value="悬疑">悬疑</option>
          <option value="游戏">游戏</option>
        </select>
      </div>
      <div class="form-group">
        <label for="exampleInputEmail1">分类2</label>
        <input type="text" class="form-control" name="category2" placeholder="请输入分类">
      </div>
      <div class="form-group">
        <label for="">简介</label>
        <textarea class="form-control" name="info1" rows="6"></textarea>
      </div>
      <div class="form-group">
        <label>时间</label>
        <input type="text" class="form-control" name="booktime" placeholder="请输入时间">
      </div>
      <div class="form-group">
        <label for="">排名</label>
        <input type="number" name="ranking" class="form-control" placeholder="请输入排行">
      </div>
      <button type="submit" class="btn btn-default">提交</button>
    </form>
  </div>
</body>
</html>

界面如下:

express-generator脚手架的使用(二)

2.3.4在路由里写一个处理新增书籍的请求

//处理新增书籍的请求
book.post("/add",async(req,res)=>{
  let result = await db.insert("book",req.body);
  //判断受影响的行数如果大于0,说明新增成功,否则失败。
  if (result.affectedRows>0) {
    res.send("新增成功")
  } else {
    res.send("新增失败")
  }
})

2.3.5 运行验证

express-generator脚手架的使用(二)

express-generator脚手架的使用(二)

express-generator脚手架的使用(二)

2.4用户点击实现删除功能

2.4.1在bookList.ejs里面添加删除界面

<td><button type="button" data-id="<%= item.id%>" class="btn btn-danger btn-del">删除</button></td>

  //获取所有的删除按钮,为它们添加点击事件
    let delBtns = document.querySelectorAll(".btn-del");
    for (let i = 0; i < delBtns.length; i++) {
       delBtns[i].onclick = function () {
         //弹出确认框
         if (confirm("确认删除吗?")) {
          //发起删除请求  修改url中的地址 
          //告诉服务器,要删除的数据是哪一个
           location.href = '/book/del?id='+this.dataset.id;
         }
       }
    }

2.4.2在book.js里面添加删除响应

//实现删除功能  location.href只能发送get请求
book.get("/del",async(req,res)=>{
  // 获取id
  let {id} = req.query;
  let result = await db.del("book",{id})
  if (result.affectedRows>0) {
    res.send("删除成功")
  } else {
    res.send("删除失败")
  }
})

2.4.3 运行验证

express-generator脚手架的使用(二)

express-generator脚手架的使用(二)

2.5 用户点击实现修改功能

2.5.1 在bookList.ejs中添加修改按钮

  <button type="button" data-id="<%= item.id%>" class="btn btn-warning btn-edit">修改</button>
 //获取所有的修改按钮,为它们添加点击事件
    let editBtns = document.querySelectorAll(".btn-edit");
    for (let i = 0; i < editBtns.length; i++) {
       editBtns[i].onclick = function(){
        location.href = '/book/editPage?id=' + this.dataset.id;
       }
    }

2.5.2 新建一个删除页面的ejs文件

这里命名为 book_edit.ejs

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>修改书籍</title>
  <link rel="stylesheet" href="/css/bootstrap.min.css">
  <link rel="stylesheet" href="/css/book_add.css">
</head>

<body>
  <div class="container">
    <h1>修改书籍</h1>
    <form method="post" action="/book/edit"> 
      <div class="form-group">
        <label for="exampleInputEmail1">书名</label>
        <input type="text" class="form-control" name="info2"  value="<%= info2 %>"     placeholder="请输入书名">
      </div>
      <div class="form-group">
        <label>作者</label>
        <input type="text" class="form-control" name="author" value="<%= author %>"    placeholder="请输入作者">
      </div>
      <div class="form-group">
        <label>分类1</label>
        <select class="form-control" name="category1">
          <!-- <option value="">---请选择---</option> -->
          <option value="玄幻" <% if (category1 == "玄幻") { %> selected <% } %>>玄幻</option>
          <option value="奇幻" <% if (category1 == "奇幻") { %> selected <% } %>>玄幻</option>
          <option value="都市" <% if (category1 == "都市") { %> selected <% } %>>都市</option>
          <option value="历史" <% if (category1 == "历史") { %> selected <% } %>>历史</option>
          <option value="科幻" <% if (category1 == "科幻") { %> selected <% } %>>科幻</option>
          <option value="仙侠" <% if (category1 == "仙侠") { %> selected <% } %>>仙侠</option>
          <option value="轻小说" <% if (category1 == "轻小说") { %> selected <% } %>>轻小说</option>
          <option value="悬疑" <% if (category1 == "悬疑") { %> selected <% } %>>悬疑</option>
          <option value="游戏" <% if (category1 == "游戏") { %> selected <% } %>>游戏</option>
        </select>
      </div>
      <div class="form-group">
        <label for="exampleInputEmail1">分类2</label>
        <select class="form-control" name="category2">
          <!-- <option value="">---请选择---</option> -->
          <option value="东方玄幻" <% if (category2 == "东方玄幻") { %> selected <% } %>>东方玄幻</option>
          <option value="两宋元明" <% if (category2 == "两宋元明") { %> selected <% } %>>两宋元明</option>
          <option value="侦探推理" <% if (category2 == "侦探推理") { %> selected <% } %>>侦探推理</option>
          <option value="修真文明" <% if (category2 == "修真文明") { %> selected <% } %>>修真文明</option>
          <option value="原生幻想" <% if (category2 == "原生幻想") { %> selected <% } %>>原生幻想</option>
          <option value="古典仙侠" <% if (category2 == "古典仙侠") { %> selected <% } %>>古典仙侠</option>
          <option value="娱乐明星" <% if (category2 == "娱乐明星") { %> selected <% } %>>娱乐明星</option>
          <option value="幻想修仙" <% if (category2 == "幻想修仙") { %> selected <% } %>>幻想修仙</option>
          <option value="异世大陆" <% if (category2 == "异世大陆") { %> selected <% } %>>异世大陆</option>
          <option value="异术超能" <% if (category2 == "异术超能") { %> selected <% } %>>异术超能</option>
          <option value="时空穿梭" <% if (category2 == "时空穿梭") { %> selected <% } %>>时空穿梭</option>
          <option value="现代修真" <% if (category2 == "现代修真") { %> selected <% } %>>现代修真</option>
          <option value="现代魔法" <% if (category2 == "现代魔法") { %> selected <% } %>>现代魔法</option>
          <option value="神话修真" <% if (category2 == "神话修真") { %> selected <% } %>>神话修真</option>
          <option value="秦汉三国" <% if (category2 == "秦汉三国") { %> selected <% } %>>秦汉三国</option>
          <option value="衍生同人" <% if (category2 == "衍生同人") { %> selected <% } %>>衍生同人</option>
          <option value="诡秘悬疑" <% if (category2 == "诡秘悬疑") { %> selected <% } %>>诡秘悬疑</option>
          <option value="进化变异" <% if (category2 == "进化变异") { %> selected <% } %>>进化变异</option>
          <option value="都市异能" <% if (category2 == "都市异能") { %> selected <% } %>>都市异能</option>
          <option value="高武世界" <% if (category2 == "高武世界") { %> selected <% } %>>高武世界</option>
        </select>
      </div>
      <div class="form-group">
        <label for="">简介</label>
        <textarea class="form-control" name="info1" rows="6"><%= info1 %></textarea>
      </div>
      <div class="form-group">
        <label>时间</label>
        <input type="text" class="form-control" name="booktime" value="<%= booktime %>"  placeholder="请输入时间">
      </div>
      <div class="form-group">
        <label for="">排名</label>
        <input type="number" name="id" class="form-control"  value="<%= id %>"   placeholder="请输入排行">
      </div>
      <button type="submit" class="btn btn-default">提交</button>
    </form>
  </div>
</body>

</html>

界面如下:

express-generator脚手架的使用(二)

2.5.3 在路由里添加修改功能

//实现修改功能
book.post("/edit",async(req,res)=>{
  //获取传递过来的参数
  let editBook = req.body;
  //实现修改功能
  let result = await db.update("book",editBook,{id:editBook.id});
  if (result.affectedRows>0) {
    res.send("修改成功")
  } else {
    res.send("修改失败")
  }
})

2.5.4 运行验证

express-generator脚手架的使用(二)

express-generator脚手架的使用(二)

express-generator脚手架的使用(二) 至此大功告成!

2.6 用户点击实现搜索功能

2.6.1 在bookList.ejs添加搜索样式

<form class="form-inline" action="/book/list" method="get">
      <div class="form-group">
        <label for="searchBox">书名:</label>
        <input type="text" value="<%= bookName %>" class="form-control" id="searchBox" name="bookName">
      </div>
      <button type="submit" class="btn btn-default">查询</button>
    </form>

2.6.2 修改路由里的book.js文件

 //定义获取书籍数据的sql  只定义好了一部分。
  let sql = `select * from book`
  //定义查询所有书籍数量的SQL
  let countSql = `select count(*) as count from book`;

  if (bookName) {
    sql += ` where info2 like '%${bookName}%'`
    countSql += ` where info2 like '%${bookName}%'`
  }

  sql+= ` limit ${(page-1)*5},5`
  
  //完成拼接,去执行sql

  let data = await db.query(sql);
  let result = await db.query(countSql);
  let count = result[0].count;
  //根据总数计算总页数。
  let totalPage = Math.ceil(count / 5);
  //bookName 是为了分页时,点击分页标签不会出现查询错误。
  res.render("bookList",{data,totalPage,page,bookName});
})

2.6.3 运行验证

express-generator脚手架的使用(二)

2.7 整体效果图

express-generator脚手架的使用(二)

总结

查询的流程

localhost:3000/book/list

用户地址栏输入地址 域名+端口 (localhost:3000),发生了一个请求 => 找到nodeJs启动的服务 => 根据端口后面跟着的 URL 找到匹配的路由 (/book/list) => 获取参数(page) 查询数据库 得到数据列表 => 逻辑处理 => 响应一个页面给浏览器 (res.render(要响应的页面,页面中需要的数据)) => 响应的字符串渲染成可视化的页面。

新增页面中点击提交按钮

=> form表单将用户输入的值,提交到action中的地址上,参数的键是表单元素中的name。 => form表单发起了一个请求。 => 找到对应的服务,找到对应的路由。 => 获取参数,进行逻辑处理(数据库的操作) => 响应一个结果给浏览器 => 浏览器解析响应结果展示。

转载自:https://juejin.cn/post/7044479073569112095
评论
请登录