前言

上一篇文章对入Moon整体结构进行了分析,基本了解了Moon代码结构组成,接下来的文章会对于Moon中各个部分的细节进行分析与了解,分析的版本是Moon的v0.9.0。

具体分析

首先通过了一个实例来看看Moon的实现效果,具体代码如下:

  <div id="app"><p>{{msg}}</p></div><script src="./moon.js"></script><script>new Moon({el: '#app',data: {msg: 'hello world'}});</script>

上面是Moon中最基本的用法,接下来就分析下Moon中具体的处理。

Moon构造函数
 function Moon(opts) {// Moon构造函数传入的options,即上例中{el: '#app', data: {msg: 'hello world'}}this.$opts = opts || {};var self = this;// 编号,此时id=0this.$id = id++;// 实例名称,上例中不存在name属性,故此为rootthis.$name = this.$opts.name || "root";// data属性this.$data = this.$opts.data || {};// render函数,上例中无render,故此为noopthis.$render = this.$opts.render || noop;// hooks, 就是生命周期函数需写在hooks对象中this.$hooks = this.$opts.hooks || {};// methods属性是否存在,存在就会调用initMethods(顾名思义该方法是初始化方法的)var methods = this.$opts.methods;if (methods !== undefined) {initMethods(self, methods);}// 新增$events、$dom(虚拟DOM)属性this.$events = {};this.$dom = {};// 观察对象this.$observer = new Observer(this);this.$destroyed = true;this.$queued = false;// 计算属性computed是否存在,存在就调用initComputed初始化计算属性var computed = this.$opts.computed;if (computed !== undefined) {initComputed(this, computed);}// 初始化this.init();}

上面实例中不存在methods以及computed,所以主要的处理是observer对象的创建以及init方法的执行

Observer:观察对象构造函数
    function Observer(instance) {// Moon实例,每个Moon实例都会存在一个Observer实例this.instance = instance;// 计算属性缓存对象this.cache = {};// 计算属性的setterthis.setters = {};this.clear = {};this.target = null;// 依赖mapthis.map = {};}
init():初始化
    Moon.prototype.init = function () {log("======= Moon =======");// 调用callhook函数callHook(this, 'init');// 如果el属性存在,就调用mount函数if (this.$opts.el !== undefined) {this.mount(this.$opts.el);}};
callHook函数
   var callHook = function (instance, name) {// 查看hook对象中是否存在指定的生命周期方法,存在就调用该方法var hook = instance.$hooks[name];if (hook !== undefined) {hook.call(instance);}};
mount
    Moon.prototype.mount = function (el) {// 获取挂载点DOM对象this.$el = document.querySelector(el);this.$destroyed = false;// el不存在报错if ("development" !== "production" && this.$el === null) {error("Element " + this.$opts.el + " not found");}// 在$el中定义私有属性__moon__代表当前Moon实例this.$el.__moon__ = this;// 不存在模板,就会获取$el的标签及其包含的内容// 上面的实例中不存在template属性,所以此处是<div id="app"><p>{{msg}}</p></div>this.$template = this.$opts.template || this.$el.outerHTML;// 如果render是noop函数,表示是默认render函数,就会调用Moon.compileif (this.$render === noop) {this.$render = Moon.compile(this.$template);}// build函数,就是创建虚拟DOM并this.build();// mounted生命周期函数是否存在,存在就调用mountedcallHook(this, 'mounted');};
Moon.compile
 Moon.compile = function (template) {// 调用compile函数,将template html转换成render函数return compile(template);};
build
  Moon.prototype.build = function () {// 调用render函数创建dom节点var dom = this.render();var old = null;// 如果存在实例的$dom不存在,old表示就是挂载点的DOM节点if (this.$dom.meta !== undefined) {old = this.$dom;} else {old = this.$el;this.$dom = dom;}// 调用patch函数this.patch(old, dom, this.$el.parentNode);};
render
    Moon.prototype.render = function () {// 实际上就是调用$render函数,创建虚拟DOM节点// h是Moon中定义的函数return this.$render(h);};

本篇旨在Moon构造函数的过程,此时只要知道render函数的作用即可,就是创建虚拟DOM,针对上面的实例,render函数的结果是:

从上面的结果中可以看到,render函数实际上是将不同类型的node都创建成指定格式的对象,现在只需要知道这个对象的组成属性有,具体后面会专门分析:

  • children:子节点对应的virtual dom
  • meta:元信息
  • props:属性
  • type:标签名
  • val:值
patch
   // 具体该函数的功能是处理虚拟DOM,将改变更新到真实DOM中Moon.prototype.patch = function (old, vnode, parent) {};

之后会针对虚拟DOM与真实DOM之间有个详细分析,本次具体去了解。

总结

Moon构造函数创建Moon实例添加的属性主要有:

  • $opts:参数对象
  • $id:id编号
  • $name:实例名称
  • $data:数据中心
  • $render:render函数,根据html转换成虚拟DOM
  • $hooks:生命周期对象
  • $dom:虚拟DOM对象

    Moon构造函数的处理流程如下:

    属性添加–>初始化所有方法—> 观察对象创建—>初始化计算属性—->生命周期函数init处理—->获取el挂载点DOM—->获取template—->根据template构建render函数–>根据render函数创建Virtual DOM—->Virtual DOM与真实DOM之间的处理—>调用mounted生命周期函数

    在整个Moon创建的过程中,还有几处不甚明了:

  • methods的处理

  • computed的处理
  • Observer的监听机制

在下篇文章中会对于methods以及computed等相关做具体的分析。

Moon系列之Moon构造函数相关推荐

  1. [USACO09MAR]Moon哞哞叫Moon Mooing(模拟)

    链接:https://ac.nowcoder.com/acm/contest/1086/F 来源:牛客网 题目描述 A full moon casts some sort of spell on th ...

  2. javascript面向对象系列第一篇——构造函数和原型对象

    前面的话 一般地,javascript使用构造函数和原型对象来进行面向对象编程,它们的表现与其他面向对象编程语言中的类相似又不同.本文将详细介绍如何用构造函数和原型对象来创建对象 构造函数 构造函数是 ...

  3. C#拾遗系列(3):构造函数

    1. 主要演示构造函数的继承   声明空构造函数可阻止自动生成默认构造函数.   如果您不对构造函数使用访问修饰符,则在默认情况下它仍为私有构造函数.   通常显式地使用 private 修饰符来清楚 ...

  4. C++进阶系列:拷贝构造函数与NRV优化

    <深度探索C++对象模型>第二章67页有: 这个程序的第一个版本不能实施NRV优化,因为test class 缺少一个copy constructor. 也就是缺少拷贝构造函数所以不能NR ...

  5. BLUEMOON: 2021

    BLUEMOON: 2021 作者: admin 时间: 2021-06-10 分类: vulnhub靶场 fping -g 192.168.137.1/24 # step1 扫主机,找到靶场131 ...

  6. Ubuntu 搭建 Zerotier One MOON 根目录服务器

    原文转摘:http://www.congan.wang/archives/947 博主倒腾了一天,总算搞定了,主要是受到各种搭建教程的错误引导,导致关键过程错误. 官网的MOON搭建教程:https: ...

  7. 完全无人驾驶量产车Apollo Moon威马版首秀 成本降一半、能力翻10倍

    2021年10 月19日,百度Apollo联合威马正式发布两款新车,新车型均基于威马W6打造.一款是配置激光雷达的新一代无人车Apollo Moon量产车型(Apollo Moon威马版):另一款是搭 ...

  8. 使用三丰云服务器建立moon节点搭建zerotier

    文章目录 前言 一.配置步骤 1.在三丰云网站上注册账号了,免费获取云服务器,在这云服务器中配置zerotier 2.将zerotier中的各个设备连入moon节点 总结 前言 因为想要在宿舍里就能配 ...

  9. 如何利用Parsec+Zerotier+moon实现云电脑云游戏

    前期说明 ​ RD Client 没法串流,向日葵带宽受限,同时也没办法打游戏.那么可不可以自己实现一台云电脑来实现云游戏呢?答案当然是可以的了,下面文章将进行介绍Parsec ​ 这是我目前使用的终 ...

最新文章

  1. Linux系统编程——进程基础知识
  2. 简易嵌入式管理平台 C 实现
  3. RocketMQ部署安装注意事项
  4. python 判断子序列_Leetcode练习(Python):第392题:判断子序列:给定字符串 s 和 t ,判断 s 是否为 t 的子序列。...
  5. 外连接OUTER JOIN(三十五)
  6. 栈应用—括号匹配问题
  7. Devcpp、Codeblocks如何设置支持c++11
  8. 如何导入android sdk,如何导入android sdk samples
  9. 数学模型转化为计算机语言,程序设计语言类课程教学选题方法探讨
  10. Linux基础篇——Linux进程、服务管理
  11. PPT制作三大技巧:图标 、图片背景透明和自动函数
  12. 人间四月天,有一本好书要送给你
  13. React hooks 不能拿到最新的的setState的值
  14. 机器人学数学理论_基于格理论的机器学习数学
  15. QT读取位置时发生访问冲突
  16. eks安装kubectl
  17. java API 在线文档
  18. 基于php的学生考勤管理系统
  19. Telerik DevCraft UI,提供 .NET 和 JavaScript 技术
  20. Proteus彻底卸载干净和license密钥报错等问题

热门文章

  1. 关于数据库连接池满了的问题详解
  2. 南开大学计算机考博参考书目,南开大学考博参考书
  3. CSS3—盒子模型 讲解
  4. 论文阅读笔记:Multi-Labeled Relation Extraction with Attentive Capsule Network(AAAI-2019)
  5. MySQL存emoji表情
  6. 写了一个小小的html
  7. vue 微信支付的坑_Vue实现微信支付功能遇到的坑
  8. 【Kotlin】学习小记-基础篇
  9. PythonRedis 无序集合set、有序集合zset操作
  10. 如何清理hue元数据库里面的历史数据