当前位置: 首页 > Web前端 > HTML5

教你从零开始写一个简单的VUE--模板

时间:2023-04-05 23:46:53 HTML5

教程目录1.教你从零开始写一个简单的VUE2。教你从零开始写一个简单的VUE--template你好,我回来了,上一篇教你写一个简单的VUE,实现了VUE的数据驱动视图渲染模板,以及更新到页。简单的带你了解VUEProcess这样一个数据驱动的视图框架的工作原理,今天给大家讲讲一个前端框架最核心的部分---模板,代码还是放在最后文章,模板分类请随意下载在介绍我们实现的模板语言之前,我们先来了解一下,现在市面上比较流行的模板语言:PHP/ASP/JSP风格<%if(list.length){%>

    <%for(n=0;n
  1. <%=list[n]%>
  2. <%}%>
<%}%>这是最接近js的语法成一门语言,比较直观,但是由于有<>分隔符,对IDE不太友好,不容易格式化成mustcache样式{{#iflist.length}}
    {{#eachlistitem}}
  1. {{item}}
  2. {{/each}}
{{/if}}这是默认语法artTemplate,高级语法有限,通常很难自定义扩展DSL风格的语法首先介绍一下什么是DSL。DSL的全称是DomainSpecificLanguage/DSL。它用于解决领域中的一类问题。比如Vue中的v-xxx,Vue称之为指令,实际上是一个DSL,用来解决模板语法等问题。由于该模板相当于HTML语法中的一个标签属性,对IDE友好,不会影响格式。手术。Vue的模板语法相当于DSL语法和mustcache风格的结合。逻辑控制部分使用DSL语法,输出显示部分使用mustcache风格。模板语法,根据上一节的说明,我们使用DSL风格的语法。下面是我们用来测试的模板。我们使用最简单的配置方式,将模板写在script标签中。可以看到我们定义了几个DSL,分别是dsl-if、dsl-for、dsl-html分别用于判断、循环和直接输出html,使用mustcache作为字符串输出语法。当然,这只是一种简单的模板DSL语言。主要是为了阐述思路。真正的模板需要更多的模板语法。具体可以参考VUE文档模板解析成为AST。首先解释一下什么是AST。AST的全称是抽象语法树(abstractsyntaxtreeTree),是对源代码的抽象语法结构的树状表示。每个源码都可以抽象成AST,比如我们常用的js、css、json等,都可以解析成AST,模板解析成AST。对模板的html结构进行解析,变成一棵具有结构、关系、属性的抽象树。这样方便我们后面对模板进行多次处理,减少多次解析字符串带来的损失,同时它变成了一个树的数据结构会更方便我们的遍历。大家可以搜索一下AST的优缺点。这里就不展开说明了,上面的字符串模板解析后会变成下面的AST,可以看到字符串模板变成了一个对象数组,每个obj代表一个节点,里面包含了属性,类型,父类-对象的子关系、使用的DSL等。这可以看作是我们模板的一个中间状态,为我们进一步的处理打下基础。AST被转换为模板函数。联系上一篇文章。其实模板函数的构造也是类似的,基本都是将函数字符串拼接起来,然后通过Function对象转化为函数。成为函数后,只需要传入相应的数据即可。,该函数将返回一个用模板数据呈现的html字符串。下面是例子中通过AST得到的一个函数体,然后使用newFunction,就变成了一个真正的函数。至于这个函数体的解释,我会放在后面的具体实现中,来解释结合数据和模板函数生成html。由于这篇文章主要讲的是模板的实现,所以数据部分还是使用了延续上一篇文章的绑定。当初始化或数据发生变化时,响应函数会重新调用与数据关联的模板函数生成新的html。重新渲染。上面我们已经讲解了模板的开发思路。主要总结就是把string模板转成ast,ast转成模板函数,然后结合数据进行html生成和渲染。具体实现方法在本教程中先进行讲解。方法是思想的实现,而不是完全vue的实现方法。Vue是一个完整的框架,里面涉及的东西很多。我们的实现是为了让大家更好的理解Vue的原理,并不是为了完全实现字符串模板变成ASTpart1.模板预处理:由于字符串模板是人为处理的,在编写的时候可能会出现标签不匹配,标签未闭合等问题,所以我们需要先做一些预处理来去除这些干扰,方法有很多种,比如通过一些语法分析工具进行解析,这里我们采用比较简单的方式来处理,代码如下(/src/core/render.js):可以看到我创建了一个div标签,然后把字符串模版放到里面,让浏览器解析模版,然后我们通过innerHTML去除前后空格,取出来,这样字符串模板被处理。备注:根据vue的规则,一个模板只有一个根节点,所以我们取childNodes[0]2.生成ast:我们在上面对字符串模板进行了预处理,然后我们需要将字符串模板转化为ast,代码比较长。有兴趣的可以看看/src/compiler/ast/parse.js。下面说说分析思路。分析使用正则表达式和String.replace(regExt,fn),正则表达式为/<(?:"[^"]*"['"]*|'[^']*'['"]*|[^'">])+>/g,解析出标签和标签上的属性,然后按照生成模板函数的思路,就是递归遍历ast树,针对不同的类型调用不同的生成函数节点和不同的NSL,最后将它们组合成模板函数字符串。代码如下(/src/compiler/compiler-helper.js):可以看出处理函数处理了DSL和不同的标签类型,然后返回一个辅助函数的调用,比如_i,_f,_c等等,这里辅助函数实际上是在调用模板函数的时候调用的。下面我们说明一个辅助函数_c。这个辅助函数的作用是生成节点。可以看到调用这个函数后,对应的ast节点实际生成了,变成了dom节点,会插入子节点。通过众多辅助函数的递归嵌套调用,最终的模板函数可以与数据结合渲染出真正的dom节点。说一个比较详细的知识点就是辅助函数的调用。我们知道,上面的辅助函数调用在生成的时候其实是一个字符串,然后通过newFunction变成了一个真正的函数。那么问题来了。我们知道,newFunction的作用域在运行时是和代码隔离的,它不能调用_c、_f等辅助函数,如何实现调用呢?这里使用了一个我们很少使用的关键字。很多书都不推荐这个关键字,因为它的作用是修改with代码块的范围。如果被滥用,代码的逻辑将不可控。不过这个关键字在模板函数中有奇效,可以方便的将当前代码作用域的规定传递给模板函数,从而在模板函数中调用运行时作用域中的函数。可以看一下上一节生成的模板函数字符串,会发现它被整个with(that){}包裹起来了。模板函数运行时,直接传入当前作用域即可。代码如下:Combinedata至此,我们生成了一个模板函数。通过传入数据并运行模板函数,我们可以生成dom。代码如下:我们可以直接使用以data为作用域的compiler_helper,直接调用模板函数生成dom,再结合我们第一篇写的数据监控,就可以实现一个简单的数据驱动视图.至此,我们的VUE模板的基本实现就介绍完了。上面的实现并不完整,只是实现了一些简单的语法,大家可以下载代码继续补充。仔细想想可能会发现上面的模板有问题,就是如果数据中的其中一个值发生变化,整个模板就得重新编译重新渲染,其实很性能消耗。这其实就是我下篇文章要讲的模板渲染的效率。首先提出几个关键词virtualdom,diff算法,最小化渲染,吊一下大家的胃口。哈哈,我会在下一篇文章中全面介绍。看完下一篇,你会对市面上现有的数据驱动框架的模板部分有个全面的了解~下一篇更精彩~~敬请关注最后附上源码点我,各位嘉宾给个星呗~~