微信扫一扫抽红包在哪里做网站做网站和app哪类商标

diannao/2026/1/19 13:44:18/文章来源:
微信扫一扫抽红包在哪里做网站,做网站和app哪类商标,个体工商户网站备案,广州番禺新楼盘最新房价解析模板编译template的背后发生了什么一、#x1f4d1;初识模板编译1、vue组件中使用render代替template2、模板编译总结二、✏️感受模板编译的美1、with语法#xff08;1#xff09;例子展示#x1f330;#xff08;2#xff09;知识点归纳三、#x1f4c8;编译模板1… 解析模板编译template的背后发生了什么一、初识模板编译1、vue组件中使用render代替template2、模板编译总结二、✏️感受模板编译的美1、with语法1例子展示2知识点归纳三、编译模板1、编译模板碎碎念2、编译模板过程1初始化一个npm环境2安装编译器3新建新文件4了解缩写函数5编译插值6编译表达式7编译属性和动态属性8编译条件9编译循环10编译事件11编译v-model3、模板编译总结四、组件渲染/更新过程1、初识组件渲染/更新2、组件渲染/更新过程1初次渲染过程1解析模板为render函数2触发响应式3执行render函数生成vnode2更新过程1更新过程细述2完成流程图3异步渲染3、小结五、✔️结束语依稀记得我们在vue时最上方总是有一个 template 包围着。而很多时候我们也没有很在意的去意识到 template/template 究竟是什么。在今天的这篇文章中就带大家一起来了解模板编译 template 的背后究竟发生了什么事情 一起来了解模板编译的纸短情长 一、初识模板编译 1、vue组件中使用render代替template template 即模板。模板是 vue 开发中最常用的部分即与vue的使用关联最紧密的原理。它不是 html 它有指令、有插值、也有 JS 表达式那它到底是什么呢我们来看个例子。 在 vue 中定义一个组件通常会使用 template 模板字符串来定义一个组件。比如 Vue.component(heading,{template:xxx })一般情况下模板的定义是上面这种情况。同时在程序编译期间模板会将 template 的这种字符串类型编译成 render 函数。 但是呢在有些复杂的情况下可能就不能用 template 函数了这个时候会考虑直接用 render 函数来定义一个组件。比如 Vue.component(heading,{render: function(createElement){return createElement(h this.level, //tag props[ //childrencreateElement(a,{attrs:{name:headerId,href:# headerId}},this is a tag)])} })就像上面这样子我们也可以通过使用一个 render 函数来定义一个组件。 2、模板编译总结 看完上面的例子我们来做个小结✨ template即模板。这个模板会编译成 render 函数其中 render 函数用的是 with 语法。过程模板→ render 函数→ vnode →组件渲染和更新过程。vue 组件可以用 render 函数代替 template 。React 一直都用 render 没有模板这里仅作知识补充不做讲解。 二、✏️感受模板编译的美 1、with语法 1例子展示 先来了解模板编译中一个很重要的知识点 with 语法。下面先用一个例子来展示with语法与普通语法的不同。 不使用with语法执行程序时 const obj {a: 100, b: 200}console.log(obj.a) console.log(obj.b) console.log(obj.c) //undefined使用with语法执行程序时 //使用with能改变 {} 内自由变量的查找方式 // 将 {} 内自由变量当作 obj 的属性来查找 with(obj){console.log(a)console.log(b)console.log(c) //会报错 }2知识点归纳 看完上面with语法的例子我们来对 with 语法做一个知识点归纳。 with 语法会改变 {} 内自由变量的查找规则当作 obj 属性来查找如果在当前 {} 内找不到匹配的 obj 属性就会报错with 要谨慎使用它打破了作用域规则会让其易读性变差。 三、编译模板 1、编译模板碎碎念 在前面中我们讲过模板它不是 html 它有指令、有插值、也有JS表达式它能实现判断、也能实现循环。 试想一下模板为什么不是 html 思考一下假如你在写程序时能用 html 写出一个判断或者循环出来吗答案自然时不行的。 所以说 html 只是一个静态的标签语言你写什么它就显示什么它没有办法实现一个逻辑或者做循环和判断。 因此对于前端浏览器而言只有 JS 才能实现判断和循环等各种逻辑功能。 所以模板一定是转换为某种 JS 代码之后才进行运行的。而这个模板怎么转换成 js 代码的这个过程就称为编译模板。 那这个模板是怎么转的呢接下来我们来看下编译模板的过程。 2、编译模板过程 1初始化一个npm环境 首先先建立一个新文件可以命名为 vue-template-complier-demo 。之后用以下命令行初始化一个npm的环境 npm init -y2安装编译器 npm 安装模板编译器。命令行如下 npm install vue-template-compiler --save3新建新文件 在根目录下初始化新建一个 index.js 文件并引入 vue-template-compiler 。代码如下 //引入vue-template-compiler const compiler require(vue-template-compiler)// 编译 const res compiler.compile(template) console.log(res.render)接下来我们就来看下模板中的插值、表达式、属性和动态属性等等类型的编译到底是怎么样的 4了解缩写函数 以下vue源码中的缩写函数先了解将在下面的讲解中用到。 // 从 vue 源码中找到缩写函数的含义 function installRenderHelpers (target) {target._c createElement;target._o markOnce;target._n toNumber;target._s toString;target._l renderList;target._t renderSlot;target._q looseEqual;target._i looseIndexOf;target._m renderStatic;target._f resolveFilter;target._k checkKeyCodes;target._b bindObjectProps;target._v createTextVNode;target._e createEmptyVNode;target._u resolveScopedSlots;target._g bindObjectListeners;target._d bindDynamicKeys;target._p prependModifier; }5编译插值 //引入vue-template-compiler const compiler require(vue-template-compiler)// 插值 const template p{{message}}/p // with(this){return createElement(p,[createTextVNode(toString(message))])} // h - vnode // createElement - vnode// 编译 const res compiler.compile(template) console.log(res.render)编译以上内容打印结果如下 从上图中可以看到插值类型的模板最终被编译成一个 with 语句并且这个 with 语句的参数都指向了 this 。 同时大家可以看到里面有一个 _c _v _s。那这几个元素是什么呢 这个就是上面第四点中提到的 vue 源码中的缩写函数。 _c 对应的就是源码中的 createElement _v 对应的就是源码中的 createTextVNode _s 对应的就是源码中的 toString 。 所以以上编译后的 with 语句 with(this){return _c(p,[_v(_s(message))])} 事实上就是 with(this){return createElement(p,[createTextVNode(toString(message))])} 。 以上这个语句的意思为编译创建一个 p 元素之后呢 p 元素就没有子元素了于是就创建它的文本节点 message 同时 message 是字符串的形式存在因此要进行 toString 。 额外再补充一个知识点 createElement 其实就等于我们平常所说的 h 函数返回的是一个 虚拟DOM 节点。 以上就是一个插值模板编译的过程下面再用几个例子让大家熟悉。 6编译表达式 //引入vue-template-compiler const compiler require(vue-template-compiler)// 表达式 const template p{{flag ? message : no message found}}/p // with(this){return _c(p,[_v(_s(flag ? message : no message found))])}// 编译 const res compiler.compile(template) console.log(res.render)编译以上内容打印结果如下 依据上面插值的分析方法我们来分析表达式的模板编译过程。 表达式编译后的结果返回了一个虚拟 DOM 节点同样地查询 vue 源码中的缩写函数我们可以发现 with(this){return _c(p,[_v(_s(flag ? message : no message found))])} 最终的结果等于 with(this){return createElement(p,[createTextVnode(toString(flag ? message : no message found))])} 。 先创建了一个 p 元素之后 p 元素没有子元素了于是创建文本节点最终 toString 三目表达式里面的内容。 7编译属性和动态属性 //引入vue-template-compiler const compiler require(vue-template-compiler)// 属性和动态属性 const template div iddiv1 classcontainerimg :srcimgUrl//div// with(this){return _c(div, // {staticClass:container,attrs:{id:div1}}, // [ // _c(img,{attrs:{src:imgUrl}})])}// 编译 const res compiler.compile(template) console.log(res.render)编译以上内容打印结果如下 依据上面的分析方法我们来分析属性和动态属性的模板编译过程。 属性和动态属性编译后的结果返回了一个虚拟 DOM 节点同样地查询 vue 源码中的缩写函数我们可以发现 with(this){return _c(div,{staticClass:container,attrs:{id:div1}},[_c(img,{attrs:{src:imgUrl}})])} 最终的结果等于 with(this){return createElement(div,{staticClass:container,attrs:{id:div1}},[createElement(img,{attrs:{src:imgUrl}})])} 。 此时我们可以看到返回的 vnode 节点中包含 class 名字 container 。此时 div 有一个 id 选择器这个 id 选择器是该 div 的一个属性于是就通过attrs来表示。 最外层结束后里面还有一层 img 。 img 可以视其为跟 div 一样的标签于是先创建 img 元素又因为 img 绑定了一个具体的值就像是 div 里面绑定了 id 选择器。所以在创建完 img 的值之后继续用 attrs 来传递 img 所绑定的值。 8编译条件 // 条件 const template divp v-ifflag aA/pp v-elseB/p/div// with(this){return _c(div,[(flag a)?_c(p,[_v(A)]):_c(p,[_v(B)])])}编译以上内容打印结果如下 依据上面的分析方法我们来分析条件的模板编译过程。 对于条件来说首先是先创建一个 div 元素之后呢模板编译把 v-if 和 v-else 分割成一个三目表达式的方式来进行编译。 9编译循环 // 循环 const template ulli v-foritem in list :keyitem.id{{item.title}}/li/ul// with(this){return _c(ul,_l((list),function(item){return _c(li,{key:item.id},[_v(_s(item.title))])}),0)} 编译以上内容打印结果如下 依据上面的分析方法我们来分析循环的模板编译过程。 对于以上循环来说首先会创建一个 ul 元素之后查询 _l 的缩写函数我们知道它是 renderlist 所以 list 列表会被 renderList 函数进行编译。 最后渲染后的 item 被当作函数的参数进行传递并列返回对应 item 的 li 列表元素。 10编译事件 // 事件 const template button clickclickHandlersubmit/button// with(this){return _c(button,{on:{click:clickHandler}},[_v(submit)])}编译以上内容打印结果如下 依据上面的分析方法我们来分析事件的模板编译过程。 对于事件来说首先会创建一个 button 元素之后 click 即 v-on:click 会被编译成 on:{click:clickHandler} 。最后是 _v 即 createTextVNode 。创建一个 submit 的文本节点将 click 的内容提交上去。 11编译v-model // v-model const template input typetext v-modelname // 主要看 input 事件 // with(this){return _c(input,{directives:[{name:model,rawName:v-model,value:(name),expression:name}],attrs:{type:text},domProps:{value:(name)},on:{input:function($event){if($event.target.composing)return;name$event.target.value}}})}编译以上内容打印结果如下 依据上面的分析方法我们来分析双向绑定v-model的模板编译过程。 对于 v-model 来说主要看的是 input 事件。 v-model 的背后绑定的是 name 和 value 这两个语法糖。之后通过 attrs 去创建 类型type 为 text 的属性。 最终是 input 事件 input 事件绑定 $event 最后 name 的值就等同于 $event.target.value 这样数据就实现了双向绑定。 3、模板编译总结 看完上述的内容我们来对模板编译做个小结 1从render函数到vnode 模板编译后是一个 render 函数执行 render 函数后返回一个 vnode 2vnode到patch和diff 基于 vnode 的基础上再执行 patch 和 diff 3模板编译工具 在平常的开发中我们可以使用 webpack 、 vue-loader 等构建工具在开发环境下编译模板。 四、组件渲染/更新过程 1、初识组件渲染/更新 讲完上完的内容我们再来讲一个与编译模板关联性很强的知识点组件渲染/更新过程。 一个组件从渲染到页面上开始再到修改 data 去触发更新数据驱动视图其背后的原理是什么又需要掌握哪些要点呢 事实上组件在渲染之前会先进行模板编译模板 template 会编译成 render 函数。 之后就是数据的监听了这就要谈到响应式数据。vue的响应式通过操作 Object.defineProperty() 去监听 getter 和 setter 方法来使得数据实时更新。 监听完数据之后就是执行 render 函数生成 vnode 。 到了 vnode 即 vdom 这一步之后会进行 patch(elem,vnode) 和 patch(vnode,newVnode) 的比较。 关于响应式原理和vdom的解读如有需要可以查看我的前两篇文章进行学习这里不再展开细述~ 2、组件渲染/更新过程 组件渲染和更新过程主要经过以下三个步骤初次渲染过程→更新过程→异步渲染。 接下来就这三个步骤进行一一讲解。 1初次渲染过程 初次渲染过程即组件第一次渲染是怎么样的怎么把模板渲染到页面上。具体有以下三个步骤 解析模板为 render 函数触发响应式监听 data 属性 getter 和 setter 执行 render 函数生成 vnode 进行 patch(elem,vnode) 。 下面就这三个步骤来进行一一讲解。 1解析模板为render函数 在开发环境下解析模板为 render 函数一般是由 vue-loader 这个插件来处理的。还有一种情况就是用户直接用 cdn 的方式引入 vuejs 的文件进行本地代码练习这种情况下解析模板为 render 函数就是在浏览器环境运行的。 小知识了解完我们来看下这个步骤。 解析模板为 render 函数即解析 template 为 render 函数这个就是上述文章中说的编译模板。 2触发响应式 在编译完模板之后 render 函数有了我们来开始监听 data 属性。 监听 data 属性这个时候我们就需要触发响应式也就是渲染数据。 那在这个阶段怎么渲染数据呢 这个阶段我们需要执行 render 函数 render 函数会触发 getter 方法因为数据没有进行更新只是进行渲染。只有在进行渲染的时候才会操作 setter 方法。 3执行render函数生成vnode 最后当数据渲染完毕后就会执行第一步生成的 render 函数然后生成虚拟 DOM 节点 vnode 之后进行 patch(elem,vnode) 。 2更新过程 1更新过程细述 更新过程即 data 修改之后组件是怎么更新的。 在这个阶段呢将会修改 data 并且触发 setter 注意在此之前 data 在 getter 中已经被监听。 触发完 setter 之后重新执行 render 函数并生成 newVnode 最后进行 patch(vnode, newVnode) 的diff比较。 2完成流程图 接下来我们用一张流程图来完整的回顾渲染和更新的过程。 3异步渲染 在渲染和更新结束之后我们的程序可能还有可能会发生多个程序同时加载这就涉及到一个异步渲染问题。 异步渲染问题我们用 $nextTick 来作为例子讲解。 假设我们现在要实现一个功能当我们点击按钮时打印出列表的项数。这个时候我们大多人可能会这么操作。 templatediv idapp!-- ref的设置时为了方便后续可以用来取节点的DOM元素 --ul reful1li v-for(item, index) in list :keyindex{{item}}/li/ulbutton clickaddItem添加一项/button/div /templatescript export default {name: app,data() {return {list: [a, b, c]}},methods: {addItem() {this.list.push(${Date.now()})this.list.push(${Date.now()})this.list.push(${Date.now()})// 获取 DOM 元素const ulElem this.$refs.ul1console.log( ulElem.childNodes.length )}} } /script 此时浏览器的显示效果如下 细心的小伙伴已经发现浏览器并没有按照我们所想的打印。当页面上的列表显示 6项 内容时此时控制台只打印 3项 当显示 9项 时此时控制台直接只打印 6项 。 那这究竟时为什么呢 其实当我们点击的那一刻 data 发生变化但是 DOM 并不会立刻进行渲染。所以等到我们点击完成的时候获取的元素还是原来触发的内容而不会增添上新的内容。 那我们所期望的是当点击之后立刻触发 DOM 渲染并拿到最新的值。这个时候就需要用到 nextTick 。具体代码如下 script export default {name: app,data() {return {list: [a, b, c]}},methods: {addItem() {this.list.push(${Date.now()})this.list.push(${Date.now()})this.list.push(${Date.now()})// 1. 异步渲染$nextTick 待 DOM 渲染完再回调// 即NextTick函数会在多次data修改完并且全部DOM渲染完再触发仅在最后触发一次// 2. 页面渲染时会将 data 的修改做整合this.$nextTick(() {// 获取 DOM 元素const ulElem this.$refs.ul1console.log( ulElem.childNodes.length )})}} } /script我们通过给获取 DOM 元素的代码外面再嵌套一层 $nextTick 函数来达到我们想要的效果。在此过程中当我们点击结束后 data 的值发生变化此时 $nextTick 会等待DOM全部渲染完成之后再进行回调。 最终浏览器的打印效果如下 所以也就是说 $nextTick 通过汇总 data 的修改最后再一次性更新视图。 这样可以减少 DOM 的操作次数大大的提高了性能。 3、小结 经过上述一系列的讲解我们可以把内容分割成以下两个要点 要理解清楚渲染和响应式、渲染和模板编译、渲染和vdom的关系。要理解组件渲染/更新的过程初次渲染过程→更新过程→异步渲染。 五、✔️结束语 从模板编译到组件渲染更新过程我们了解了整个 template 背后的全过程。相信通过本文的学习大家对模板编译有了一个更深的认识。 关于模板编译的内容就讲到这里啦如有不理解或文章有误欢迎评论区留言或私信我交流~ 关注公众号 星期一研究室 不定期分享学习干货更多有趣的专栏待你解锁~如果这篇文章对你有帮助记得 点个赞加个关注 再走哦~我们下期见

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/90325.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

