WEB开发: 三分钟变身全栈工程师 - 前/后端/API/数据库 Node.js + SQLite实战教程

这个教程,实现了一个学生成绩管理系统,用Node.js 作为web服务器架构,用SQLite作为数据库,用Vue.js作为前端框架,用Element-ui作为UI库。一步步来学习,三分钟让你变身全栈工程师。

Node.js

        Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行时环境,用于构建高效、可扩展的网络应用。它采用事件驱动、非阻塞 I/O 模型,特别适合处理 I/O 密集型任务,如实时应用和大规模分布式系统。Node.js 使用单线程事件循环处理多个并发连接,支持大量并发请求,能够高效地处理实时数据流。开发者可以使用 JavaScript 编写服务器端代码,使得前后端代码语言一致,提升开发效率。这里用的Node 版本:v14.21.3 (太高装不了sqlite)

SQLite

        SQLite 是一个轻量级、嵌入式的关系型数据库管理系统,它以 C 语言编写,提供了完整的 SQL 功能。SQLite 不依赖于服务器进程或系统安装,数据库文件存储在本地磁盘,适合嵌入到应用程序中使用。由于其占用资源少、易于集成,SQLite 常用于移动应用、桌面应用、嵌入式设备、浏览器等场景。它支持事务、ACID(原子性、一致性、隔离性、持久性)等特性,且性能优秀,广泛应用于需要轻量、快速存储解决方案的项目中。

Vue.js

        Vue.js 是一款渐进式的 JavaScript 框架,用于构建用户界面。与其他框架不同,Vue.js 可以逐步采用,即可以仅在应用程序的一部分中使用它,也可以将其用于整个项目。Vue.js 的核心库专注于视图层,易于上手,且与其他库或现有项目能够很好地集成。

        Vue.js 采用响应式数据绑定和组件化开发方式,使得 UI 更新和状态管理变得非常简便。它提供了丰富的工具和库,支持单页应用(SPA)的开发,包含 Vue Router(路由管理)和 Vuex(状态管理)。Vue.js 的轻量、灵活和高性能特性,使其成为前端开发中非常受欢迎的框架之一。

Element-ui

        Element UI 是一款基于 Vue.js 的桌面端 UI 组件库,旨在为开发者提供一套高质量的、可定制的 UI 组件,帮助构建美观、易用的后台管理系统或企业级应用。它包含了丰富的组件,如表格、表单、按钮、导航栏、对话框等,可以大大提高开发效率。

        Element UI 的设计风格简洁、清晰、现代,符合大多数用户界面的设计需求,且提供了详细的文档和易于理解的 API。它支持按需加载,可以减小项目的体积,还提供了主题定制功能,方便开发者根据需求调整界面的样式。

        此外,Element UI 被广泛应用于 Vue.js 项目中,且社区活跃,更新频繁,已成为 Vue.js 生态中常用的 UI 组件库之一。

前戏结束了,正式开始啦:

请可以按照以下步骤来创建这个基于 Node.js、SQLite3 和 Vue.js + Element-UI 的学生管理系统。

1. 初始化项目

首先,创建一个新的 Node.js 项目。

//创建一个专用的目录
mkdir student-management
cd student-management

//初始化这个项目
npm init -y

//安装一些必要的包  其中express  是node里面做服务器的,body-parser用来解析输入字符串对象的
npm install express sqlite3 body-parser

2. 创建 SQLite 数据库

在项目根目录下创建 SQLite 数据库和学生表(student 表包含 id, name, grade, score 字段)。

// db.js
const sqlite3 = require('sqlite3').verbose();
const db = new sqlite3.Database('db.db');

// 创建学生表
db.serialize(() => {
  db.run("CREATE TABLE IF NOT EXISTS student (id INTEGER PRIMARY KEY, name TEXT, grade TEXT, score INTEGER)");
});

module.exports = db;

3. 创建 Web Server

创建 index.js 文件来设置 Web 服务器,作为api 和网站服务,处理增删查改操作。

详细的方法和逻辑请看注释

// index.js
const express = require('express');
const bodyParser = require('body-parser');

//这里引入了数据库db.js ,第一次会创建一个数据库,要求都写在db.js里面了
const db = require('./db');
const path = require('path');

//定义一个app作为web服务器 使用了express这个库
const app = express();

//定义端口是8001
const port = 8001;

//把服务器接收到的内容转成json格式 以便后面处理
app.use(bodyParser.json());

// 查询学生,支持根据 name 过滤 /query是路由 前端必须使用get访问这个api
app.get('/query', (req, res) => {
  const name = req.query.name || '';
  const query = `SELECT * FROM student WHERE name LIKE ?`;

  db.all(query, [`%${name}%`], (err, rows) => {
    if (err) {
      res.status(500).json({ error: err.message });
    } else {
      res.json(rows);
    }
  });
});

// 插入一个学生 /insert 是路由 前端必须使用post访问这个api
app.post('/insert', (req, res) => {
  const { name, grade, score } = req.body;
  const stmt = db.prepare("INSERT INTO student (name, grade, score) VALUES (?, ?, ?)");
  
  stmt.run(name, grade, score, function(err) {
    if (err) {
      res.status(500).json({ error: err.message });
    } else {
      res.status(201).json({ id: this.lastID });
    }
  });

  stmt.finalize();
});

