根据数据和模板动态生成页面+列表的动态渲染

非原创

本文转自https://github.com/a415432669/-front_end_notebook/tree/master/Node/day6/%E6%96%87%E6%A1%A3

根据数据和模板动态生成页面

1.根据规则去解析链接,并且获取ID或者时索引值

//请求路径:http://127.0.0.1/movies/0
let index = req.pathObj.base;

2.根据索引获取数据

let movies = [
         {
            name:"雪暴",
            brief:"电影《雪暴》讲述了在一座极北的边陲小镇,一伙穷凶极恶、作案手法老到的悍匪为抢夺黄金,打劫运金车,并借助大雪掩盖了所有犯罪痕迹。为了探求真相,警察王康浩暗地里搜集证据,熟悉地形,终于在一场灾难级的暴雪降临时,与谋财害命的悍匪发生了惊心动魄的正面对决……",
            author:"张震"
         },{
             name:"少年的你",
             brief:"陈念(周冬雨 饰)是一名即将参加高考的高三学生,同校女生胡晓蝶(张艺凡 饰)的跳楼自杀让她的生活陷入了困顿之中。胡晓蝶死后,陈念遭到了以魏莱(周也 饰)为首的三人组的霸凌,魏莱虽然表面上看来是乖巧的优等生,实际上却心思毒辣,胡晓蝶的死和她有着千丝万缕的联系。",
             author:"周冬雨 "
         }
     ]
let pageData = movies[index]

3.根据模板渲染页面

res.render(movies[index],'./template/index.html')

4.底层需要实现渲染函数,通过正则匹配,找到需要修改的地方进行一一的修改。

function render(options,path){
    fs.readFile(path,{encoding:"utf-8",flag:"r"},(err,data)=>{
        if(err){
            console.log(err)
        }else{
            console.log(data)
            let reg = /\{\{(.*?)\}\}/igs
            let result;
            while(result = reg.exec(data)){
                //去除2边的空白
                let strKey = result[1].trim()
                let strValue = options[strKey]
                data = data.replace(result[0],strValue)
            }
​
            this.end(data)
        }
    })
}

列表的动态渲染

1. 定义了列表循环的标记

{%for {stars} %}
<li>
<h4>姓名:{
   
   {item}}</h4>
</li>
{%endfor%}

2.正则匹配标记

let reg = /\{\%for \{(.*?)\} \%\}(.*?)\{\%endfor\%\}/igs

匹配到2个组

  1. 第一个组时匹配出变量的key值
  2. 第二个组匹配出需要生成的每一项的内容

3. 匹配替换每一项的内容

while(result = reg.exec(data)){
    let strKey = result[1].trim();
    //通过KEY值获取数组内容
    let strValueArr = options[strKey]
    let listStr = ""
    strValueArr.forEach((item,i)=>{
    //替换每一项内容里的变量
        listStr = listStr + replaceVar(result[2],{"item":item})
    })
    data = data.replace(result[0],listStr)
}

4.通过eval函数,将字符串的表达式计算出来

let strValue = eval('options.'+strKey);

完整代码:

index.js

let LcApp = require('./lcApp');

let app = new LcApp();
// 好处:保护路径,防止被修改
app.staticDir = '/abc';

app.on('/', (req, res) => {
    res.setHeader("Content-type", "text/html;charset=utf-8");
    res.end("这是首页");
    // <img src='./abc/1.jpg' />
})

app.on('/dlam', (req, res) => {
    if (req.pathObj.base == "index") {
        res.end("dlam");
    } else {
        res.end("dlamaaaa");
    }
})

app.on('/movies', (req, res) => {

    let movies = [{
        name: "千与千寻",
        brief: "震惊父母变禽兽,其女被迫在洗浴中心工作",
        author: "宫崎骏",
        stars: ["小明", "千寻", "老婆婆"]
    }, {
        name: "葫芦娃",
        brief: "一帮兄弟在大庭广众之下打一女人,围观群众竟拍手叫好",
        author: "忘了",
        stars: [{
            name: "葫芦娃七兄弟",
            gender: "男"
        }, {
            name: "蛇精",
            gender: "女"
        }]

    }];

    let index = req.pathObj.base;
    // res.end(movies[index].name);
    if (index == 0) {
        res.render(movies[index], './template/index0.html');
    } else {
        res.render(movies[index], './template/index1.html');
    }

})


app.run(80, () => {
    console.log("服务器启动:", "http://127.0.0.1");
})

lcApp.js

let http = require('http');
let path = require('path');
let url = require('url');
let fs = require('fs');

