js网站模板素材 网站模板套用教程

模板是什么?前端模板怎么实现?很多朋友可能不太了解这个,下面这篇文章就给大家介绍一下前端模板的原理和简单的实现代码。前端模板的开发模板可以说是前端开发最常用的工具之一。将页面的固定内容提取到一个模板中,将服务器返回的动态数据填充到模板中的预留坑中。最后,组...

模板是什么?前端模板怎么实现?很多朋友可能不太了解这个,下面这篇文章就给大家介绍一下前端模板的原理和简单的实现代码。

前端模板的开发

模板可以说是前端开发最常用的工具之一。将页面的固定内容提取到一个模板中,将服务器返回的动态数据填充到模板中的预留坑中。最后,组装一个完整的页面html字符串,并交给浏览器进行解析。

模板可以大大提高开发效率。如果没有模板,开发人员将不得不手动拼写字符串。

var tpl = & # 8216& ltp & gt’+用户名+‘& lt/p >’;

$(‘body & # 8217).追加(第三方物流);

在近几年的前端开发过程中,模板也发生了变化:

1。php模板JSP模板

早期没有前端分离的时代,前端只是后端项目中的一个文件夹。在这个时期,php和java提供了自己的模板引擎。以jsp为例:java web应用的页面通常是。JSP文件,内容大部分是html和一些模板自己的语法。它们本质上是纯文本,但既不是html也不是java。

语法:index.jsp

& lthtml & gt

& lthead & gt& lttitle & gtHello World & lt/title >& lt/head >

& ltbody & gt

你好世界!& ltbr/>;

& lt%

out . println(“你的IP地址是”+request . getremote addr());

% & gt

& lt/body >

& lt/html >

在这个时期,模板引擎往往是服务器编译模板字符串并生成html字符串给客户端。

2。八字胡通用模板

随着2009年node的发布,JavaScript也可以实现服务器的功能,大大方便了开发者。小胡子和车把模板的诞生方便了前端开发者。这两个模板都是由JavaScript实现的。从此,前端模板可以同时在服务器和客户端上运行。然而,在大多数使用场景中,js根据服务器异步获取的数据嵌入模板,以生成新的dom插入页码。对前端和后端开发都非常有利。

Mustache语法:index.mustache

& ltp & gt用户名:{ { user.name } } & lt/p >

{{#if (user.gender === 2)}}

& ltp & gt女性

{{/if}}

3。React里的JSX,Vue里的模板

接下来,在新一代中,vue中的模板编写与之前的模板有所不同,功能更加强大。在客户端和服务器端都可以使用,但是在使用场景上有很大的差距:页面根据数据变化,模板生成的dom也随之变化,这对模板的性能要求很高。

Vue语法:index.vue

& ltp & gt用户名:{ { user.name } } & lt/p >

& lt模板v-if = ”user.gender = = = 2 & # 8243& gt

& ltp & gt女性

& lt/div >

由模板实现的功能

无论是从JSP到vue的模板,模板的语法越来越简单,功能越来越丰富,但基本功能是不可或缺的:

变量输出(转义/不转义):出于安全考虑,模板基本默认都会将变量的字符串转义输出,当然也实现了不转义输出的功能,慎重使用。条件判断(if else):开发中经常需要的功能。循环变量:循环数组,生成很多重复的代码片段。模板嵌套:有了模板嵌套,可以减少很多重复代码,并且嵌套模板集成作用域。

以上功能基本涵盖了大部分模板的基本功能。对于这些基本功能,我们可以探讨如何实现模板。

模板实现原理

正如标题所说,模板本质上是纯文本字符串。字符串如何操作js程序?

模板用法:

var DOM string = template(template string,data);

该引擎获取模板字符串和模板的范围,并编译它以生成完整的DOM字符串。

大多数模板具有基本相同的实现原理:

首先,模板通过各种手段剥离公共串和模板语法串,生成抽象语法树AST;然后编译模板语法片段,期间在引擎输入的变量中搜索模板变量;模板片段生成一个普通的html片段,与原来的普通字符串拼接输出。

其实模板编译逻辑并不是特别复杂。至于vue这种动态绑定数据的模板,有时间可以参考文末的链接。

实现快速简单的模板。

现在以小胡子模板为例,手动实现一个实现基本功能的模板。

模板字符串template: index.txt

& lt!DOCTYPE html & gt

& lthtml & gt

& lthead & gt

& ltmeta charset = & # 8221utf-8 ″/>

& ltmeta http-equiv = ”X-UA兼容”内容= ”IE = edge & # 8221& gt

& lttitle & gt页面标题& lt/title >

& ltmeta name = & # 8221viewport & # 8221内容= ”width =设备宽度,initial-scale = 1 ″& gt

& ltlink rel = & # 8221样式表”type = & # 8221text/CSS ”media = & # 8221屏幕”href = & # 8221***in.css & # 8221/>

& lt脚本src = & # 8221***in.js & # 8221& gt& lt/script >

& lt/head >

& ltbody & gt

& lth1 & gt熊猫模板编译

& lth2 & gt普通变量输出

& ltp & gt用户名:{ { common.username } } & lt/p >

& ltp & gtescape:{ { common . escape } } </p >

& lth2 & gt不要转义输出

& ltp & gtunescape:{ { &common.escape } } & lt/p >

& lth2 & gt输出:

& ltul & gt

{ { #每个列表}}

& lt李班= ”{ { value } } & # 8221& gt{ { key } } & lt/李& gt

{{/each}}

& lt/ul >

& lth2 & gt输出条件:

{ { # if shouldEscape } }

& ltp & gtescape { { common.escape } } & lt/p >

{{else}}

& ltp & gtunescape:{ { &common.escape } } & lt/p >

{{/if}}

& lt/body >

& lt/html >

模板对应数据:

模块.导出= {

常见:{

用户名:‘澳大利亚’,

逃:‘& ltp & gtAus & lt/p >’

},

肩景:假,

列表:[

{ key:‘一’,值:1},

{ key:‘b & # 8217,值:2},

{ key:‘c & # 8217,值:3},

{ key:‘d & # 8217,值:4}

]

};

如何使用模板:

var fs = require(“fs & # 8221);

var TPL = fs . read file sync(‘。/index . txt ’, ‘utf8 & # 8217);

var state = require(‘。/test ’);

var Panda = require(‘。/熊猫’);

Panda.render(第三方物流,州)

然后实现模板:

1.常规切割线

模板引擎得到模板字符串后,通常会使用规则切割字符串来区分哪些是静态字符串,哪些是需要编译的字符串,并生成抽象语法树(AST)。

//将未处理的字符串分割成字符组标记。

panda . prototype . parse = function(TPL){

var令牌=[];

var TPL start = 0;

var tagStart = 0;

var tagEnd = 0;

while(tag start >= 0) {

tagStart = tpl.indexOf(openTag,TPL start);

if(tag start <0)破;

//纯文本

tokens.push(新令牌(‘正文’,tpl.slice(tplStart,tag start)));

tagEnd = tpl.indexOf(closeTag,tag start)+2;

if(tagEnd <0)抛出新错误(‘{{}}标签未关闭’);

//细分js

var TPL value = TPL . slice(tag start+2,tagEnd & # 82112);

var token = this . classify js(TPL value);

tokens.push(令牌);

tplStart = tagEnd

}

//最后一段

tokens.push(新令牌(‘正文’,tpl.slice(tagEnd,TPL . length)));

返回this.parseJs(令牌);

};

在这一步中,字符串的分割通常是通过正则化来完成的,后期对字符串的检索会用到很多正则化方法。

在这个步骤中,通常可以检查模板标签的异常关闭并报告一个错误。

2.模板语法的分类

AST生成后,普通字符串不再需要管理,最后会直接输出,重点是模板语法的分类。

//专门处理模板中的js

panda . prototype . parse js = function(tokens){

var sections =[];

var nested tokens =[];

var conditions array =[];

var collector = nestedTokens

var部分;

var电流条件;

for(var I = 0;我& lttokens.lengthi++) {

var token = tokens[I];

var value = token.value

var symbol = token.type

开关(符号){

案例‘#’: {

collector.push(令牌);

sections . push(token);

if(token . action = = = ‘每个’){

collector = token . children =[];

} else if(token . action = = = ‘如果’) {

currentCondition =值;

var conditionArray

collector = condition array =[];

token . conditions = token . conditions | | conditions array;

conditionsArray.push({

条件:当前条件,

收藏家:收藏家

});

}

打破;

}

案例‘else & # 8217: {

if(sections . length = = = 0 | | sections[sections . length –1].开拍!== ‘如果’) {

抛出新错误(‘Else用法错误’);

}

currentCondition =值;

收集器=[];

conditionsArray.push({

条件:当前条件,

收藏家:收藏家

});

打破;

}

案例‘/’: {

section = sections . pop();

如果(第& amp& amp开始行动。== token.value) {

抛出新错误(‘说明标签没有关闭’);

}

if(sections . length >0){

var last section = sections[sections . length –1];

if(last section . action = = = ‘每个’){

collector = last section . chid lren;

} else if(last section . action = ‘如果’) {

conditions array =[];

collector = nestedTokens

}

}否则{

collector = nestedTokens

}

打破;

}

默认值:{

collector.push(令牌);

打破;

}

}

}

返回nestedTokens

}

在最后一步中,我们生成了ast,这里这个AST是一个分词标记数组:

[

令牌{},

令牌{},

令牌{},

]

这个令牌是每个字符串,记录了令牌的类型、动作、子令牌、条件令牌等信息。

/**

* token类代表每个分词的标准数据结构。

*/

函数令牌(类型、值、操作、子代、条件){

this.type = type

this.value = value

this.action = action

this.children =儿童;

条件=条件;

}

在这个步骤中,循环方法中的子令牌被嵌套到相应的令牌中,条件渲染子令牌被嵌套到相应的令牌中。

这一步完成后,一个具有嵌套关系的标准AST就完成了。

3.变量搜索和赋值

现在开始根据token中的变量寻找对应的值,根据对应的函数生成值串。

/**

*解析数据结构的类

*/

函数上下文(数据,父上下文){

this.data = data

this.cache = { & # 8216。’:this . data };

this.parent = parentContext

}

context . prototype . push = function(data){

返回新的上下文(数据,这个);

}

//根据字符串名称找到实变量值

Context.prototype.lookup =函数查找(名称){

name = trim(名称);

var cache = this.cache

var值;

//缓存已被查询

if(cache . hasownproperty(name)){

value = cache[name];

}否则{

var context = this,names,index,lookupHit = false

while(上下文){

//用户.用户名

if(name . index of(‘。’)& gt0) {

value = context.data

names = name . split(‘。’);

索引= 0;

而(值!= null & amp& ampindex & ltnames.length) {

if(index = = = names . length –1) {

lookupHit = hasProperty(value,names[index]);

}

value = value[names[index++]];

}

}否则{

value = context . data[name];

lookup hit = has property(context . data,name);

}

如果(lookupHit) {

打破;

}

context = context.parent

}

cache[name]= value;

}

返回值;

}

为了提高搜索效率,采用了缓存代理,每次找到的可变存储路径便于下次快速搜索。

与JavaScript编译器不同,模板引擎在找不到对应变量时会停止搜索,并无错误地返回空。

4.节点的条件呈现和嵌套

这里先说模板语法令牌和普通字符串令牌,开始统一编译生成字符串,拼接成完整的字符串。

//根据令牌和上下文混合拼接字符串输出结果。

panda . prototype . render tokens = function(token,context) {

var结果= ”;

var令牌、符号、值;

for (var i = 0,numTokens = tokens.length我& ltnumTokens++i) {

值=未定义;

token = tokens[I];

symbol = token.type

if(symbol = = = ‘#’)value = this.renderSection(token,context);

else if(symbol = = = ‘& amp’)value = this . unescapedvalue(token,context);

else if(symbol = = = ‘=’)value = this.escapedValue(token,context);

else if(symbol = = = ‘正文’)value = this . raw value(token);

如果(值!==未定义)结果+=值;

}

返回结果;

}

5.绘制页面

页面字符串已经被解析,可以直接输出:

panda . prototype . render = function(TPL,state) {

if(类型tpl!== ‘字符串’) {

返回新错误(‘请输入一个字符串!’);

}

//解析字符串

var token = this . cache[TPL]?tokens:this . parse(TPL);

//解析数据结构

var context =上下文的状态实例?状态:新上下文(状态);

//呈现模板

返回this.renderTokens(令牌,上下文);

};

浏览器解析页面的输出字符串,然后页面出现。

以上只是一个简单的模板实现,没有经过系统测试,仅供学习使用,源码入口。成熟的模板引擎具有完整的异常处理、变量搜索和分析、范围替换、优化渲染、断点调试等功能。

摘要

前端模板可以做的事情有很多。很多框架集成了模板的功能,配合css、js等混合编译,生成解析好的样式,绑定成功事件的dom。

此外,还有许多方法可以实现模板。本文的实现参考了小胡子源代码。对模板标签中的代码进行解析,但是通过代码片段分类和变量搜索来执行,把纯字符串的代码变成解释器执行的代码。

另外可以看看vue,一个可以实现双向绑定的模板,空。

本文来自吃鸡只用平底锅投稿,不代表舒华文档立场,如若转载,请注明出处:https://www.chinashuhua.cn/24/530265.html

打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
() 0
上一篇 05-02
下一篇 05-02

相关推荐

  • 什么是网站,带你了解网站的功能和作用

    网站是什么?网址是什么?抛开技术术语,网站是人机交流的工具。它由三部分组成,即网站三要素、域名、空和源文件。它们共同构成了一个可以浏览和使用的网站。网站的源文件有哪些?网站源文件包含网页的设计、前端代码、后台程序、网站数据等。网站空房间是做什么用的?网站空

    2023-07-29 07:41:02
    763 0
  • 怎么建公司网站,搭建公司网站所需资料

    网站开发要有一个过程。有了网站开发流程步骤之后,我们就可以按照流程步骤有逻辑有规划的开发自己的网站了,但是还是有很多小伙伴不明白“什么是网站开发流程?”我们来看看网站的开发过程。网站建设网站建设流程1.准备网站空。网站空房间也是服务器,主要用来存储网站程序文

    2023-07-29 06:42:01
    868 0
  • 企业建网站的详细步骤(企业为什么要建网站)

    很多企业和个人都想建立一个自己的网站,因为网站是互联网最基础的工具,不仅可以曝光自己的产品,还可以在网站上形成交易,让客户直接购买。而且网站的好处还不止这些,因为这篇文章的主题是教你建网站。网站的好处我就不多说了,还是占字数。我把我的想法逐字逐句打了出来,

    2023-07-29 06:17:02
    966 0
  • 名品打折网站有哪些(盘点国外9大知名折扣商品网站)

    过去,消费者只能在实体店购买打折商品,但现在随着电子商务的发展,消费者可以选择在网上购买打折商品。不过网上折扣店也是良莠不齐。为此统计了9家不仅能提供多种商品,而且折扣力度很大的国外网站,以供参考。盘点国外九大知名折扣商品网站。1.6pm.com6pm.com是一个专门销

    2023-07-28 04:30:01
    283 0

评论列表

联系我们

在线咨询: QQ交谈

邮件:admin@qq.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信