zoukankan      html  css  js  c++  java
  • MongoDB+模板引擎 项目实例-学生档案管理

    目标:模板引擎应用,强化 node.js 项目制作流程。

    知识点:http请求响应、数据库、模板引擎、静态资源访问。

    1、建立项目文件夹并生成项目描述文件 package.json

    1.1、创建 students 文件夹

    1.2、生成项目描述文件 package.json

    在命令行工具中切换到当前项目的根目录下,输入:

    npm init -y

    2、创建网站服务器,实现客户端和服务器端通信

    2.1、创建网站服务器

    在根目录下新建 app.js 文件:

    // 引入 http 模块
    const http = require('http');
    // 创建网站服务器
    const app = http.createServer();

    2.2、添加请求事件,实现通信

    // 引入 http 模块
    const http = require('http');
    // 创建网站服务器
    const app = http.createServer();
    // 当客户端访问服务器端的时候
    app.on('request', (req, res) => {
      res.end('ok');
    });
    
    app.listen(80);
    console.log('服务器启动成功');

    在命令行工具中开启服务器:

    nodemon app.js

    再打开浏览器,输入:http://localhost/

    可以看到,响应成功:

    3、连接数据库并根据需求设计学员信息表

    3.1、连接数据库

    1、安装 mongoose,在命令行工具中输入:

    npm install mongoose

    然后重启开启服务器:nodemon app.js

    2、连接数据库

    在 app.js 文件中添加:

    // 引入 http 模块
    const http = require('http');
    const mongoose = require('mongoose');
    // 连接数据库
    mongoose.connect('mongodb://localhost/playground', { useNewUrlParser: true, useUnifiedTopology: true})
      .then(() => console.log('数据库连接成功'))
      .catch(() => console.log('数据库连接失败'))
    // 创建网站服务器
    const app = http.createServer();
    // 当客户端访问服务器端的时候
    app.on('request', (req, res) => {
      res.end('ok');
    });
    
    app.listen(80);
    console.log('服务器启动成功');

    然后在命令行工具中可以看到:数据库连接成功的提示。

    注意:如果没启动 MongoDB,记得要先启动:net start mongoDB

    我们上次说过要把数据库的代码分离出去,不要都写在一个文件中

    所以新建 model 文件夹,创建 connect.js 文件,然后把数据库连接部分的代码剪切过来。

    const mongoose = require('mongoose');
    // 连接数据库
    mongoose.connect('mongodb://localhost/playground', { useNewUrlParser: true, useUnifiedTopology: true})
      .then(() => console.log('数据库连接成功'))
      .catch(() => console.log('数据库连接失败'))

    然后回到 app.js 中导入connect

    require('./model/connect');

    3.2、设计学员信息表

    1、设计用户集合用到的字段

    在 model 目录下新建 user.js 文件:

    const mongoose = require('mongoose');
    // 创建学生集合规则
    const studentsSchema = new mongoose.Schema({
      name:{
        type: String,
        required: true,
        minlength: 2,
        maxlength: 10
      },
      age: {
        type: Number,
        min: 10,
        max: 25
      },
      sex: {
        type:String
      },
      email: String,
      hobbies: [String],
      collage: String,
      enterDate: {
        type: Date,
        default: Date.now
      }
    });
    // 创建学生信息集合
    const Student = mongoose.model('Student', studentsSchema);
    // 将学生信息集合进行导出
    module.exports = Student;

    回到 app.js 文件中,导入 Student 

    const Student = require('./model/user');

    4、创建路由并实现页面模板呈递

    第三方模块 router

    功能:实现路由。

    使用步骤:

    1、获取路由对象

    2、调用路由对象提供的方法创建路由

    3、启用路由,使路由生效

    示例代码:

    const getRouter = require('router');
    const router = getRouter();
    router.get('/add', (req, res) => {
      res.end('hello world')
    })
    server.on('request', (req. res) => {
      router(req, res)
    })

    下载安装:

    npm install router

    重新启动项目:nodemon app.js

    回到app.js 文件中,引入 router 模块:

    // 引入 router 模块
    const getRouter = require('router');
    // 获取路由对象
    const router = getRouter();
    
    router.get('/test', (req, res) => {
      res.end('test')
    })
    router.get('/index', (req, res) => {
      res.end('index')
    })
    
    // 当客户端访问服务器端的时候
    app.on('request', (req, res) => {
      // res.end('ok');
      router(req, res, () => {
      })
    });

    此时打开浏览器,输入:http://localhost/test,页面上可以看到 test ;同样输入 http://localhost/index,页面可以显示index。

    4.1、创建当前项目路由

    // 添加学生档案信息页面
    router.get('/add', (req, res) => {
      res.end('add')
    })
    // 学生档案信息列表页面
    router.get('/list', (req, res) => {
      res.end('list')
    })

    4.2、呈现对应的页面

    1、安装模板引擎

    在命令行工具输入:npm install art-template

    在项目根目录下,新建 views 文件夹, 把静态页面粘贴过来;并在项目根目录下,新建 public 文件夹,把 css 文件站提过来。

    在 app.js 文件中引入模板引擎:

    const template = require('art-template');

    接下来在对应的路由中,渲染模板引擎,并把渲染的结果响应给客户端

    2、配置模板的根目录

    const path = require('path');
    
    // 配置模板的根目录
    template.defaults.root = path.join(__dirname, 'views');
    
    // 添加学生档案信息页面
    router.get('/add', (req, res) => {
      const html = template('index.art', {})
      res.end(html)
    })
    // 学生档案信息列表页面
    router.get('/list', (req, res) => {
      const html = template('list.art', {})
      res.end(html)
    })

    在命令行工具开启服务:nodemon app.js

    回到浏览器中,输入:http://localhost/add

    会发现i服务器一直请求,点击刷新按钮,可以看到没有样式,查看源码可以看到页面还引用了一个 css 样式文件。

    第三方模块 serve-static

    功能:实现静态资源访问服务。

    步骤:

    1、引入 serve-static 模块获取创建静态资源服务功能的方法

    2、调用方法创建静态资源服务并指定静态资源服务目录

    3、启动静态资源服务功能

    示例代码:

    const serveStatic = require('serve-static')
    const serve = serveStatic('public')
    server.on('request', () => {
      serve(req. res)
    })
    server.listen(3000)

    5、实现静态资源访问

    5.1、下载安装 serve-static

    npm install serve-static

    5.2、引入静态资源访问 serve-static 模块

    // 引入静态资源访问模块
    const serveStatic = require('serve-static');

    5.3、实现静态资源访问服务

    // 实现静态资源访问服务
    const serve = serveStatic(path.join(__dirname, 'public'));

    5.4、启用静态资源访问服务功能

    // 当客户端访问服务器端的时候
    app.on('request', (req, res) => {
      // 启用路由功能
      router(req, res, () => {})
      // 启用静态资源访问服务功能
      serve(req, res, () => {})
    });

    回到浏览器刷新页面,可以看到样式出来了:

    6、实现学生信息添加功能

    6.1、在模板的表单中指定请求地址与请求方式

    打开 views 目录下的 index.art 文件,添加请求地址及请求方式

    <form method="post" action="/add">

    6.2、为每一个表单项添加 name 属性

    <input class="normal" type="text" autofocus placeholder="请输入姓名" name="name">
    
    <input class="normal"  type="text" placeholder="请输入年龄" name="age">
    
    <input type="radio" value="0" name="sex"><input type="radio" value="1" name="sex"><input class="normal" type="text" placeholder="请输入邮箱地址" name="email">
    
    <input type="checkbox" value="0" name="hobbies"> 敲代码
    <input type="checkbox" value="1" name="hobbies"> 打篮球
    <input type="checkbox" value="1" name="hobbies"> 睡觉
    
    <select class="normal" name="collage">
    
    <input type="date" class="normal" name="enterDate"> 

    6.3、添加实现学生信息功能路由

    // 实现学生信息添加功能路由
    router.post('/add', (req, res) => {
     
    })

    6.4、接收客户端传递过来的学生信息

    // 实现学生信息添加功能路由
    router.post('/add', (req, res) => {
      // 接收用户提交的信息
      let fromData= '';
      // 当有参数传递的时候会触发 data 事件
      req.on('data', param => {
        fromData += param;
      });
      // 当参数接收完毕的时候会触发 end 事件
      req.on('end', async () => {
        console.log(querystring.parse(fromData))
        res.end('123');
      });
    })

    回到浏览器中刷新页面,随便输入一些信息后提交;然后可以看到页面显示:123

    打开命令行工具,可以看到:参数已经接受过来了

    6.5、将学生信息添加到数据库中

    // 实现学生信息添加功能路由
    router.post('/add', (req, res) => {
      // 接收用户提交的信息
      let fromData= '';
      // 当有参数传递的时候会触发 data 事件
      req.on('data', param => {
        fromData += param;
      });
      // 当参数接收完毕的时候会触发 end 事件
      req.on('end', async () => {
        // 将用户提交的信息添加到数据库中
        await Student.create( querystring.parse(fromData));
        // 重定向 状态码是301
        // Location 跳转地址
        res.writeHead(301, {
          Location: '/list'
        });
        res.end();
      });
    }) 

    6.6、将页面信息重定向到学生信息列表页面

    回到浏览器中刷新页面,重新提交一些信息后,会重定向到 /list 路由

    打开 Compass 软件,可以看到 playground 下多了一个 students 集合,里面有一条刚提交的数据

    7、实现学生信息展示功能

    7.1、从数据库中将所有的学生信息查询出来

    在 app.js 中继续编辑代码:

    // 学生档案信息列表页面
    router.get('/list', async (req, res) => {
      // 查询用户信息
      let students = await Student.find()
      console.log(students);
    
      const html = template('list.art', {})
      res.end(html)
    })

    回到浏览器中刷新 /list 页面,在命令行工具中可以看到:

     

    7.2、通过模板引擎将学生信息和 HTML 模板进行拼接

    继续编辑 app.js 文件:

    // 学生档案信息列表页面
    router.get('/list', async (req, res) => {
      // 查询用户信息
      let students = await Student.find()
      console.log(students);
    
      const html = template('list.art', {
        students: students
      })
      res.end(html)
    })

    打开 list.art 文件,添加循环:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>学员信息</title>
        <link rel="stylesheet" href="./css/list.css">
    </head>
    <body>
        <table>
            <caption>学员信息</caption>
            <tr>
                <th>姓名</th>
                <th>年龄</th>
                <th>性别</th>
                <th>邮箱地址</th>
                <th>爱好</th>
                <th>所属学院</th>
                <th>入学时间</th>
            </tr>
            {{each students}}
            <tr>
                <th>{{$value.name}}</th>
                <th>{{$value.age}}}</th>
                <th>{{$value.sex}}</th>
                <th>{{$value.email}}</th>
                <th>{{$value.hobbies}}</th>
                <th>{{$value.collage}}</th>
                <th>{{$value.enterDate}}</th>
            </tr>
            {{/each}}
        </table>
    </body>
    </html>

    回到浏览器刷新 /list 页面,可以看到数据渲染出来了:

    这里可以看出三个问题:性别、爱好、入学时间。

    7.3、将拼接好的 HTML 模板响应给客户端

    解决性别问题:

    <th>{{$value.sex == '0' ? '男' : '女'}}</th>

    解决爱好问题:

    打开 index.art 文件,修改下:

    爱好: 
    <input type="checkbox" value="敲代码" name="hobbies"> 敲代码
    <input type="checkbox" value="打篮球" name="hobbies"> 打篮球
    <input type="checkbox" value="睡觉" name="hobbies"> 睡觉

    再重新添加一条学生信息:

    可以看到爱好已经显示了,但是格式还是不对,还要进行处理:

    <th>
        {{each $value.hobbies}}
         <span>{{$value}}</span>
        {{/each}}
    </th>

    刷新浏览器,可以看到:爱好的格式已经正常了

    解决时间问题:

    第三方模板 dateformat 处理时间格式

    下载安装:

    npm install dateformat

    然后重新开启服务:nodemon app.js

    修改 app.js 文件:

    // 引入处理日期的第三方模块
    const dateFormat = require('dateformat');
    
    // 导入模板变量 处理日期格式的方法
    template.defaults.imports.dateFormat = dateFormat;

    回到 list.art 文件:

    <th>{{dateFormat($value.enterDate, "yyyy-mm-dd hh:mm")}}</th>

    在浏览器刷新页面,可以看到:日期格式也正常了

    此时功能都实现了。

    但是发现 app.js 中路由部分的代码还可以分离出去

    新建 route 目录,并在目录下 新建 index.js 文件,把 app.js 中路由部分的代码剪切过来:

    // 引入 router 模块
    const getRouter = require('router');
    // 获取路由对象
    const router = getRouter();
    // 学生信息集合
    const Student = require('../model/user');
    // 引入模板引擎
    const template = require('art-template');
    // 处理请求参数模块
    const querystring = require('querystring');
    
    // 添加学生档案信息页面
    router.get('/add', (req, res) => {
      const html = template('index.art', {})
      res.end(html)
    })
    // 学生档案信息列表页面
    router.get('/list', async (req, res) => {
      // 查询用户信息
      let students = await Student.find()
      console.log(students);
    
      const html = template('list.art', {
        students: students
      })
      res.end(html)
    })
    // 实现学生信息添加功能路由
    router.post('/add', (req, res) => {
      // 接收用户提交的信息
      let fromData= '';
      // 当有参数传递的时候会触发 data 事件
      req.on('data', param => {
        fromData += param;
      });
      // 当参数接收完毕的时候会触发 end 事件
      req.on('end', async () => {
        // 将用户提交的信息添加到数据库中
        await Student.create( querystring.parse(fromData));
        // 重定向 状态码是301
        // Location 跳转地址
        res.writeHead(301, {
          Location: '/list'
        });
        res.end();
      });
    })
    
    module.exports = router;

    修改后的 app.js 文件:

    // 引入 http 模块
    const http = require('http');
    // 引入模板引擎
    const template = require('art-template');
    // 引入 path 慕课
    const path = require('path');
    // 引入静态资源访问模块
    const serveStatic = require('serve-static');
    // 引入处理日期的第三方模块
    const dateFormat = require('dateformat');
    
    const router = require('./route/index');
    
    // 实现静态资源访问服务
    const serve = serveStatic(path.join(__dirname, 'public'));
    
    // 配置模板的根目录
    template.defaults.root = path.join(__dirname, 'views');
    // 导入模板变量 处理日期格式的方法
    template.defaults.imports.dateFormat = dateFormat;
    
    // 数据库连接
    require('./model/connect');
    
    // 创建网站服务器
    const app = http.createServer();
    // 当客户端访问服务器端的时候
    app.on('request', (req, res) => {
      // 启用路由功能
      router(req, res, () => {})
      // 启用静态资源访问服务功能
      serve(req, res, () => {})
    });
    
    app.listen(80);
    console.log('服务器启动成功');

    回到浏览器刷新,重新测试下功能。OK,没有影响,都正常。

  • 相关阅读:
    web前端的面试真题
    web前端面试真题! 面试的经历和回答只做参考1
    web前端面试真题! 面试的经历和回答只做参考
    html面试资料
    angluar.js的核心介绍
    解决 Chrome支持小于12px 的文字
    div居中效果出现的问题和解决方法
    li和li之间的bug解决方法
    前端面试题笔试考题和答案
    html5新增的标签和使用的方法
  • 原文地址:https://www.cnblogs.com/joe235/p/12895747.html
Copyright © 2011-2022 走看看