class10:子路由和MVC模型

一、ejs文件渲染css样式

如果要给ejs文件添加css样式,我们自然而然的想到使用外联在ejs文件中引入css文件渲染样式。而实际上这样的做法却不能渲染样式。

正确做法: 新建与views文件夹(ejs文件所在位置)同级的文件夹静态目录public,在静态目录中建立样式文件的css文件。ejs文件中用link标签引入css样式,用 / + css文件名 引入,其中/表示引入静态文件。

// index.ejs
<link rel="stylesheet" href="/index.css">
// index.css
body{
    background-color: aquamarine;
}

渲染结果:
在这里插入图片描述

注意:静态文件资源要提前配置,views只放置ejs文件。

二、状态码(无太大用途)

可以认为的在后端返回数据时设置404状态码,导致输出端显示404错误:

app.get("/test", (req, res)=>{
    res.status("404");
})

在这里插入图片描述

三、重定向(无太大用途)

重定向,即重新定位路由方向(地址),比如我们访问http://localhost:3000/red,使用重定向使得加载地址时访问百度https://www.baidu.com网址:

app.get("/red", (req, res)=>{
    res.redirect("https://www.baidu.com");
})

例:当未找到数据或路由时返回404报错页面

在静态资源中新建404.html文件,在后端配置(写在最后)未找到路由时跳转到404.html的文件:

app.use("*", (req, res)=>{
    res.redirect("/404.html")
})

输入一个错误路由:

在这里插入图片描述

自动加载404.html文件:

在这里插入图片描述

四、子路由

我们知道,如果路由请求都放在一个文件中将会很拥挤,维护麻烦。例如我们开发一个淘宝页面,将会包括很多子页面,这些子页面(首页、广场、购物车、我的等)都需要一个子路由,我们可以把子路由放在一个文件夹下。

新建一个与静态资源文件同级的目录router存放子路由,新建一个home.js文件存放首页的路由地址。

在home.js中引入子路由所需模块:

const express = require("express");
let router = express.Router();

使用子路由发起请求:

注意发起请求的名称与模块名赋予的变量一致:

router.get("/", (req, res) => { 
    res.send("长风破浪会有时,直挂云帆济沧海。")
});

/ 代表根路由,我们要配置的是/home页面,需要在后端主目录app.js中声明:

配置子路由:

app.use("/home", require("./router/home"));

第一个参数/home代表我们配置的子路由是/home,它对应的js文件所在的位置是:./router/home,即home.js文件。

所以上面第二个代码块中的根路由/表示的是该配置的子路由:/home

要引入home.js文件,需要将其导出:

module.exports = router;

总结:app.js中配置子路由/home,通过该子路由可以访问到router文件夹下的home.js文件的数据。

这样,就可以通过子路由访问数据了:

在这里插入图片描述

子路由中添加子路由:

在子路由的配置文件home.js中添加其他子路由:

const express = require("express");
let router = express.Router();

router.get("/", (req, res) => { //  /home
    res.send("长风破浪会有时,直挂云帆济沧海。")
});
// http://localhost:8080/home

router.get("/left", (req, res) => {
    res.send("南朝四百八十寺,多少楼台烟雨中。")
});
// http://localhost:8080/home/left

router.get("/right", (req, res) => {
    res.send("雄关漫道真如铁,而今迈步从头越。")
});
// http://localhost:3000/home/right

module.exports = router;

在这里插入图片描述

五、实例

上一课中我们做了一个计算偶数的实例,我们可以先进行优化,当我们输入的数字是第一次计算,那我们就计算它的偶数,并将该数字作为文件名生成txt文件,保存在同目录下的data文件夹中;当我们输入的数字之前已经计算过了,那我们读取对应数字的文件名中的数据直接返回到前端。

假设前端以post发起请求:

首先我们要拼接路径

// 引入path模块
const path = require("path");

let {value} = req.body;
// 拼接路径
let pathNameFile=path.join("./data/"+value+".txt"); // value为前端输入框输入的数字

然后判断该数字的文件是否存在

若存在,直接读取文件数据;

若不存在,进行计算,并写入文件:

// 引入fs模块
const fs = require("fs")
// 返回一个布尔值  判断文件是否存在
const bol = fs.existsSync(pathNameFile);

// 有则读取返回数据 没有则写入并计算返回数据
if(bol){ 
	// 返回数据
    console.log("文件" + value + "已存在,直接读取...");
    // 绝对路径
	res.sendFile(path.join(__dirname, pathNameFile));
}else{ //false 不存在
    console.log("文件" + value + "不存在,开始计算...");
	let arr = [];
	for(let i=0;i<=value;i++)
	{
		if(i%2==0)
		{
			arr.push(i)
		}
	}
	// 写入数据---相对路径
	fs.writeFile(pathNameFile, JSON.stringify(arr),()=>{
		res.send(arr);
	});
}

结果截图:
在这里插入图片描述

前端代码:

