Moon系列之slot以及指令相关
2018-01-18 11:23
134 查看
前言
上篇文章中分析了Moon中虚拟DOM的整个逻辑处理,它是Moon整个功能实现的核心,本篇的要说明的slot以及指令的处理都是在上篇文章分析的逻辑过程中,只是上篇文章没有突出说明具体的处理,本篇就是具体的说明Moon是如何处理slot以及指令的。具体分析
还是通过实例来开始分析整个过程,具体实例代码如下:<div id="app"> <p m-if="true">{{getToday}}</p> <mn-test> <p>{{today}}</p> <p slot="second">hello world</p> </mn-test> </div> <script src="./moon.js"></script> <script> debugger Moon.component('mn-test', { template: `<div> <slot></slot> <slot name="second"></slot> </div>` }); new Moon({ el: '#app', data: { today: Date.now() }, computed: { getToday: { get() { var now = new Date(this.get('today')); return now.toLocaleString(); } } } }); </script>
上面的实例中涉及到了slot以及指令m-if。
首先整个的过程还是如同虚拟DOM中的处理,需要说明的是m-if在tokens中也是作为标签属性的存在,slot也是作为token中也是作为标签属性的存在。所以在返回render的处理中,lex以及parse中的处理没有什么不同,主要的不同是在于generate中部分。
generate中关于slot以及指令的处理
generate函数的逻辑处理如下:
可以看出slot以及指令是在generateEL函数中处理的。
在具体分析了generateEL函数的处理逻辑,关于slot以及指令的核心逻辑如下:
var compiledCode = ""; // 是否存在插槽slot if (vnode.type === "slot") { parentVNode.meta.shouldRender = true; parentVNode.deep = true; var slotNameAttr = vnode.props.attrs.name; compiledCode = 'instance.$slots[\'' + (slotNameAttr && slotNameAttr.value || "default") + '\']'; } else { // 创建函数体 compiledCode = createCall(vnode, parentVNode); } // 虚拟DOM是否存在指令相关的对象 if (vnode.specialDirectivesAfter !== undefined) { for (var specialDirectiveAfterInfo in vnode.specialDirectivesAfter) { var specialDirectiveAfter = vnode.specialDirectivesAfter[specialDirectiveAfterInfo]; compiledCode = specialDirectives[specialDirectiveAfter.name].afterGenerate(specialDirectiveAfter.value, specialDirectiveAfter.meta, compiledCode, vnode); } }
上面的代码就是generateEL中关于slot以及指令的处理。
上面就说过在lex中生成tokens,上面实例中m-if以及slot都是作为对应标签的属性的,所以就会在createCall中,slot的处理从上面可以直接看出,而对于指令的处理,就要具体分析了。
指令相关
if (vnode.specialDirectivesAfter !== undefined) { 具体代码 }
需要判断虚拟DOM是否存在specialDirectivesAfter对象,通过具体的分析,该对象的添加是在createCall中对于属性的处理,相关处理代码如下:
var attrInfo = attrs[attr]; var specialDirective = null; // 是否是Moon实例内置的指令 if ((specialDirective = specialDirectives[attrName]) !== undefined) { if (specialDirective.afterGenerate !== undefined) { // 添加specialDirectivesAfter对象 if (vnode.specialDirectivesAfter === undefined) { vnode.specialDirectivesAfter = {}; } // 指令相关赋值 vnode.specialDirectivesAfter[attr] = attrInfo; } if (specialDirective.duringPropGenerate !== undefined) { generatedObject += specialDirective.duringPropGenerate(attrInfo.value, attrInfo.meta, vnode); } vnode.meta.shouldRender = true; delete attrs[attr]; }
从上面的处理逻辑看出,Moon指令的具有特定的结构,下面就看看m-if的构成:
specialDirectives[Moon.config.prefix + "if"] = { afterGenerate: function (value, meta, code, vnode) { return '(' + compileTemplate(value, delimiters, escapedDelimiters, false) + ') ? ' + code + ' : h("#text", ' + generateMeta(defaultMetadata()) + ', "")'; } };
具体看看compileTemplate的处理逻辑:
compileTemplate的处理结果是:
(true) ? h("p", {attrs: {}}, {"shouldRender": true, "eventListeners": {}}, [h("#text", {"shouldRender": true, "eventListeners": {}}, "" + instance.get("getToday") + "")]) : h("#text", {"shouldRender": false, "eventListeners": {}}, "")
compileTemplate函数还是根据不用的指令处理成不同的render的部分函数体。
对于其他指令,具体的处理我会详细注释,Moon内置的指令都是对象,对象拥有方法beforeGenerate、duringPropGenerate、afterGenerate,这些方法afterGenerate是在generate函数中处理,beforeGenerate和duringPropGenerate是在generateProps中处理。
相关文章推荐
- Linux中基础笔记(必备知识)包含常用指令以及tomcat搭建 系列1
- 【SSO单点系列】(6):CAS4.0 单点流程序列图(中文版)以及相关术语解释(TGT、ST、PGT、PT、PGTIOU)
- Linux中基础笔记(必备知识)包含常用指令以及tomcat搭建 系列2
- Intent系列讲解---Intent简介以及相关属性
- AM335x的DDR3软硬件设计以及相关资源--TI--Sitara AM335x系列
- 【Java80小白建站系列】5.网站技术的选择以及相关软件的安装
- Apache下的子目录以及相关指令的说明
- Linux中基础笔记(必备知识)包含常用指令以及tomcat搭建 系列3
- AllowOverride以及Options相关指令
- 相关图像处理以及UIGraphicsBeginImageContext系列知识
- 【SSO单点系列】(6):CAS4.0 单点流程序列图(中文版)以及相关术语解释(TGT、ST、PGT、PT、PGTIOU)
- Android 版本更新(非热更新) 适配7.0更新 以及三星 note系列读取内存相关目录无权限问题
- Moon系列之虚拟DOM相关
- shell相关指令介绍$*和$#以及$?和if [[ ! -z $1 ]]
- SSE2指令集系列之二----整数运算相关指令
- ionic angularJS input 相关指令 以及定时器 的使用
- AllowOverride以及Options相关指令
- 相关图像处理以及UIGraphicsBeginImageContext系列知识
- SSE2指令集系列之二----整数运算相关指令
- SSE2指令集系列之二----整数运算相关指令