当前位置: 首页 > news >正文

临沂建设公司网站wordpress大图简约主题

临沂建设公司网站,wordpress大图简约主题,宁德市住房和城乡建设局新网站,wordpress 媒体选项在 Vue 里渲染一块内容#xff0c;会有以下步骤及流程#xff1a; 第一步#xff0c;解析语法#xff0c;生成AST 第二步#xff0c;根据AST结果#xff0c;完成data数据初始化 第三步#xff0c;根据AST结果和DATA数据绑定情况#xff0c;生成虚拟DOM 第四步…在 Vue 里渲染一块内容会有以下步骤及流程 第一步解析语法生成AST 第二步根据AST结果完成data数据初始化 第三步根据AST结果和DATA数据绑定情况生成虚拟DOM 第四步将虚拟DOM 生成真正的DOM插入到页面中进行页面渲染。 那怎么理解这个流程呢 一、解析语法生成AST AST 语法树实际就是抽象语法树Abstract Syntax Tree是指通过构建语法树的形式将源代码中的语句映射到树中的每一个节点上。 DOM 结构树也是AST中的一种把HTML DOM语法解析并生成最终页面。 我们详细看看这个过程 1、捕获语法 在生成AST的过程中会涉及到编译器的原理, 会经过以下过程 1、语法分析 语法分析的任务是在词法分析的基础上将单词序列组合成各类语法短语。如 程序、语句、表达式等。语法分析程序判断源程序在结构上是否正确 如 v-if / v-for 这样的指令 也有这样的自定义 DOM 标签还有click/props 这样的简化绑定语法。需要将它们一一解析出来并相应地进行后续处理。2、语义分析 语义分析是审查源程序有无语义错误为代码生成阶段收集类型信息一般类型检查也会在这个过程中进行。如我们绑定了某个不存在的变量或者事件又或者是使用了某个未定义的自定义组件等都会在这个阶段进行报错提示。 (3) 、生成 AST 在Vue 里语法分析、语义分析基本上是通过正则的方式来处理生成 AST其实就是将解析出来的元素、指令、属性、父子节点关系等内容进行处理得到一个 AST 对象以下是简化后的源码   /*** HTML编译成AST对象*/ export function parse(template: string,options: CompilerOptions ): ASTElement | void {// 返回AST对象// 篇幅原因一些前置定义省略// 此处开始解析HTML模板parseHTML(template, {expectHTML: options.expectHTML,isUnaryTag: options.isUnaryTag,shouldDecodeNewlines: options.shouldDecodeNewlines,start(tag, attrs, unary) {// 一些前置检查和设置、兼容处理此处省略// 此处定义了初始化的元素AST对象const element: ASTElement {type: 1,tag,attrsList: attrs,attrsMap: makeAttrsMap(attrs),parent: currentParent,children: []};// 检查元素标签是否合法不是保留命名if (isForbiddenTag(element) !isServerRendering()) {element.forbidden true;process.env.NODE_ENV ! production warn(Templates should only be responsible for mapping the state to the UI. Avoid placing tags with side-effects in your templates, such as ${tag} , as they will not be parsed.);}// 执行一些前置的元素预处理for (let i 0; i preTransforms.length; i) {preTransforms[i](element, options);}// 是否原生元素if (inVPre) {// 处理元素元素的一些属性processRawAttrs(element);} else {// 处理指令此处包括v-for/v-if/v-once/key等等processFor(element);processIf(element);processOnce(element);processKey(element); // 删除结构属性// 确定这是否是一个简单的元素element.plain !element.key !attrs.length;// 处理ref/slot/component等属性processRef(element);processSlot(element);processComponent(element);for (let i 0; i transforms.length; i) {transforms[i](element, options);}processAttrs(element);}// 后面还有一些父子节点等处理此处省略}// 其他省略});return root; }2、DOM 元素捕获 假如我们需要捕获一个div元素再生成一个div元素。 有一段模板我们可以对它进行捕获 diva111/ap222span333/span /p /div捕获后我们可以得到这样一个对象 divObj {dom: {type: dom,ele: div,nodeIndex: 0,children: [{type: dom,ele: a,nodeIndex: 1,children: [{ type: text, value: 111 }]},{type: dom,ele: p,nodeIndex: 2,children: [{ type: text, value: 222 },{type: dom,ele: span,nodeIndex: 3,children: [{ type: text, value: 333 }]}]}]} }; 这个对象保存了我们需要的一些信息: HTML元素里需要绑定哪些变量因为变量更新的时候需要更新该节点内容。 以怎样的方式来拼接是否有逻辑指令如v-if、v-for等 哪些节点绑定了什么监听事件是否匹配一些常用的事件能力支持 Vue 会根据 AST 对象生成一段可执行的代码我们看看这部分的实现 // 生成一个元素 function genElement(el: ASTElement): string {// 根据该元素是否有相关的指令、属性语法对象来进行对应的代码生成if (el.staticRoot !el.staticProcessed) {return genStatic(el);} else if (el.once !el.onceProcessed) {return genOnce(el);} else if (el.for !el.forProcessed) {return genFor(el);} else if (el.if !el.ifProcessed) {return genIf(el);} else if (el.tag template !el.slotTarget) {return genChildren(el) || void 0;} else if (el.tag slot) {return genSlot(el);} else {// component或者element的代码生成let code;if (el.component) {code genComponent(el.component, el);} else {const data el.plain ? undefined : genData(el);const children el.inlineTemplate ? null : genChildren(el, true);code _c(${el.tag}${data ? ,${data} : // data}${children ? ,${children} : // children});}// 模块转换for (let i 0; i transforms.length; i) {code transforms[i](el, code);}// 返回最后拼装好的可执行的代码return code;} }3、模板引擎赋能 通过以上介绍或许大家会说原本就是一个div经过 AST 生成一个对象最终还是生成一个div这不是多余的步骤吗 其实 在这个过程中我们可以实现一些功能 排除无效 DOM 元素并在构建过程可进行报错 使用自定义组件的时候可匹配出来 可方便地实现数据绑定、事件绑定等功能 为虚拟 DOM Diff 过程打下铺垫 HTML 转义预防 XSS 漏洞 通用的模板引擎能处理很多低效又重复的工作例如浏览器兼容、全局事件的统一管理和维护、模板更新的虚拟 DOM 机制、树状组织管理组件。这样我们知道了模板引擎都做了什么事情后就可以区分 Vue 框架提供的能力和我们需要自行处理的逻辑可以更专注于业务开发。 二、虚拟DOM 虚拟 DOM 大概可分成三个过程 第一步用 JS 对象模拟 DOM 树得到一棵虚拟 DOM 树。 第二步当页面数据变更时生成新的虚拟 DOM 树比较新旧两棵虚拟 DOM 树的差异。 第三步把差异应用到真正的 DOM 树上。 1、用 JS 对象模拟 DOM 树 为什么要用到虚拟 DOM 因为一个真正的 DOM 元素非常庞大拥有很多的属性值而实际上我们并不是全部都会用到通常包括节点内容、元素位置、样式、节点的添加删除等方法。所以我们通过用 JS 对象表示 DOM 元素的方式可以大大降低了比较差异的计算量。 我们来看一下 VNode 源码只有以下20来个属性   tag: string | void; data: VNodeData | void; children: ?ArrayVNode; text: string | void; elm: Node | void; ns: string | void; context: Component | void; // rendered in this components scope key: string | number | void; componentOptions: VNodeComponentOptions | void; componentInstance: Component | void; // component instance parent: VNode | void; // component placeholder node // strictly internal raw: boolean; // contains raw HTML? (server only) isStatic: boolean; // hoisted static node isRootInsert: boolean; // necessary for enter transition check isComment: boolean; // empty comment placeholder? isCloned: boolean; // is a cloned node? isOnce: boolean; // is a v-once node? asyncFactory: Function | void; // async component factory function asyncMeta: Object | void; isAsyncPlaceholder: boolean; ssrContext: Object | void; fnContext: Component | void; // real context vm for functional nodes fnOptions: ?ComponentOptions; // for SSR caching devtoolsMeta: ?Object; // used to store functional render context fordevtools fnScopeId: ?string; // functional scope id support2 、比较新旧两棵虚拟 DOM 树的差异 虚拟 DOM 中差异对比是很关键的一步当状态变更的时候重新构造一棵新的对象树。然后用新的树和旧的树进行比较记录两棵树差异。这样的差异需要记录 需要替换掉原来的节点 移动、删除、新增子节点 修改了节点的属性 对于文本节点的文本内容改变 下图我们对比两棵 DOM 树得到的差异有 p 元素插入了一个 span 元素子节点 原先的文本节点挪到了 span 元素子节点下面 3、应用差异到真正的 DOM 树 通过前面的示例我们知道差异记录要应用到真正的 DOM 树上需要进行一些操作例如节点的替换、移动、删除文本内容的改变等。 在 Vue 中是怎么进行 DOM Diff 呢 简单看这段代码感受下 虽然代码里很多函数没贴出来但其实看函数名也可以大概理解都是什么作用例如updateChildren、addVnodes、removeVnodes、setTextContent等。   // 对比差异后更新 const oldCh oldVnode.children; const ch vnode.children; if (isDef(data) isPatchable(vnode)) {for (i 0; i cbs.update.length; i) cbs.update[i](oldVnode, vnode);if (isDef((i data.hook)) isDef((i i.update))) i(oldVnode, vnode); } if (isUndef(vnode.text)) {if (isDef(oldCh) isDef(ch)) {if (oldCh ! ch)updateChildren(elm, oldCh, ch, insertedVnodeQueue, removeOnly);} else if (isDef(ch)) {if (process.env.NODE_ENV ! production) {checkDuplicateKeys(ch);}if (isDef(oldVnode.text)) nodeOps.setTextContent(elm, );addVnodes(elm, null, ch, 0, ch.length - 1, insertedVnodeQueue);} else if (isDef(oldCh)) {removeVnodes(elm, oldCh, 0, oldCh.length - 1);} else if (isDef(oldVnode.text)) {nodeOps.setTextContent(elm, );} } else if (oldVnode.text ! vnode.text) {nodeOps.setTextContent(elm, vnode.text); } if (isDef(data)) {if (isDef((i data.hook)) isDef((i i.postpatch))) i(oldVnode, vnode); }三、数据绑定 在 Vue 中最基础的模板语法是数据绑定。 例如 div{{ message }}/div这里使用插值表达式{{}}绑定了一个message的变量开发者在 Vue 实例data中绑定该变量 new Vue({data: {message: test} });最终页面展示内容为divtest/div。那这是怎么做到的呢 1、 数据绑定的实现 这种使用双大括号来绑定变量的方式我们称之为数据绑定。 数据绑定的过程其实不复杂 (1) 、解析语法生成 AST (2) 、根据 AST 结果生成 DOM (3) 、将数据绑定更新至模板 这个过程是 Vue 中模板引擎在做的事情我们来看看上面在 Vue 里的代码片段div/div我们可以通过 DOM 元素捕获解析后获得这样一个 AST 对象   divObj {dom: {type: dom,ele: div,nodeIndex: 0,children: [{ type: text, value: }]},binding: [{ type: dom, nodeIndex: 0, valueName: message }] };我们在生成 DOM 的时候添加对message的监听数据更新时会找到对应的nodeIndex更新值 // 假设这是一个生成 DOM 的过程包括 innerHTML 和事件监听 function generateDOM(astObject) {const { dom, binding [] } astObject;// 生成DOM这里假设当前节点是baseDombaseDom.innerHTML getDOMString(dom);// 对于数据绑定的来进行监听更新baseDom.addEventListener(data:change, (name, value) {// 寻找匹配的数据绑定const obj binding.find(x x.valueName name);// 若找到值绑定的对应节点则更新其值。if (obj) {baseDom.find([data-node-index${obj.nodeIndex}]).innerHTML value;}}); }// 获取DOM字符串这里简单拼成字符串 function getDOMString(domObj) {// 无效对象返回if (!domObj) return ;const { type, children [], nodeIndex, ele, value } domObj;if (type dom) {// 若有子对象递归返回生成的字符串拼接const childString ;children.forEach(x {childString getDOMString(x);});// dom对象拼接生成对象字符串return ${ele} data-node-index${nodeIndex}${childString}/${ele};} else if (type text) {// 若为textNode返回text的值return value;} }这样我们就能在message变量更新的时候通过该变量关联的引用来自动更新对应展示的内容。而要知道message变量什么时候进行了改变我们需要对数据进行监听。 2、数据更新监听 加粗样式 我们能看到上面的简单代码描述过程中使用的数据监听方法是用了addEventListener(data:change, Function)的方式。 在 Vue 中数据更新的时候就执行了模板更新、watch、computed 等一些工作主要是依赖了Getter/Setter。而 Vue3.0 将使用Proxy的方式来进行   Object.defineProperty(obj, key, {enumerable: true,configurable: true,// getterget: function reactiveGetter() {const value getter ? getter.call(obj) : val;if (Dep.target) {dep.depend();if (childOb) {childOb.dep.depend();if (Array.isArray(value)) {dependArray(value);}}}return value;},// setter最终更新后会通知set: function reactiveSetter(newVal) {const value getter ? getter.call(obj) : val;if (newVal value || (newVal ! newVal value ! value)) {return;}if (process.env.NODE_ENV ! production customSetter) {customSetter();}if (getter !setter) return;if (setter) {setter.call(obj, newVal);} else {val newVal;}childOb !shallow observe(newVal);dep.notify();} });Vue 中大多数能力都依赖于模板引擎包括组件化管理、事件管理、Vue 实例、生命周期等相信只要理解了 AST、虚拟 DOM、数据绑定相关的机制后再去翻阅 Vue 源码 了解更多的能力就不是问题了。
http://www.hkea.cn/news/14335403/