// 根据 name 删除学生 /delete 是路由 前端必须使用post访问这个api
app.post('/delete', (req, res) => {
  const { name } = req.body;
  const stmt = db.prepare("DELETE FROM student WHERE name = ?");
  
  stmt.run(name, function(err) {
    if (err) {
      res.status(500).json({ error: err.message });
    } else {
      res.json({ affectedRows: this.changes });
    }
  });

  stmt.finalize();
});

// 根据 name 更新学生数据 /edit 是路由 前端必须使用post 访问这个api(两边改成put 也可以)
app.post('/edit', (req, res) => {
  const { name, grade, score } = req.body;
  const stmt = db.prepare("UPDATE student SET grade = ?, score = ? WHERE name = ?");
  
  stmt.run(grade, score, name, function(err) {
    if (err) {
      res.status(500).json({ error: err.message });
    } else {
      res.json({ affectedRows: this.changes });
    }
  });

  stmt.finalize();
});

// 提供静态资源 public是一个服务器静态资源目录用来放置 html css 图片 js这些
//访问网站 http://localhost:8001就是访问了这个目录, 前面的路由到不了这里 因为已经定义了 被前面截胡去了该去的地方
app.use(express.static(path.join(__dirname, 'public')));

app.listen(port, () => {
  console.log(`Server running at http://localhost:${port}`);
});

4. 创建前端:Vue.js + Element-UI

public 文件夹中,创建 index.html,并通过 Vue.js + Element-UI 创建前端页面。

创建文件夹和文件结构:
mkdir public
cd public
touch index.html
index.html 文件内容:
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>学生管理系统</title>
  <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
</head>
<body>
<!-- 这里加载后面数据中的html模板 以app 为id -->
  <div id="app"></div> 

<!-- 这里引入vue框架和 element-ui -->
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
  <script src="https://unpkg.com/element-ui/lib/index.js"></script>
  <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<!-- 以下不懂的 请参考 vue教程  看一下就会了 很容易学  或者直接看下面的结构也能理解-->
  <script>
    new Vue({
      el: '#app',
      data: {
        students: [],
        newStudent: { name: '', grade: '', score: '' },
        searchName: ''
      },
      methods: {
        fetchStudents() {
          axios.get(`/query?name=${this.searchName}`)
            .then(response => {
              this.students = response.data;
            });
        },
        addStudent() {
          axios.post('/insert', this.newStudent)
            .then(response => {
              this.fetchStudents();
              this.newStudent = { name: '', grade: '', score: '' };
            });
        },
        deleteStudent(name) {
          axios.post('/delete', { name })
            .then(response => {
              this.fetchStudents();
            });
        },
        editStudent(student) {
          const newGrade = prompt('Enter new grade:', student.grade);
          const newScore = prompt('Enter new score:', student.score);
          
          if (newGrade && newScore) {
            axios.post('/edit', { name: student.name, grade: newGrade, score: newScore })
              .then(response => {
                this.fetchStudents();
              });
          }
        }
      },
      created() {
        this.fetchStudents(); //加载就执行拉取数据
      },
      template: `
        <div>
          <el-input v-model="searchName" placeholder="Search by name" @input="fetchStudents"></el-input>
          <el-table :data="students" style="width: 100%">
            <el-table-column prop="name" label="Name"></el-table-column>
            <el-table-column prop="grade" label="Grade"></el-table-column>
            <el-table-column prop="score" label="Score"></el-table-column>
            <el-table-column label="Actions">
              <template slot-scope="scope">
                <el-button @click="editStudent(scope.row)" size="small">Edit</el-button>
                <el-button @click="deleteStudent(scope.row.name)" size="small" type="danger">Delete</el-button>
              </template>
            </el-table-column>
          </el-table>

          <el-input v-model="newStudent.name" placeholder="Name"></el-input>
          <el-input v-model="newStudent.grade" placeholder="Grade"></el-input>
          <el-input v-model="newStudent.score" type="number" placeholder="Score"></el-input>
          <el-button @click="addStudent" type="primary">Add Student</el-button>
        </div>
      `
    });
  </script>
</body>
</html>

5. 启动服务器

回到项目根目录,运行以下命令启动服务器:

node index.js

6. 访问学生管理系统

打开浏览器,访问 http://localhost:8001,你应该能够看到一个学生管理系统,支持增、删、改、查功能。最终就是酱紫的:


总结

  1. 数据库:使用 SQLite 存储学生数据,表结构为 student(id, name, grade, score)
  2. 后端:使用 Express.js 提供 API,支持学生的查询、插入、删除和更新。
  3. 前端:使用 Vue.js 和 Element-UI 创建用户界面,能够执行增、删、改、查操作。

这个基本的框架可以进一步扩展、优化和增加更多功能,比如分页、表单验证等。

入门很容易,再复杂的系统,都是从这基本功能开始的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值