做网站必备软件自己做的网站怎么发到网上

我试图在PHP中发送HTML电子邮件,但它始终显示电子邮件程序中电子邮件的源代码。但它应该将html电子邮件呈现为html,而不是将源代码显示为电子邮件内容。尝试使用sendmail发送/发送html电子邮件,但显示电子邮件的源代码我把我的邮件是这样的&a…

外卖网站建设价钱房产网二手房

文章目录 1.二叉树层序遍历 2.完全二叉树的判断 文章内容 1.二叉树层序遍历 二叉树的层序遍历需要一个队列来帮助实现。 我们在队列中存储的是节点的地址,所以我们要对队列结构体的数据域重定义, 以上代码 从逻辑上来讲就是1入队,1出队&am…

兰州网站建设模板云南网官网

一、背景 qemu单步调试arm64 linux kernel-CSDN博客介绍了如何单步调试kernel, 但是我们经常写一些测试driver, driver的部分如何调试? 二、环境准备 调试driver 就需要准备一个简单的driver, 这里用最简单的hello world来演示如何调试&am…

如何知道一个网站是谁做的wordpress 搭网站

什么是metadata表 Metadata表即Hudi元数据表,是一种特殊的Hudi表,对用户隐藏。该表用于存放普通Hudi表的元数据信息。Metadata表包含在普通Hudi表内部,与Hudi表是一一对应关系。 元数据表的作用 ApacheHudi元数据表可以显著提高查询的读/写性能。元数据表的主要目的是消…

