node 后端渲染案例(分享)

1. 案例分析

  • 该案例主要采用后端渲染数据
  • 前端部分:html、css、js、bootstrap
  • 后端部分:node.js
  • 框架:express
  • 模板引擎:art-template、express-art-template
  • 数据库:mysql

2. 案例效果

2.1 主页(唯一页面)

在这里插入图片描述

2.2 添加模态框

在这里插入图片描述

2.3 修改模态框

点击修改按钮时,会包含姓名和台词
在这里插入图片描述

2.3 删除模态框

在这里插入图片描述

3. 代码片段

3.1 目录结构

在这里插入图片描述

3.2 首页、异常页
<!-- 首页 -->
<!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/index.css">
  <link rel="stylesheet" href="./css/bootstrap.min.css">
</head>
<body>
  <div class="container">
    <div class="row">
      <div class="col-1"></div>
      <div class="col-10 border box">
        <div class="row header">
          <span class="text-center">王者荣耀英雄信息</span>
        </div>
        <div class="row">
          <form action="searchInfo" method="post" class="row g-3">
            <div class="col-auto username">
              <label for="inputUsername">名称</label>
            </div>
            <div class="col-auto">
              <input type="text" class="form-control" id="inputUsername" placeholder="名称" name="name">
            </div>
            <div class="col-auto">
              <button type="submit" class="btn btn-primary mb-3">搜索</button>
            </div>
            <div class="col-auto">
              <!-- 添加按钮 -->
              <button type="button" class="btn btn-success mb-3" data-bs-toggle="modal"
                data-bs-target="#addModal">添加</button>
            </div>
          </form>
        </div>
        <div class="row">
          <table class="table" text-align="center">
            <thead style="background-color: #dfefd7;">
              <tr>
                <th scope="col">#</th>
                <th scope="col">英雄名称</th>
                <th scope="col">英雄台词</th>
                <th scope="col" width="80">修改</th>
                <th scope="col" width="80">删除</th>
              </tr>
            </thead>
            <tbody style="background-color: #dbeff7;">
              {{each res}}
              <tr>
                <th scope="row" class="userID">{{$index + 1}}</th>
                <td>{{$value.name}}</td>
                <td>{{$value.words}}</td>
                <td>
                  <button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#updateModal"
                    data-name="{{$value.name}}" data-words="{{$value.words}}" data-id="{{$value.id}}">修改</button>
                </td>
                <td>
                  <button type="button" class="btn btn-danger" data-bs-toggle="modal" data-bs-target="#deleteModal"
                    data-id="{{$value.id}}">删除</button>
                </td>
              </tr>
              {{/each}}
            </tbody>
          </table>
        </div>
      </div>
      <div class="col-1"></div>
    </div>
  </div>
  
  <!-- 添加模块 -->
  <div class="modal fade" id="addModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
    <form action="/addInfo" method="post">
      <div class="modal-dialog">
        <div class="modal-content">
          <div class="modal-header">
            <h5 class="modal-title" id="exampleModalLabel">添加英雄</h5>
            <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
          </div>
          <div class="modal-body">
            <div class="mb-3">
              <label for="exampleInputEmail1" class="form-label">姓名:</label>
              <input type="text" class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp" name="name">
            </div>
            <div class="mb-3">
              <label for="exampleInputPassword1" class="form-label">台词:</label>
              <input type="text" class="form-control" id="exampleInputPassword1" name="words">
            </div>
          </div>
          <div class="modal-footer">
            <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
            <button type="submit" class="btn btn-primary">确定</button>
          </div>
        </div>
      </div>
    </form>
  </div>
  <!-- 修改模块 -->
  <div class="modal fade" id="updateModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
    <form action="/updateInfo" method="get">
    <input name="id" class="okUpdate">
      <div class="modal-dialog">
        <div class="modal-content">
          <div class="modal-header">
            <h5 class="modal-title" id="exampleModalLabel">修改英雄</h5>
            <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
          </div>
          <div class="modal-body">
            <div class="mb-3">
              <label for="updateName" class="form-label">姓名:</label>
              <input type="text" class="form-control" id="updateName" aria-describedby="emailHelp" name="name">
            </div>
            <div class="mb-3">
              <label for="updateWords" class="form-label">台词:</label>
              <input type="text" class="form-control" id="updateWords" name="words">
            </div>
          </div>
          <div class="modal-footer">
            <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
            <button type="submit" class="btn btn-primary">确定</button>
          </div>
        </div>
      </div>
    </form>
  </div>

  <!-- 删除模块 -->
  <div class="modal fade" id="deleteModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
    <form action="/delInfo" method="post">
    <input name="id" class="okDel">
      <div class="modal-dialog">
        <div class="modal-content">
          <div class="modal-header">
            <h5 class="modal-title" id="exampleModalLabel">删除英雄</h5>
            <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
          </div>
          <div class="modal-body">
            确定要删除吗??
          </div>
          <div class="modal-footer">
            <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
            <button type="submit" class="btn btn-primary">确定</button>
          </div>
        </div>
      </div>
    </form>
  </div>
  <script src="./js/index.js"></script>
  <script src="./js/bootstrap.min.js"></script>
