爱美容
当前位置: 首页 美容百科

数控系统不准怎么办(数控系统被锁怎么办)

时间:2023-07-01 作者: 小编 阅读量: 1 栏目名: 美容百科

在执行rendercode渲染函数生成vnode。基于HTML的模板使得将已有的应用逐步迁移到Vue更为容易。首先,JSX并不是没有学习成本的——它是基于JS之上的一套额外语法。Vue通过建立一个虚拟DOM来追踪自己要如何改变真实DOM。其实不是一个实际的DOM元素。它更准确的名字可能是createNodeDescription,因为它所包含的信息会告诉Vue页面上需要渲染什么样的节点,包括及其子节点的描述信息。“虚拟DOM”是我们对由Vue组件树建立起来的整个VNode树的称呼。

数控系统不准怎么办?数控系统被锁怎么办▉▉▉【一电一 17154833762-】▉▉▉前面两篇文章分别分享了 Vue 编译三部曲的前两曲:「 parse,template 转换为 AST」,「optimize,模型树优化」,今天小编就来说说关于数控系统不准怎么办?下面更多详细答案一起来看看吧!

数控系统不准怎么办

数控系统被锁怎么办▉▉▉【一电一 17154833762-】▉▉▉前面两篇文章分别分享了 Vue 编译三部曲的前两曲:「 parse,template 转换为 AST」,「optimize,模型树优化」。

我们先简单回顾一下前两曲。

parse: 将开发者写的 template 模板字符串转换成抽象语法树 AST ,AST 对于这里来说就是一个树状结构的 JavaScript 对象,描述了这个模板,这个对象包含了每一个元素的上下文关系。那么整个 parse 的过程是利用很多正则表达式顺序解析模板,当解析到开始标签、闭合标签、文本的时候都会分别执行对应的回调函数,来达到构造 AST 树的目的。

optimize: 深度遍历这个 AST 树,去检测它的每一棵树是不是静态节点,如果是静态节点表示生成的 DOM 永远不需要改变,这对运行时对模板的更新起到极大的优化作用,提升了运行效率。

而编译的最后一步就是把优化后的 AST 树转换成可执行的代码,即 generate生成 render code。 在执行 render code渲染函数生成 vnode。

接下来我们来看看 Vue generate 是如何将 AST 树转换为render code?。

前置知识,渲染函数

在这之前我们需要先了解一个前置的知识渲染函数,Vue 推荐在绝大多数情况下使用模板来创建你的 HTML。 然而在一些场景中,你真的需要 JavaScript 的完全编程的能力。这时你可以用渲染函数,它比模板更接近编译器。在之前的文章我们也讨论过为什么 Vue 推荐模板,但是有一些场景我们更愿意使用渲染函数?(详情戳这里)

为什么默认推荐的模板语法,引用一段时间 Vue 官网的原话如下: 任何合乎规范的 HTML 都是合法的 Vue 模板,这也带来了一些特有的优势:

对于很多习惯了 HTML 的开发者来说,模板比起 JSX 读写起来更自然。这里当然有主观偏好的成分,但如果这种区别会导致开发效率的提升,那么它就有客观的价值存在。 基于 HTML 的模板使得将已有的应用逐步迁移到 Vue 更为容易。 这也使得设计师和新人开发者更容易理解和参与到项目中。 你甚至可以使用其他模板预处理器,比如 Pug 来书写 Vue 的模板。

有些开发者认为模板意味着需要学习额外的 DSL (Domain-Specific Language 领域特定语言) 才能进行开发——我们认为这种区别是比较肤浅的。首先,JSX 并不是没有学习成本的——它是基于 JS 之上的一套额外语法。同时,正如同熟悉 JS 的人学习 JSX 会很容易一样,熟悉 HTML 的人学习 Vue 的模板语法也是很容易的。最后,DSL 的存在使得我们可以让开发者用更少的代码做更多的事,比如 v-on 的各种修饰符,在 JSX 中间实现对应的功能会需要多得多的代码。

更抽象一点来看,我们可以把组件区分为两类:一类是偏视图表现的 (presentational),一类则是偏逻辑的 (logical)。我们推荐在前者中使用模板,在后者中使用 JSX 或渲染函数。这两类组件的比例会根据应用类型的不同有所变化,但整体来说我们发现表现类的组件远远多于逻辑类组件。