东莞万江网站制作台州网站搜索优化

优先级类型 React内部对于优先级的管理,贯穿运作流程的4个阶段(从输入到输出),根据其功能的不同,可以分为3种类型: 1 )fiber优先级(LanePriority) 位于 react-reconciler包,也就是L…

免费做图片的网站有哪些网站建设风格

原文在简书首发:http://www.jianshu.com/p/badf412db4e7lua-cmsgpack是一个开源的MessagePack实现方式、纯C的库,没有任何其它依赖,编译后可以直接被lua调用,目前主要支持Lua5.1/5.2/5.3 版本。1、什么是MessagePack?-…

高端网站定制站广西网站建设渠道

目录 一、前言 二、代码 一、前言 有些时候我们需要开启或暂停一些服务,比如说开启Apach或暂停MySQL服务等,最近工作中也开发了这方面的功能,记录下来怎样使用PHP语言来开启或暂停Apache、MySQL服务的运行状态。 这种方法也适用其他服务。…

淘客网站备案wordpress能开发商城网站吗

1. 元件基本介绍 2. 基础元件的使用 3. 表单型元件的使用 4. 菜单与表格元件的使用 使用:如果想使用某个元件,我们只需要将它从元件库中拖入画布摆放即可。 - 对齐:默认情况下,两个矩形元件并排摆放,中间的边框为两…

