Skip to content
nodejs的express框架模板

项目搭建和运行

安装模版(一定放全局)

bash
npm install -g express-generator

生成项目

bash
// 这里我用的ejs模版引擎,你可以用其他的,比如pug,handlebars等,可以看npmjs官方给的模板引擎示例
express --view=ejs myapp

安装依赖

bash
cd myapp
npm install

运行

bash
npm start

访问测试

访问:http://localhost:3000 访问成功后,显示index.ejs模版页面

访问:http://localhost:3000/users 访问成功后,显示respond with a resource文本

框架整体代码不多易于理解,能跑起来后面看代码慢慢理解下吧

这个框架只是搭建了一个架子,,未实现mvc架构,需要什么功能自己搭建

可以理解为router层就是controller层就是控制器层,模型层等用到了数据库自己新建model层实现,service层等用到了数据库自己新建service层实现,router请求到数据就到service层去处理数据,然后将数据给前端展示

ejs模版引擎简单使用

路由改造

模拟数据,模拟接口数据的增删改查,修改routes/index.js文件,内容如下

js
const express = require('express');
const router = express.Router();

// 假数据,实际用数据库
let items = [
  { id: 1, name: 'Apple' },
  { id: 2, name: 'Banana' },
  { id: 3, name: 'Orange' },
  { id: 4, name: 'Grape' },
  { id: 5, name: 'Pear' },
  { id: 6, name: 'Watermelon' },
];

// 列表页:首次渲染
router.get('/', (req, res) => {
  res.render('index', { items });   // EJS 拿到初始数据
});

// RESTful API ↓↓↓
// 查
router.get('/api', (req, res) => res.json(items));
// 增
router.post('/api', express.json(), (req, res) => {
  const newItem = { id: Date.now(), name: req.body.name };
  items.push(newItem);
  res.json(newItem);
});
// 删
router.delete('/api/:id', (req, res) => {
  items = items.filter(i => i.id != req.params.id);
  res.sendStatus(204);
});
// 改
router.put('/api/:id', express.json(), (req, res) => {
  const item = items.find(i => i.id == req.params.id);
  if (item) item.name = req.body.name;
  console.log(item);
  res.json(item);
});

module.exports = router;

模版改造,有感刷新渲染方式

修改views/index.ejs文件,内容如下

trea里面打开可能会爆红,,不用管,,语法识别错误了

js
<!doctype html>
<html>
<head>
  <title>Items CRUD</title>
</head>
<body>
  <h1>Items</h1>

  <!-- 新增 -->
  <input id="addInput" placeholder="name">
  <button onclick="addItem()">Add</button>

  <!-- 列表 -->
  <table border="1">
    <thead><tr><th>ID</th><th>Name</th><th>Ops</th></tr></thead>
    <tbody id="tbody">
      <% items.forEach(i=> { %>
        <tr data-id="<%= i.id %>">
          <td><%= i.id %></td>
          <td class="name"><%= i.name %></td>
          <td>
            <button onclick="editItem(<%= i.id %>)">Edit</button>
            <button onclick="delItem(<%= i.id %>)">Del</button>
          </td>
        </tr>
      <% }) %>
    </tbody>
  </table>

  <script>
    // 新增
    async function addItem(){
      const name = document.getElementById('addInput').value.trim();
      if(!name) return;
      const res = await fetch('/api', {
        method: 'POST',
        headers: {'Content-Type':'application/json'},
        body: JSON.stringify({name})
      });
      const data = await res.json();
      location.reload();          // 简单刷新,也可 DOM 追加一行
    }
    // 删除
    async function delItem(id){
      await fetch('/api/'+id, {method:'DELETE'});
      location.reload();
    }
    // 编辑(prompt 偷懒版)
    async function editItem(id){
      const row = document.querySelector(`tr[data-id="${id}"]`);
      const newName = prompt('New name:', row.querySelector('.name').textContent);
      if(!newName) return;
      await fetch('/api/'+id, {
        method:'PUT',
        headers:{'Content-Type':'application/json'},
        body: JSON.stringify({name:newName})
      });
      location.reload();
    }
  </script>
</body>
</html>

模版改造,无刷新渲染方式

原理就是有感在每次增删改查之后会刷新页面重新请求数据,无感就不会刷新页面而是重新请求接口拿到数据

js
<!doctype html>
<html>

<head>
  <title>Items CRUD</title>
</head>

<body>
  <h1>Items</h1>

  <!-- 新增 -->
  <input id="addInput" placeholder="name">
  <button onclick="addItem()">Add</button>

  <!-- 列表 -->
  <table border="1">
    <thead>
      <tr>
        <th>ID</th>
        <th>Name</th>
        <th>Ops</th>
      </tr>
    </thead>
    <tbody id="tbody">
    </tbody>
  </table>

  <script>
    // 统一渲染函数:把后端给的新数组画成表格
    function renderTable(list) {
      const html = list.map(i => `
      <tr data-id="${i.id}">
        <td>${i.id}</td>
        <td class="name">${i.name}</td>
        <td>
          <button onclick="editItem(${i.id})">Edit</button>
          <button onclick="delItem(${i.id})">Del</button>
        </td>
      </tr>`).join('');
      document.getElementById('tbody').innerHTML = html;
    }

    // 首次进页面也用它
    (async () => {
      const res = await fetch('/api');
      renderTable(await res.json());
    })();

    // 新增
    async function addItem() {
      const name = document.getElementById('addInput').value.trim();
      if (!name) return;
      await fetch('/api', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ name })
      });
      // ➜ 增完立即查
      const res = await fetch('/api');
      renderTable(await res.json());
      document.getElementById('addInput').value = '';
    }

    // 删除
    async function delItem(id) {
      await fetch('/api/' + id, { method: 'DELETE' });
      const res = await fetch('/api');
      renderTable(await res.json());
    }

    // 修改
    async function editItem(id) {
      const row = document.querySelector(`tr[data-id="${id}"]`);
      const newName = prompt('New name:', row.querySelector('.name').textContent);
      if (!newName) return;
      await fetch('/api/' + id, {
        method: 'PUT',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ name: newName })
      });
      const res = await fetch('/api');
      renderTable(await res.json());
    }
  </script>
</body>

</html>