<body>
    <input id="txt" type="text" placeholder="请输入数字"> <br/>
    <button id="box">提交</button>
    <ul id="list"></ul>
    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
    <script>
        box.onclick = () => {
            axios({
                method: "post",
                url: "http://localhost:3000/factor",
                data: {
                    value: txt.value.trim(),
                }
            }).then(res => {
                let html = ""
                res.data.forEach(item => {
                    html += `
                    <li> ${item}</li>
                    `
                })
                list.innerHTML = html
                console.log(res)
            })
        }

    </script>
</body>

六、MVC模型

M—模块

V —页面展示

C —控制器

m模块:各种功能封装

v页面展示:静态文件 views

c控制器:只设置控制数据

例:我们对上一节的实例使用MVC模型对其进行分开管理:

在主目录app.js同级目录下新建controlles文件夹,并新建controle文件:

我们来看看主目录app.js与分目录controlles.js是怎么交互的:

// controlles.js文件
const factorFile=(req, res)=>{
    res.send("落霞与孤鹜齐飞,秋水共长天一色。");
};

module.exports = {
    factorFile,
}

该controlles.js文件定义了factorFile方法,并返回数据,并将该方法用模块导出。

// app.js
const app = express();
const {factorFile} = require("./controlles/controlles");
app.post("/factor", factorFile);

该app.js引入controlles.js中的方法,该方法是发起请求时的回调函数,使post请求变得完整。

结果:
在这里插入图片描述

modules模块:

对于controlles.js文件,我们只进行数据操作,其它的数学计算、文件的写入等由module模块负责:

新建module文件夹,在其中新建math.js文件用于数学计算,再新建pathFie.js文件用于数据写入:

// math.js
// 用于计算
const math = (value)=>{
    let  arr = [];
    for (let i=0;i<=value;i++){
        if (i% 2 ==0){
            arr.push(i)
        }
    }
    return arr
};

module.exports ={
   math,
};

在math.js中,传入一个参数value,即前端输入框输入的数字,并计算它的子偶数存入对象math,并将其导出。

// pathFile.js
const fs=require("fs");
const path =require("path");

// 判断文件是否存在  和 文件的绝对路径
const bol = (value)=>{
    // 拼接路径
    let pathNameFIle=path.join("./data/"+value+".txt");
    //  返回一个布尔值  判断文件是否存在     fs模块的路径 ./路径是以启动文件的地址为初始
    const bols = fs.existsSync(pathNameFIle);
    // 读取文件的绝对地址
    let dataFile = path.resolve(__dirname,"../"+pathNameFIle)
    // 返回值
    return {
        bols,
        dataFile
    }
};

// 写入文件函数
const writePath =(value, dataFile)=>{    
    fs.writeFile(dataFile, JSON.stringify(value),()=>{

    });
};

module.exports={
    bol,
    writePath
};

在pathFie.js中,自定义方法bol,传入参数value,即前端输入框输入的数字,将其作为名称并拼接为完整的相对路径,通过fs的方法判断该条路径是否存在,同时使用path的方法得到绝对路径,因为如果文件不存在要新建文件写入数据时需要用到绝对路径。判断完后返回布尔值(文件是否存在)和绝对路径。需要时调用该方法判断文件是否存在然后进行相应操作。

然后自定义第二个方法writePath,当文件不存在时调用该方法进行数学计算。

然后将两个方法都导出,使其它文件可以引入。

controlles模块:

其中的controlles.js文件只做对数据的操作,首先引入modules的方法,因为原方法得到的是对象所以我们可以同时进行解构赋值:

// controlles.js
const { bol, writePath } = require("../modules/pathFile");  // 判断和写入文件
const { math } = require("../modules/math");    // 计算数学

自定义方法factorFile 用if-else语句执行相应的方法:

// controlles.js
const factorFile = (req, res) => {
    let { value } = req.body;
    let { bols, dataFile } = bol(value);
    //有就读取返回数据,没有就写入并计算返回数据
    if (bols) {
        // 读取地址
        res.sendFile(dataFile)
    } else {
        // 没有就要计算并写入
        let data = math(value);
        writePath(data, dataFile)
        res.send(data)
    }
};

然后将该方法导出,便于主目录app.js调用:

// controlles.js
module.exports = {
    factorFile,
};

在主目录app.js中导入modules.js文件:

const express= require("express");
const app = express();
app.listen("8080",()=>{ console.log("8080端口启动")});

app.use(express.static("./public"));  // 设置静态资源文件夹
app.use(require("cors")());  // 设置跨域
app.use(express.urlencoded({extend:true}));  // 解析post请求
app.use(express.json());

// app.js目录--默认导出一个对象 解构赋值
// 引入controlles中导出的模块
const {factorFile}  = require("./controlles/controlles.js");  
app.post("/factor",factorFile);

views模块:

// index.html
<body>
    <input id="txt" type="text" placeholder="请输入数字"> <br/>
    <button id="box">提交</button>
    <ul id="list"></ul>
    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
    <script>
        box.onclick = () => {
            axios({
                method: "post",
                url: "http://localhost:3000/factor",
                data: {
                    value: txt.value.trim(),
                }
            }).then(res => {
                let html = ""
                res.data.forEach(item => {
                    html += `
                    <li> ${item}</li>
                    `
                })
                list.innerHTML = html
                console.log(res)
            })
        }

    </script>
</body>

结果:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Laker 23

要秃啦,支持一下嘛~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值