ps制作网站背景邹城网站定制

一个三电源切换电路 电路描述 1、Q1、Q2为NMOS,Q3、Q4和Q5为PMOS管,D1为二极管。 2、BAT1和BAT2为电池,BAT2的容量比BAT1大,VIN_5V为外部电源,VOUT为输出,给系统供电。 3、VOUT会从优先级高的电源取电&a…

重庆专业企业建设网站网络营销方案范文3篇

原文链接&#xff1a;https://blazor-university.com/components/capturing-unexpected-parameters/捕获意外参数源代码[1]之前我们已经看到了如何使用特定名称声明参数和级联参数。例如&#xff0c;一个将 <img> 元素包装在一些自定义 HTML 中的自定义组件。<div cla…

企业官方网站如何做蓝v认证上海住房和城乡建设局网站

111转载于:https://www.cnblogs.com/zoeeying/p/10139131.html

自助建站的一般流程西安旅游攻略必去景点

宝塔一键修改mysql数据库存放路径&#xff0c;更改默认数据目录脚本&#xff01;该shell脚本仅限于宝塔bt.cn linux面板使用&#xff0c;希望对有需要的朋友有所帮助&#xff0c;如有问题请留言&#xff01;主要参数功能:1.默认修改数据库存放路径sh mysql_Transfer.sh2.还原数…