</body>
</html>
<!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>Document</title>
</head>
<body>
  <h1>{{err}}</h1>
  <script>
    setTimeout(() => {
      window.location.href = "http://localhost:9527/"
    }, 3000);
  </script>
</body>
</html>
3.3 入口文件
// 入口
const express = require("express")
const path = require("path")

const app = express()

// 使用路由
const { router } = require("./router/router")

app.use(express.json())
app.use(express.urlencoded({ extended: true }))

// 后端渲染
app.engine('art', require('express-art-template'));
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'art');

// 读取静态文件中的数据
app.use(express.static("public"))

app.use(router)

app.listen(9527, () => {
  console.log("服务也开启: http://localhost:9527");
})
3.4 mysql文件
// 数据库连接
const mysql = require("mysql")

module.exports.database = function (sql, parameter = null) {
  // 数据库配置
  var connection = mysql.createConnection({
    host: 主机,
    port: 端口号,
    user: 用户名,
    password: 密码,
    database: 数据库
  });

  // 连接数据库
  connection.connect((err) => {
    if (err) {
      console.error('error connecting: ' + err.stack);
      return;
    }
    console.log('连接次数:' + connection.threadId);
  });
  return new Promise((reslove, reject) => {
    // 访问数据库
    connection.query(sql, parameter, function (error, results, fields) {
      if (error) {
        reject(error)
        return
      }
      reslove(results)
    });
    // 关闭数据库
    connection.end();
  })
}
3.5 路由文件
// 路由
const express = require("express")

// 数据处理模块
const { renderPage, addInfo, delInfo, updateInfo, searchInfo } = require("../mysql/renderData")

const router = express.Router()

// 主页面渲染数据
router.get("/", renderPage)
router.get("/home", renderPage)

// 添加数据
router.post("/addInfo", addInfo)

// 删除数据
router.post("/delInfo", delInfo)

// 更新数据
router.get("/updateInfo", updateInfo)

// 搜索数据
router.post("/searchInfo", searchInfo)

exports.router = router
3.6 渲染数据文件
// 渲染数据
const { database } = require("./database")

function renderPage(request, response) {
  database('select * from info_list where isDel = 0').then(res => {
    response.render("index.art", {
      res
    })
  }).catch(err => {
    renderErr(response, "主页数据出错了")
  })
}

function addInfo(request, response) {
  if (!request.body.name.trim()) {
    renderErr(response, "添加数据名字不能为空")
    return
  }
  database('insert into info_list set ?', request.body).then(res => {
    response.redirect("/home")
    response.send()
  }).catch(err => {
    renderErr(response, "添加数据出错了")
  })
}

function delInfo(request, response) {
  database('update info_list set isDel = 1 where id = ?', request.body.id).then(res => {
    response.redirect("/home")
    response.send()
  }).catch(err => {
    response.send(err)
  })
}

function updateInfo(request, response) {
  if (!request.query.name.trim()) {
    renderErr(response, "修改数据名字不能为空")
    return
  }
  // set 要设置的 
  // where 过滤条件
  // ? 对应数组 索引
  database('update info_list set name = ?, words = ? where id = ?',
    [request.query.name, request.query.words, request.query.id]).then(res => {
      response.redirect("/home")
      response.send()
    }).catch(err => {
      renderErr(response, "修改数据出错了")
    })
}

function searchInfo(request, response) {
  // 如果搜索为空,直接跳到首页
  if (!request.body.name.trim()) {
    response.redirect("/home")
    response.send()
    return
  }
  // like 模糊查询,% 表示零个或多个
  database('select * from info_list where name like ? and isDel = 0', `%${request.body.name}%`).then(res => {
    response.render("index.art", {
      res
    })
  }).catch(err => {
    response.send(err)
  })
}

function renderErr(response, err) {
  response.render("404.art", {
    err: err
  })
}

module.exports = {
  renderPage,
  addInfo,
  delInfo,
  updateInfo,
  searchInfo
}
3.7 修改删除数据关联文件
// 修改
document.querySelector("#updateModal").addEventListener("show.bs.modal", function (e) {
  document.querySelector("#updateName").value = e.relatedTarget.dataset.name
  document.querySelector("#updateWords").value = e.relatedTarget.dataset.words
  this.children[0].children[0].value = e.relatedTarget.dataset.id
})

// 删除
document.querySelector("#deleteModal").addEventListener("show.bs.modal", function (e) {
  this.children[0].children[0].value = e.relatedTarget.dataset.id
})
3.8 css样式文件
body {
  padding-top: 20px;
}

.container .box {
  border-radius: 5px;
  overflow: hidden;
}

.container .header {
  border-bottom: 1px solid #e8e8e8;
  background-color: #f7f7f7;
  font-size: 20px;
  padding: 5px 0;
}

.container .username label {
  font-weight: bold;
  padding-top: 6px;
}

.table {
  margin-bottom: 0px !important;
  border-top: 1px solid #dee2e6;
}

.table tr {
  line-height: 2.5;
}

.table tbody tr td:nth-child(4) {
  background-color: #fbf7e3;
}

.table tbody tr td:nth-child(5) {
  background-color: #f3dfdf;
}

button {
  opacity: 0.8;
}

.okDel {
  display: none;
}

.okUpdate {
  display: none;
}

4. 案例总结

后端渲染每次请求数据都会刷新整个页面,所以后端渲染不太好

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值