在深入渲染函数之前,了解一些浏览器的工作原理是很重要的。以下面这段 HTML 为例:

<div><h1>My title</h1>Some text content<!-- TODO: Add tagline --></div>复制代码

上述 HTML 对应的 DOM 节点树如下图所示:

每个元素都是一个节点。每段文字也是一个节点。甚至注释也都是节点。在之前的编译三部曲第一步中我们也介绍了,template生成 AST时,会把元素、文字、注释都创建成节点描述对象。

  • type = 1的基础元素节点
  • type = 2含有expression和tokens的文本节点
  • type = 3的纯文本节点或者是注释节点

    child = {type: 1,tag:"div",parent: null,children: [],attrsList: []};child = {type: 2,expression: res.expression,tokens: res.tokens,text: text};child = {type: 3,text: text};child = {type: 3,text: text,isComment: true};复制代码

    每一个节点都是页面的一个部分。就像家谱树一样,每个节点都可以有孩子节点、兄弟节点 (也就是说每个部分可以包含其它的一些部分)。

    高效地更新所有这些节点会是比较困难的,不过所幸你不必手动完成这个工作。你只需要告诉 Vue 你希望页面上的 HTML 是什么,这可以是在一个模板里:

    <h1>{{ blogTitle }}</h1>复制代码

    或者一个渲染函数里:

    render: function (createElement) {return createElement('h1', this.blogTitle)}复制代码

    在这两种情况下,Vue 都会自动保持页面的更新,即便是 blogTitle 发生了改变。

    Vue 通过建立一个虚拟 DOM 来追踪自己要如何改变真实 DOM。请仔细看这行代码:

    return createElement('h1', this.blogTitle)复制代码

    createElement到底会返回什么呢? 其实不是一个实际的 DOM 元素。它更准确的名字可能是 createNodeDescription,因为它所包含的信息会告诉 Vue 页面上需要渲染什么样的节点,包括及其子节点的描述信息。我们把这样的节点描述为“虚拟节点 (virtual node)”,也常简写它为“VNode”。“虚拟 DOM”是我们对由 Vue 组件树建立起来的整个 VNode 树的称呼。那createElement是如何映射成虚拟DOM的了?

    createElement

    export function createElement (context: Component,tag: any,data: any,children: any,normalizationType: any,alwaysNormalize: boolean): VNode | Array<VNode> {...return _createElement(context, tag, data, children, normalizationType)}复制代码

    createElement 函数就是对 _createElement 函数的一个封装,它允许传入的参数更加灵活,在处理这些参数后,调用真正创建 VNode 的函数 _createElement:

    export function _createElement (context: Component,tag?: string | Class<Component> | Function | Object,data?: VNodeData,children?: any,normalizationType?: number): VNode | Array<VNode> {...return vnode;}复制代码

    _createElement 方法有 5 个参数:

  • context 表示 VNode 的上下文环境。
  • tag 表示标签,它可以是一个字符串,也可以是一个 Component。
  • data 表示 VNode 的数据。
  • children 表示当前 VNode 的子节点,它是任意类型的,它接下来需要被规范为标准的 VNode 数组。
  • normalizationType 表示子节点规范的类型,类型不同规范的方法也就不一样,它主要是参考 render 函数是编译生成的还是用户手写的。

    _createElement 实现内容略多,这里就不详细分析了,反正最后都会创建一个 VNode ,每个 VNode 有 children,children 每个元素也是一个 VNode,这样就形成了一个 VNode Tree,它很好的描述了我们的 DOM Tree。

    接下来熟悉一下如何在 createElement 函数中使用模板中的功能。这里是createElement 接收的参数:

    / @returns {VNode}createElement(// {String | Object | Function}// 一个 HTML 标签名、组件选项对象,或者// resolve 了上述任何一种的一个 async 函数。必填项。'div',// {Object}// 一个与模板中属性对应的数据对象。可选。{// (详情见下一节)},// {String | Array}// 子级虚拟节点 (VNodes),由 `createElement()` 构建而成,// 也可以使用字符串来生成“文本虚拟节点”。可选。['先写一些文字',createElement('h1', '一则头条'),createElement(MyComponent, {props: {someProp: 'foobar'}})])复制代码

    到这里我们回过头去看看上文说的这句话:「Vue 推荐在绝大多数情况下使用模板来创建你的 HTML。 然而在一些场景中,你真的需要 JavaScript 的完全编程的能力。这时你可以用渲染函数,它比模板更接近编译器。」

    而本文的重点generate编译器,它的作用和目的就是将 AST 转换为渲染函数 , 解析成如下格式:

    _c('div',{attrs:{"id":"app"}},[_v(_s(message))])复制代码

    接下来我们就一起走进 generate 源码世界。

    generate

    我们先用一个示例来看看 AST经过 generate 之后生成的render code 到底长什么样?

    例如有这样一段模块:

    data: {isShow: true,list: ['小白','小黄','小黑','小绿'],}<div><ulv-if="isShow"><liv-for="(item, index) in list"@click="clickItem(item)">{{item}}:{{index}}</li></ul></div>复制代码

    它经过编译,执行 const code = generate(ast, options),生成的 render code就会是如下这样一个字符串,注意这是一个字符串,只是为了方便大家阅读,我进行了格式化。

    with (this) {return _c('div', [isShow? _c('ul',{ staticClass: 'list' },_l(list, function (item, index) {return _c('li',{on: {click: function ($event) {return clickItem(item);},},},[_v('\n'_s(item)':'_s(index)'\n')],);}),0,): _e(),]);}复制代码

    with 字符串?

    大家发现生成的渲染函数字符串居然是一个with包裹的字符串,这样做的原因是with的作用域和模板的作用域是契合的,可以极大的简化编译流程。

    但是肯定会有同学质疑with不是不推荐使用?并且有性能问题吗?为什么还要用?

    尤雨溪本人的回答是这样的:


    “ 因为没有什么太明显的坏处(经测试性能影响几乎可以忽略),但是 with 的作用域和模板的作用域正好契合,可以极大地简化模板编译过程。Vue 1.x 使用的正则替换 identifier path 是一个本质上 unsound 的方案,不能涵盖所有的 edge case;而走正经的 parse 到 AST 的路线会使得编译器代码量爆炸。虽然 Vue 2 的编译器是可以分离的,但凡是可能跑在浏览器里的部分,还是要考虑到尺寸问题。用 with 代码量可以很少,而且把作用域的处理交给 js 引擎来做也更可靠。

    用 with 的主要副作用是生成的代码不能在 strict mode / ES module 中运行,但直接在浏览器里编译的时候因为用了 new Function(),等同于 eval,不受这一点影响。

    当然,最理想的情况还是可以把 with 去掉,所以在使用预编译的时候(vue-loader 或 vueify),会自动把第一遍编译生成的代码进行一次额外处理,用完整的 AST 分析来处理作用域,把 with 拿掉,顺便支持模板中的 ES2015 语法。也就是说如果用 webpackvue 的时候,最终生成的代码是没有 with 的。”


    而对于性能的影响,使用with 的确会造成一定的性能降低。但是真实 DOM 的渲染时间比 Virtual DOM 要长,而是否使用 with 只是影响了 Virtual DOM 的渲染,对真实 DOM 的渲染没有影响。所以对于普通需求来说,这种性能的影响比较小。

    并且使用 with, 就不需要在模板里面写 this 了。而编译生成的 with(this) 可以在某种程度上实现对于作用域的动态注入。这样写方便又简单,极大的简化编译流程,虽然有小的性能影响,但是权衡之下肯定利大于弊。

    _c 函数

    并且在生成的渲染字符串中有这样一些醒目的标记,例如:_c

    vm._c = (a, b, c, d) => createElement(vm, a, b, c, d, false)复制代码

    _c 其实在源码中对应的就是createElement函数,用于创建vnode。

    而还有一些常用的_(下划线)函数 如:_l 对应 renderList 渲染列表;_v 对应 createTextVNode 创建文本 VNode;_e 对于 createEmptyVNode创建空的 VNode。它们都被定义在 installRenderHelpers中。

    export function installRenderHelpers (target: any) {target._o = markOncetarget._n = toNumbertarget._s = toStringtarget._l = renderListtarget._t = renderSlottarget._q = looseEqualtarget._i = looseIndexOftarget._m = renderStatictarget._f = resolveFiltertarget._k = checkKeyCodestarget._b = bindObjectPropstarget._v = createTextVNodetarget._e = createEmptyVNodetarget._u = resolveScopedSlotstarget._g = bindObjectListeners}复制代码

    好,接下来,我们回到 generate 源码中来。

    generate 函数

    const code = generate(ast, options)复制代码

    function generate (ast,options) {var state = new CodegenState(options);var code = ast ? genElement(ast, state) : '_c("div")';return {render: ("with(this){return "code"}"),staticRenderFns: state.staticRenderFns}}复制代码

    进入generate流程调用 generate函数。generate函数代码不是很复杂,参数也比较简单

  • ast:转换优化后的语法树
  • options:编译器运行时的配置项

    函数首先调用 CodegenState 构造函数,创建实例对象 state 初始化编译的状态。CodegenState 的主要作用就是给实例初始化一些相关的属性。

  • options:基础的配置项
  • warn:警告函数
  • transforms:静态样式和属性、非静态样式和属性的处理函数引用
  • dataGenFns:模块数据函数的引用
  • directives:v-bind、v-model、v-text、v-html、v-on、内置指令对应 处理函数
  • isReservedTag:检查是否是保留标签
  • maybeComponent:检查元素是否为组件
  • staticRenderFns:存放静态节点的 render 函数
  • pre:记录标签是否使用了 v-pre

    var CodegenState = function CodegenState (options) {this.options = options;this.warn = options.warn || baseWarn;this.transforms = pluckModuleFunction(options.modules, 'transformCode');this.dataGenFns = pluckModuleFunction(options.modules, 'genData');this.directives = extend(extend({}, baseDirectives), options.directives);var isReservedTag = options.isReservedTag || no;this.maybeComponent = function (el) { return !!el.component || !isReservedTag(el.tag); };this.onceId = 0;this.staticRenderFns = [];this.pre = false;};复制代码

    接下来就是最重要的一步是,生成render code string。

    var code = ast ? genElement(ast, state) : '_c("div")';复制代码

    有ast就调用 genElement函数,没有的话,默认就创建一个div。这里的重点是genElement函数, 接下来我们来重点看看 genElement干了些什么?

    genElement

    当调用 genElement函数时,传入已经优化处理好的ast。然后在函数中根据不同的节点属性执行不同的生成函数。

    ①,判断 el.parent是否有值,来进行 pre 属性的设置。

    ②,如果节点是一个静态根节点staticRoot = ture,并且节点还没有被解析过staticProcessed = undefined就会调用 genStatic 函数。此函数用于生成静态节点的渲染函数字符串。生成一个_m的函数字符串。详情请看genStatic函数解析↓。

    ③,如果节点存在v-once,并且节点还没有被解析过onceProcessed = undefined就会调用 genOnce 函数。此函数用于生成v-once节点的渲染函数字符串。生成一个_o的函数字符串。详情请看genonce函数解析↓。

    ④,如果存在v-for循环,并且节点还没有被解析过forProcessed = undefined就会调用 genFor函数。此函数用于节点存在循环的情况,生成一个_l的函数字符串。详情请看genFor函数解析↓。

    ⑤,如果存在v-if循环,并且节点还没有被解析过ifProcessed = undefined就会调用 genIf函数。此函数用于节点存在v-if、v-else-if、v-else的情况,生成一个包含三目表达式的字符串(或者是嵌套的三目表达式:a ? b ? ... : c : d),详情请看genIf函数解析↓。

    • 推荐阅读
    • 听觉的秘密(听觉世界里的潜规则)

      鸡尾酒会效应说起大脑的能力强,至今,大脑在处理声音方面的一个功能还在让所有科学家惊叹,这个功能的神奇机制至今也还是个谜。这种功能有个有趣的名字,叫做“鸡尾酒会效应”。动物也展现鸡尾酒会效应最近的研究发现,很多动物的听觉系统也具有这种鸡尾酒会效应的功能,例如鸟儿们经常群集一起,叽叽喳喳开大会,但它们往往只是回应自己伴侣的叫声,显然它们能够从嘈杂的叽喳声中分辨出伴侣的声音。

    • 淄博环保供热第一供热分公司供暖范围在哪?

      淄博环保供热第一供热分公司供暖范围在哪?供暖小常识之暖气不热的具体排气方法:每个暖气片上都有一个手动排气阀,用户可轻轻拧松手动排气阀,听到排气声立即停止扭动排气阀,若见有稳定水流流出可将排气阀轻轻拧紧。排过气后,若暖气片还是不热,应请专业人员查明原因,帮助解决问题,切不可盲目放水。

    • 窗帘是什么材质 高精密窗帘是什么材质

      透明类的丝质面料,手感柔软、纹路流畅,用做窗帘,既浪漫又高雅。丝质窗帘最大的特点也是最明显的缺点就是价格昂贵,难以清洗。古代太后或皇后临朝听政,殿上用竹帘遮隔,则称为垂帘听政。

    • 普惠性幼儿园能否增加收费项目(普惠性幼儿园覆盖率将超过80)

      普惠性幼儿园覆盖率将超过80日前,陕西省教育厅和陕西省发改委联合印发了《陕西省教育事业发展“十四五”规划》,其中明确提出要强化学前教育规划建设,将新增公办园300所,公办园占比和公办园在园幼儿占比保持50%以上,普惠性幼儿园覆盖。

    • 林清玄人生感言(承担是生命里最美的东西)

      更令人赞叹的是,那个煮面的老板还边与顾客聊着闲天。对于孩子突如其来的谈话,我感到莞尔,并且立即坦然承认,我一定输给卖面的人。他们不用言语,而以动作表达了对生命的承担。在古印度人传统的观念里,认为只要是两条河交会的地方一定是圣地,这是千年智慧累积所得到的结论。当然,在我们以神圣的心面对世界时,自己就有了承担,也就成为值得敬佩的人之一。事实上,所有的比较都是一种执著。

    • 白花蛇舌草的功效与作用(白花蛇舌草的功效与作用效)

      白花蛇舌草一年生小草本,生于潮湿的田边、沟边、路旁和草地。白花蛇舌草药材全体扭成团块,灰绿色至灰棕色。白花蛇舌草补充信息:炮制:取原药材除去杂质,抢水洗净,稍润,切段,干燥。白花蛇舌草适合人群:孕妇慎用白花蛇舌草的功效和作用白花蛇舌草味苦、微甘,性微寒;入肺、肝、胃经;具有清热利湿,解毒抗癌的功效;主治肺热喘咳,咽喉肿痛,湿热黄疸,热淋涩痛,水肿,痢疾肠炎,肠痈,痈肿疮疡,毒蛇咬伤,癌肿。

    • 苏州西站长途汽车站停运通知(苏州市区79班汽车客运班线停班)

      苏州汽车客运总站表示,将给因台风造成停班班次的旅客办理免费退票。昆山客运中心站正密切关注“利奇马”的走向及发展趋势,动态调整班次开行方案并及时通知广大旅客相关停班信息,确保旅客安全出行。有去机场、高铁站、火车站换乘的旅客请适当增加出行时间,以免受台风影响耽误行程。如因天气原因导致班次停运,乘车人可在当天携带本人身份证持车票到车站窗口办理全额退票。

    • 二氧化碳用途(二氧化碳的用途)

      二氧化碳是我们很熟悉的一种气体,大量的二氧化碳会导致温室效应的加剧。学过生物的同学都知道,植物的光合作用是需要二氧化碳作为原料的。在很多农场里面,也会放置产生二氧化碳的仪器,提高农作物的产量。二氧化碳灭火器可用于扑灭图书、重要仪器的失火,因为扑灭后没有任何的残留物质。其实这种效果都是由人为用干冰造成的。以及人工降雨也都会用到二氧化碳等,用途广泛。

    • 桂林社保卡要自己去银行办吗(桂林社保卡要自己去银行办吗现在)

      制卡人1寸白底免冠深色上衣证件纸质彩色照片1张。如委托代办,需提供受委托人的居民身份证原件。填写社会保障卡制卡申领表。社会保障卡启用1.办理条件本统筹区已领取社会保障卡,但未激活社保功能的参保人员。广西区内转入已经持有社会保障卡的参保人员。

    • tvb五花是谁(深扒TVB五朵金花)

      根据港媒报道,杨怡与胡定欣在剧组拍摄期间已经有了两女相争的苗头。根据当时报道,吴卓羲公开表示,自己与徐子珊仅拍摄了一天电视剧,便成为了男女朋友,使得二人被视为最佳荧幕情侣。在此期间,黄宗泽与五花们合作过多部作品,荧幕情侣也是组合了一对又一对。此外,同样家庭事业双丰收的还有勤恳劳模杨怡。然而,现实生活中,与杨怡定情的却是在剧中饰演马国明弟弟的罗仲谦。杨怡仍然认定罗仲谦,并于2016年10月于英国完婚。