郑州做网站外包的公司十堰吧

在 Linux 中开启 Flask 项目持续运行 在部署 Flask 项目时&#xff0c;情况往往并不是那么理想。默认情况下&#xff0c;关闭 SSH 终端后&#xff0c;Flask 服务就停止了。这时&#xff0c;您需要找到一种方法在 Linux 服务器上实现持续运行 Flask 项目&#xff0c;并在服务器…

网站编排百度热度榜搜索趋势

在 CMake 中&#xff0c;target_include_directories 命令用于向特定目标&#xff08;如可执行文件或库&#xff09;添加包含目录&#xff0c;以便编译器能够找到特定目标所需的头文件。 基本语法 target_include_directories(target_name[SYSTEM] [BEFORE]directory1[direct…

珠海做网站公司有哪些wordpress 删除demo

一、前言 上周工作遇到了一个需求&#xff0c;同步多个省份销号数据&#xff0c;解绑微信粉丝。分省定时将销号数据放到SFTP服务器上&#xff0c;我需要开发定时任务去解析文件。因为是多省份&#xff0c;服务器、文件名规则、数据规则都不一定&#xff0c;所以要做成可配置是有…

天梭手表官方网站word怎么做网页

schoolcms // 版本信息 const THINK_VERSION 3.2.3; ThinkPHP3.2完全开发手册 http://document.thinkphp.cn/manual_3_2.html