class LcApp {
    constructor() {
        this.server = http.createServer();
        this.reqEvent = {};
        this.staticDir = 'static';
        this.server.on('request', (req, res) => {
            // 解析路径
            let pathObj = path.parse(req.url);
            console.log(pathObj);
            if (pathObj.dir in this.reqEvent) {
                res.render = render;
                res.setHeader("Content-type", "text/html;charset=utf-8");
                req.pathObj = pathObj;
                this.reqEvent[pathObj.dir](req, res);
            } else if (pathObj.dir == this.staticDir) {
                res.setHeader("content-type", this.getContentType(pathObj.ext))
                //从服务器磁盘中读取文件,并输出到响应对象中
                let rs = fs.createReadStream('./static/' + pathObj.base)
                rs.pipe(res)
            } else {
                res.setHeader("Content-type", "text/html;charset=utf-8");
                res.end("<h1>404!找不到页面</h1>")
            }
        })
    }
    on(url, fn) {
        this.reqEvent[url] = fn;
    }
    run(port, callback) {
        this.server.listen(port, callback)
    }
    // getContentType(extName) {
    //     switch (extName) {
    //         case ".jpg":
    //             return "image/jpeg";
    //         case ".html":
    //             return "text/html;charset=utf-8";
    //         case ".js":
    //             return "text/javascript;charset=utf-8";
    //         case ".json":
    //             return "text/json;charset=utf-8";
    //         case ".gif":
    //             return "image/gif";
    //         case ".css":
    //             return "text/css"
    //     }
    // }
}

function render(options, path) {
    // fs.readFile(path, {
    //     encoding: "utf-8",
    //     flag: "r"
    // }, (err, data) => {
    //     if (err) {
    //         console.log(err);
    //     } else {
    //         console.log(data);
    //         let reg = /\{\{(.*?)\}\}/igs;
    //         while (result = reg.exec(data)) {
    //             // 去除两边空格
    //             let strKey = result[1].trim()
    //             let strValue = options[strKey];
    //             data = data.replace(result[0], strValue);
    //         }

    //         this.end(data);
    //     }
    // })
    fs.readFile(path, {
        encoding: "utf-8",
        flag: "r"
    }, (err, data) => {
        if (err) {
            console.log(err);
        } else {
            data = replaceArr(data, options);
            data = replaceVar(data, options);
        }
    })
}


function replaceVar(data, options) {
    let reg = /\{\{(.*?)\}\}/igs;
    let result;
    console.log(options);
    while (result = reg.exec(data)) {
        // 去除两边空格
        let strKey = result[1].trim()
        // eval是将字符串转化成 JS表达式 进行运行
        let strValue = eval('options.' + strKey);
        data = data.replace(result[0], strValue);
    }

    return data;
}

function replaceArr(data, options) {
    // 匹配循环的变量,并且替换循环的内容
    let reg = /\{\%for \{(.*?)\} \%\}(.*?)\{\% endfor \%\}/igs;
    while (result = reg.exec(data)) {
        // 去除两边空格
        let strKey = result[1].trim()
        // 通过KEY值获取数组内容
        let strValueArr = options[strKey];
        let listStr = "";
        strValueArr.forEach((item, i) => {
            // 替换每一项内容里的变量
            listStr = listStr + replaceVar(result[2], {
                "item": item
            });
        });
        data = data.replace(result[0], listStr);
    }

    return data;
}

module.exports = LcApp;

index0.js

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>小鱼儿</title>
</head>

<body>
    <h1>标题:{
   
   { name }}</h1>
    <h3>我是一个保安:{
   
   { brief }}</h3>
    <p>上班为了下班:{
   
   { author }}</p>
    <h4>主演</h4>
    <ul>
        {%for {stars} %}
        <li>
            <h4>姓名:{
   
   {item}}</h4>
        </li>
        {% endfor %}
    </ul>
</body>

</html>

index1.js

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>小鱼儿</title>
</head>

<body>
    <h1>标题:{
   
   { name }}</h1>
    <h3>我是一个保安:{
   
   { brief }}</h3>
    <p>上班为了下班:{
   
   { author }}</p>
    <h4>主演</h4>
    <ul>
        {%for {stars} %}
        <li>
            <h4>姓名:{
   
   {item.name}}</h4>
            <p>性别:{
   
   {item.gender}}</p>
        </li>
        {% endfor %}
    </ul>
</body>

</html>

猜你喜欢

转载自blog.csdn.net/small_rain_/article/details/112480294