模板引擎

Posted grani

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了模板引擎相关的知识,希望对你有一定的参考价值。

模板引擎,“ 引擎 ” 两字一直让我觉得其高大上,今天要好好梳理

以一个例子证明其用处:点击按钮发送 ajax 请求获取后台服务器数据,再将数据显示在网页的空 table标签 中

Node 实现的小服务器

var http = require(‘http‘)
var server = http.createServer()
server.on(‘request‘, function (req, res) {
    res.setHeader(‘Access-Control-Allow-Origin‘,‘*‘) //跨域资源共享,允许任何源的请求

    //json数组,模拟数据库数据
    var data = `[{
        "name": "MicKong",
        "age": "20",
        "sex":"male",
        "tel":"123456",
        "address":"Beijing"
    },
    {
        "name": "May",
        "age": "18",
        "sex":"female",
        "tel":"123456",
        "address":"Hong Kong"
    }]`
    res.end(data)  //响应data数据
})

server.listen(3000, function () {
    console.log(‘Server running...‘)
})

 

html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<table id="list"></table> <!--将数据显示在这个空的table标签中-->
<input type="button" id="btn" value="获取数据">
<script>
    document.getElementById(btn).onclick = function () {
        var xhr = new XMLHttpRequest()
        xhr.open(get, http://127.0.0.1:3000)
        xhr.send()
        xhr.onreadystatechange = function () {
            var xhr = new XMLHttpRequest()
            xhr.open(get, http://127.0.0.1:3000)
            xhr.send()
            xhr.onreadystatechange = function () {
                if (xhr.readyState !== 4) return
                console.log(JSON.parse(xhr.responseText)); //先输出到控制台看是否成功获取到了数据
            }
        }
    }
</script>
</body>
</html>

浏览器成功获取到数据

技术分享图片

 

接下来数据不是要输出到控制台而是通过DOM操作直接显示到当前网页

xhr.onreadystatechange = function () {
    if (xhr.readyState !== 4) return
    var data = JSON.parse(xhr.responseText);
    var table = document.getElementById(‘list‘)
    for (var i = 0; i < data.length; i++) {
        var tr = document.createElement(‘tr‘)
        var td1 = document.createElement(‘td‘)
        td1.innerHTML = data[i].name
        tr.appendChild(td1)

        var td2 = document.createElement(‘td‘)
        td2.innerHTML = data[i].age
        tr.appendChild(td2)

        var td3 = document.createElement(‘td‘)
        td3.innerHTML = data[i].sex
        tr.appendChild(td3)
        /* 略...... */
        table.appendChild(tr)
    }
    document.body.appendChild(table)
}

DOM 操作时创建行再创建列,列添加到行中,行添加到表格......可以看到数据的渲染十分繁琐,更别说数据多的时候,当然可以使用 for...in 和 tr.innerHTML = ‘<td></td>‘ 的方式,但这仍不够轻松便捷。此时可使用模板引擎,帮我们完成数据的渲染

 

模版引擎实际上就是一个 api,本质就是字符串解析替换。模版引擎有很多种,使用方式大同小异,目的为了更容易地将数据渲染到 html 中

这里使用 art-template 模板引擎,可以在 github 下载也可用 npm 下载 

技术分享图片

该命令会下载到当前目录,下载后会有 node_modules 文件夹,node_modules/art-template/lib/template-web.js

node_modules 文件夹不要改动

 

使用步骤

? 下载后用 script 标签将模板引擎引入到 html 中

? 准备一个模板

? 准备一个数据

? 通过模板引擎提供的一个函数将模板和数据整合得到渲染结果 html

? 将渲染结果的 html 设置到默认元素的 innerHTML 中

 

引入 template-web.js 并准备一个模板,根据 template-web.js文档 里的语法创建模板

  技术分享图片

<script src="template-web.js"></script> <!-- 引入template-web.js -->
<script id="temp" type="text/x-template-web"> <!--each内部的$value拿到的是当前被遍历的元素-->
{{each target}}
<tr>
    <td>{{ $value.name }}</td>
    <td>{{ $value.age }}</td>
    <td>{{ $value.sex }}</td>
    <td>{{ $value.tel }}</td>
    <td>{{ $value.address }}</td>
</tr>
{{/each}}
</script>

模板可以作为字符串放在 js 里,也可写在 table 标签内 ,甚至 div 中,之所以放在 script标签 里,是因为 script标签 的 type 如果不为 " text/javascript " 的话就不会当作 js 代码执行,标签里的内容不但能换行又有着色显示,还不会显示到网页中,是个很好的模板存放地。type 值为只要不为 " text/javascript " 即可,x是自定义的意思,后面跟上所用的模板引擎名字,这样写仅是为了见名知意 

 

准备数据,用模板引擎的API将模板和数据整合,并将结果赋值给想要渲染元素的 innerHTML

template( ‘ script标签的id ‘ , {对象} )

xhr.onreadystatechange = function () {
    if (xhr.readyState !== 4) return
    var data = JSON.parse(xhr.responseText)

    //模板所需的数据
    var content = {target: data} //target名可随意,但要与模板里each循环名字一致
    //借助模板引擎的API渲染数据
    var result = template(‘temp‘, content) //通过模板引擎提供的一个函数将模板和数据整合得到渲染结果 html
    document.getElementById(‘list‘).innerHTML = result //将渲染结果的html设置到table的innerHTML中
}

点击按钮,ajax 获取数据后利用 art-template 成功将数据渲染到网页中

技术分享图片

 

模板引擎只关心自己能认识的模板标记语法

{{ }} ,其他内容则不会改动

<script id="temp" type="text/x-template-web">
    大家好我叫{{ name }}
    今年{{ age }}岁
    喜欢{{each hobby}} {{ $value }} {{/each}}
</script>
<script>
    //template函数放入模板和数据
    var result = template(temp, {
        name: Paul,
        age: 20,
        hobby: [fruits,songs,sports]
    })
    console.log(result)
</script>

技术分享图片

 

Node 中使用模板引擎

模板引擎最早就是诞生于服务器领域,后来才发展到了前端。art-template 是个 js模板引擎,不但可在浏览器中使用,也可在 Node 中使用

? 安装 npm install art-template,npm安装好后才能在代码中用 require() 加载

? 在需要使用的文件模块中加载 art-template

? 查文档,使用模板引擎的API

 

   技术分享图片

template.render ( ‘ 模板字符串 ‘ ,{对象} ) 

var template = require(‘art-template‘)

var result = template.render(‘hello {{ name }}‘,{
    name:‘Paul‘
})

console.log(result)

技术分享图片

 

接下来要在 html 中编写模板语法(也就是把整个 html 作为上面的 ‘ 模板字符串 ’ ),在服务端渲染后再响应给浏览器

demo.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{{ title }}</title>
</head>
<body>
<h3>{{ title }}</h3>
<ul>
    <li>姓名:{{ name }}</li>
    <li>年龄:{{ age }}</li>
    <li>爱好:{{each hobby}} {{ $value }} {{/each}}</li>
</ul>

<script>
    var str = {{ title }} //在字符串内模版引擎依旧能识别{{}}
</script>
</body>
</html>

 

后台读取 demo.html 文件,通过 template模块的 render() 方法将模板和数据整合并返回给浏览器

var http = require(‘http‘) //http模块创建服务器
var template = require(‘art-template‘) //加载art-template模块
var fs = require(‘fs‘) //加载fs模块,为了读取文件
var server = http.createServer()
server.on(‘request‘, function (req, res) {
    fs.readFile(‘./demo.html‘,function (err,data) {
        if(err)
            return res.end(‘Can not find demo.html‘)
        //读取的文件内容是二进制,但render要的是字符串
        var result = template.render(data.toString(),{
            name:‘Paul‘,
            age: 20,
            hobby:[‘songs‘,‘sports‘,‘food‘],
            title:‘个人信息‘
        })
        res.end(result)
    })
})

server.listen(3000, function () {
    console.log(‘Server running...‘)
})

浏览器访问,直接拿到渲染后的结果

技术分享图片

如果是客户端异步请求后渲染的,右键查看源代码则找不到相关内容,如果在页面源代码中找得到的就是服务端渲染的

客户端渲染不利于 SEO 搜索引擎优化但速度快用户体验友好,服务端渲染可被爬虫抓取,客户端异步渲染很难被爬虫抓取,所以真正的网站是两者结合来做的

以上是关于模板引擎的主要内容,如果未能解决你的问题,请参考以下文章

Laravel之视图和Blade模板引擎

JavaScript中template模板引擎

百度JS模板引擎

Python中verbaim标签使用详解

在 EJS 模板引擎中,如何“包含”页脚?

VSCode自定义代码片段——.vue文件的模板