相关文章:

  • 金华哪里有做网站的公司4000-262-调用wordpress文章
  • 网站黏度wordpress建站 ftp
  • 深圳做网站要为什么做织梦网站时图片出不来
  • 好的建网站的书籍网站 流程 工具
  • 浙江网站建设dyfwzxseo关键词优化公司官网
  • 宝安区网站建设培训interidea 做网站
  • 中国做二手房最大的网站wordpress 主题制作全
  • 织梦网做企业网站需要授权吗wordpress中的portfolio
  • 末年人免费观看网站亳州市建设工程质量监督站网站
  • 沈阳市建设局网站docker实际企业解决方案
  • 天津网站建设价位小程序开发方案
  • 做网站域名是赠送的吗大公司的网站都找谁设计
  • 俄语网站叫什么yandex哪些企业会考虑做网站
  • 米拓cms 网站模板在哪无锡论坛网本地网站
  • 比特币交易所网站开发企业商务网站建设
  • 星沙做淘宝店铺网站智慧校园官网
  • 腾讯免费网站建设别人的网站是怎么找到的
  • 抚顺网站建设招聘wordpress伪静
  • 营销型网站的特征wordpress主题修改颜色教程
  • 专业制作网站是什么全国建设工程造价管理系统
  • 广州网站推广¥做下拉去118cr公司怎么推广网络营销
  • 网站地图什么时候提交好成都手机模板建站
  • 寻找项目做的网站添加友情链接的技巧
  • 网站开发和小程序开发区别交友软件开发
  • 怎么免费申请网站免费的客户管理app
  • canvas做的手机网站东莞淘宝网站建设
  • 网站建设与管理期末考试题wordpress 如何仿站
  • 做网站界面设计大小微信显示wordpress
  • 西安专业做网站的生活服务信息类网站建设
  • 国外做3d模型的网站关于加强网站建设