做网站需要绑定电脑ip吗中信建设四川分公司招聘

一、缩短访问路径 1、如图访问该文件路径 没有缩短之前&#xff0c;访问的路径是 http://localhost/zerg_new/public/index.php/api/v1/banner/1 缩短后&#xff0c;访问的路径是 http://z_new.cn/api/v1/banner/1 2、缩短路径步骤 本机apache配置&#xff0c;小编使用的…

邢台网站制作哪里有建设完网站成功后需要注意什么

锯齿形斜纹组织图&#xff1a; 分析&#xff1a; 前半齿长度k&#xff0c;表示山谷到山峰的列数&#xff0c;也就是锯齿的宽度&#xff1b; 锯齿飞数s&#xff0c;表示山峰到山峰的行数&#xff0c;也就是锯齿的高度。 起始点相差4格&#xff0c;也就是第一部分整体向上移动…

企业网站seo手机南京网站建设与维护

什么叫静态链表&#xff1f;——用顺序表模拟链表&#xff0c;就叫做静态链表 第一列相当于数据域data&#xff0c;第二列相当于指针域next&#xff0c; 第一行&#xff08;0&#xff09;相当于头结点&#xff08;头结点的数据域不放数据&#xff09; &#xff08;a&#xff…

南昌网站建设模板技术公司注册免费

openai用tf实现的真的看不懂&#xff0c;大佬的世界… PPO的详细细节 1. 奖励模型和策略的价值头将 query 和 response 的连接作为输入 奖励模型和策略的价值头 不 仅仅查看响应。相反&#xff0c;它将 query 和 response 连接在一起&#xff0c;作为 query_response def ge…