首先生成的 ast 会加上一些属性,每个 element 元素可以看作是一个 ast 对象,整颗 DOM 树可以看作是包含依赖关系的 ast 对象。

v-if 指令

源码在 processIf(element) 函数里面处理

// <span v-if="msg">6</span>
// (msg)?_c('span',[_v("6")]):_e()
let ast = [{type: 1,tag: 'span',attrsList: [],attrsMap: { 'v-if': 'msg' },rawAttrsMap: {},parent: {type: 1,tag: 'div',attrsList: [],attrsMap: {},rawAttrsMap: {},parent: undefined,children: [],plain: true,static: false,staticRoot: false},children: [],if: 'msg',ifConditions: [ { exp: 'msg', block: el } ],plain: true,static: false,staticRoot: false,pre: undefined,ifProcessed: true}
]

先 processIf 再 genIf,生成 render:

function genIf (el,state,altGen,altEmpty
) {el.ifProcessed = true; // avoid recursionreturn genIfConditions(el.ifConditions.slice(), state, altGen, altEmpty)
}function genIfConditions (conditions, // [ { exp: 'msg', block: el } ]state,altGen, // 无altEmpty // 无
) {if (!conditions.length) {return altEmpty || '_e()'}var condition = conditions.shift();if (condition.exp) {// 主要看这里,通过三元运算符?和:拼接字符串return ("(" + (condition.exp) + ")?" + (genElement(el, state)) + ":" + (genIfConditions(conditions, state, altGen, altEmpty)))} else {return ("" + (genTernaryExp(condition.block)))}
}

v-for 指令

源码在 processFor(element) 函数里面处理

// _l((list), function(item){return _c('span',[_v("6")])})
// <span v-for="item in list">6</span>
let ast = [{type: 1,tag: 'span',attrsList: [],attrsMap: { 'v-for': 'item in list' },rawAttrsMap: {},parent: {type: 1,tag: 'div',attrsList: [],attrsMap: {},rawAttrsMap: {},parent: undefined,children: [],plain: true,static: false,staticRoot: false},children: [],for: 'list',alias: 'item',plain: true,static: false,staticRoot: false,pre: undefined,forProcessed: true}
]

我们简单想象一下 for 指令需要包装成一个函数,方便之后的循环遍历,比如下面这样:

function _l(list, callback) { list.forEach(item => callback(item))  }

具体的生成过程:

function genFor (el,state,altGen, // 无altHelper // 无
) {var exp = el.for;var alias = el.alias;var iterator1 = el.iterator1 ? ("," + (el.iterator1)) : '';var iterator2 = el.iterator2 ? ("," + (el.iterator2)) : '';// 主要看这里,包装成一个function函数el.forProcessed = true; // avoid recursionreturn ('_l') + "((" + exp + ")," +"function(" + alias + iterator1 + iterator2 + "){" +"return " + ((genElement)(el, state)) +'})'
}

v-once 指令

源码在 processOnce(element) 函数里面处理

// <div>11<span v-once="msg">6</span></div>
// render: `with(this){return _c('div',[_v("11"),_m(0)])}`,
// staticRenderFns: [ `with(this){return _c('span',[_v("6")])}` ],
let ast = [{type: 1,tag: 'span',attrsList: [],attrsMap: { 'v-once': '' },rawAttrsMap: {},parent: {type: 1,tag: 'div',attrsList: [],attrsMap: {},rawAttrsMap: {},parent: undefined,children: [],plain: true,static: false,staticRoot: false},children: [],once: true,plain: true,static: false,staticInFor: false,staticRoot: false,pre: undefined,onceProcessed: true,staticProcessed: true}
]

v-once 只渲染元素和组件一次。随后的重新渲染,元素/组件及其所有的子节点将被视为静态内容并跳过。这可以用于优化更新性能。

function genOnce (el, state) {el.onceProcessed = true;return genStatic(el, state)
}function genStatic (el, state) {el.staticProcessed = true;var originalPreState = state.pre;state.staticRenderFns.push(("with(this){return " + (genElement(el, state)) + "}"));state.pre = originalPreState;return ("_m(" + (state.staticRenderFns.length - 1) + (el.staticInFor ? ',true' : '') + ")")
}

生成 render 函数的目的就是为了当绑定的变量值发生改变的时候,可以重新执行 render 函数,最后生成真实的 DOM,其中_c 和 _v 等等这些辅助函数就是处理真实 DOM 的函数,关于 render 函数生成 DOM 我们之后再分析。

vue中指令的编译过程相关推荐

  1. 【蜂鸟E203内核解析】Chap.2 E203内核中指令执行的过程-为什么E203是两级流水线?

    [蜂鸟E203内核解析]Chap.2 E203内核中指令执行的过程-为什么E203是两级流水线? 0. E203的两级流水线结构 1. IFU取指令 2. EXU 译码执行交付写回 (1)译码部分与指 ...

  2. ie浏览器查看vue中js_浅析 Vue.js 中那些空间换时间的操作

    Hello,各位小伙伴,接下来的一段时间里,我会把我的课程<Vue.js 3.0 核心源码解析>中问题的答案陆续在我的公众号发布,由于课程的问题大多数都是开放性的问题,所以我的答案也不一定 ...

  3. uboot配置和编译过程详解

    ▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼ 分享一个大神朋友的人工智能教程.零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到 ...

  4. 2021-07-14在vue中引入emoji表情

    在vue中添加emoji表情 过程 过程 在已经创建的表情button中应用ant design组件: 网址.添加气泡卡片组件 在js中引入依赖 下面展示一些 内联代码片. // 引入安装包和样式 i ...

  5. vue中的指令——内置指令

    什么是指令 指令是带 v- 前缀的特殊属性,其值限定为单个表达式. vue提供了少量指令供大家使用,在一定程度上简化了开发过程.当然除了内置指令,还有自定义指令,本篇就是只对内置指令进行讲解. 内置指 ...

  6. openfoam安装中出现allmake error_深入理解 OpenFOAM 环境与编译过程

    深入理解 OpenFOAM 环境变量与编译 操作系统选择 由于 OpenFOAM 在 Linux 平台开发和测试,在非 Linux 平台无法直接对软件进行编译和安装,所以在非 Linux 平台上最简便 ...

  7. vue指令写在html中的原理,详解Vue中的MVVM原理和实现方法

    对Vue中的MVVM原理解析和实现首先你对Vue需要有一定的了解,知道MVVM.这样才能更有助于你顺利的完成下面原理的阅读学习和编写下面由我阿巴阿巴的详细走一遍Vue中MVVM原理的实现,这篇文章大家 ...

  8. 编译html成qch,在应用程序编译过程中运行qcollectiongenerator

    我一直在研究一个名为RoboJournal的程序很长一段时间.下一版本包含完整的文档;每当用户按F1或单击RoboJournal程序中的帮助项目时,帮助文件将显示在Qt助手中(比简单地打开浏览器窗口以 ...

  9. vue中webpack编译打包使用之Vue知识点归纳(十一)

    本文中将描述 webpack 简述 webpack 项目的初始化配置 webpack 打包运行一个 vue 项目 1 什么是webpack,到底需要解决什么问题 近几年前端的快速发展,前端已不是简单的 ...

最新文章

  1. 随机森林(Random Forest)为什么是森林?到底随机在哪里?行采样和列采样又是什么东西?
  2. python中的单下划线和双下划线_python 里面的单下划线与双下划线的区别(私有和保护)...
  3. Linux16.04和Windows 10双系统下,解决时间不一致问题
  4. 通过接口字段名称反向猜测数据库列名
  5. 6-4 链表逆置 (10 分)
  6. 递归实现斐波那契数列(Java)
  7. Win7扫雷的H5完整复刻实现(二) / js扫雷算法处理空白连通域与点击不同方块的实现
  8. 分享一个2.4G无线麦克风音频接收器的成功案例
  9. python基础学习总结
  10. js距离单位换算_1等于多少公里
  11. 纽约科技行业十大高薪职位
  12. Hypervisor技术
  13. 计算摄影——图像超分
  14. SpringBoot整合Graylog3.0
  15. Gallery中,取消惯性滑动,滑动一次只切换一个视图
  16. 7.MATLAB参数统计与假设检验-常用非参数检验
  17. 差分定位和精密定位(一)--差分定位
  18. 关于position:fixed;的居中问题
  19. 打开空白页.chm文件
  20. ctfshow---vip限免题目11~20

热门文章

  1. 必看!程序员逃生指南!
  2. 英伟达斥资 400 亿美元收购 Arm,欲向 Arm 员工发 15 亿美元股票
  3. 华为 MindSpore 喊你来开发 10 大 AI 模型,260 万奖金怎能没你一份?
  4. 将 Kubernetes 云原生技术革命进行到底!
  5. “不会MySQL,干啥都不行!”高级开发:工作、面试处处都会踩坑!
  6. 从 Ops 到 NoOps,阿里文娱智能运维的关键:自动化应用容量管理
  7. 再获全球顶会ASPLOS认可:阿里云神龙凭什么打破物理机神话
  8. 提高 10 倍性能,揭秘淘宝、天猫背后的图片存储如何扛住双十一巨流?| 问底中国 IT 技术演进...
  9. 2020年,程序员要做好苦日子的准备了!
  10. “上云”很 fashion 的今天,GeekPwn 搞了个比赛……