├── 1 ├── index.html └── README.md /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Document 9 | 10 | 11 | 12 | 13 |
14 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

Vue.js 2.4.4版本,源码解读

2 | 3 |

提纲分为这五章:

4 |

1、Vue构造函数:实例方法和静态方法

5 |

2、Vue的响应原理:Observe、Watcher、Dep关系

6 |

3、Vue的编译过程:template、AST、Render过程

7 |

4、Vue的虚拟节点:VNode、patch算法

8 |

5、Vue的异步队列:nextTick调度

9 | 10 |
11 | 12 |
13 |
14 |

一、Vue构造函数:实例方法和静态方法

15 | 16 |

Vue运行时---第一步扩展实例方法(点击链接)

17 |

总结Vue扩展实例方法流程为:

18 |

1、 定义function Vue()

19 |

2、 initMixin扩展vm._init

20 |

3、 stateMixin扩展vm.$data、vm.$props、vm.$set、vm.$delete、vm.$watch

21 |

4、 eventsMixin扩展vm.$on、vm.$once、vm.$off、vm.$emit

22 |

5、 lifecycleMixin扩展vm._update、wm.$forceUpdate、vm.$destroy

23 |

6、 renderMixin扩展vm.$nextTick、vm._render和一些工具方法

24 | 25 |

Vue运行时---第二步扩展静态方法(点击链接)

26 |

总结Vue扩展静态方法流程为:

27 |

1、扩展了工具方法Vue.util.warn、Vue.util.extend、Vue.util.mergeOptions、Vue.util.defineReactive

28 |

2、扩展了Vue.set 、Vue.delete、Vue.nextTick

29 |

3、扩展了Vue.options.conponents、Vue.options.directives、Vue.options.filters

30 |

4、扩展了Vue.options._base 等于 Vue构造函数本身

31 |

5、扩展了Vue.options.components为默认{name、abstract、props、created、destroyed、watch、render}对象

32 |

6、initUse(Vue)扩展了Vue.use

33 |

7、initMixin(Vue)扩展了Vue.mixin

34 |

8、initExtend(Vue)扩展了Vue.cid属性和Vue.extentd方法

35 |

9、initAssetsRegisters(Vue)扩展了Vue.componet、Vue.directive、Vue.filter三个方法

36 |

10、‘core/index’中扩展了Vue.$isServer和Vue.$ssrContext的get方法

37 |

11、‘runtime/index中扩展了’Vue.config的配置方法mustUseProp、isReservedTag、isReservedAttr、getTagnamespace、isUnknownElement

38 |

12、‘runtime/index’中使用了平台相关的指令和组件覆盖之前生成的Vue.options.directives和Vue.options.components

39 |

13、‘runtime/index’中增加实例方法vm.patch

40 |

14、‘runtime/index’中扩展了实例方法vm.$mounted

41 | 42 |
43 |
44 |
45 |

二、Vue的响应原理:Observe、Watcher、Dep关系

46 | 47 |

Vue的响应原理:Observe、Watcher、Dep关系(点击链接)

48 |

1、 每个data中属性元素会有一个闭包Dep的实例,里面存放Watcher实例

49 |

2、 当template编译为render函数时,会调用属性的get方法,将每一次调用都生成一个watcher实例,并压入dep中,产生订阅效果。

50 |

3、 当设置data中属性值的时候,调用属性的set方法通知所有订阅该属性的元素更新

51 |

4、 而且props,computed,watch内同理是增加watcher产生订阅和发布的效果。

52 |
53 |
54 |
55 |

三、Vue的编译过程:template、AST、Render过程

56 | 57 |

Vue的编译过程:template、AST、Render过程(点击链接)

58 |

1、 template先判断是否存在render函数,如果不存在则判断template模板,最后判断el标签。

59 |

2、 const ast = parse(template.trim(),options)是生成抽象语法树。

60 |

3、 optimize(ast,options)优化AST树。

61 |

4、 const code = generate(ast, options)这一句之后,生成render函数。

62 | 63 |
64 |
65 |
66 |

四、Vue的虚拟节点:VNode、patch算法

67 | 68 |

①Vue的虚拟节点Vnode过程(点击链接)

69 |

清晰描述了“tempalte”转化为“ast抽象语法树”转化为“render函数”转化为“vnode虚拟树”的过程。

70 | -------------------------------------------------------------------------------- /1: -------------------------------------------------------------------------------- 1 | using ETModel; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace ETHotfix 8 | { 9 | /// 10 | /// 四种消息类型封装:AMHandler、AMRpcHandler、AMActorHandler、AMRpcActorHandler 11 | /// 12 | public class MessageHelper 13 | { 14 | /// 15 | /// 单向通信,向任一服务器发送消息 16 | /// 接收端例子: 17 | /// [MessageHandler(AppType.Gate)] 18 | /// public class C2G_ReturnLobby_NttHandler : AMHandler 19 | /// { 20 | /// protected override async void Run(Session session, C2G_ReturnLobby_Ntt message) 21 | /// { 22 | /// } 23 | /// } 24 | /// 25 | /// IRequest 26 | /// AppType 27 | public static void Send2Session(IMessage message, AppType appType) 28 | { 29 | //随机分配appType服务器 30 | Session session = GetRandomSession(appType); 31 | session.Send(message); 32 | } 33 | 34 | /// 35 | /// 双向通信,向任一服务器发送消息,并接收返回消息 36 | /// 接收端例子: 37 | /// [MessageHandler(AppType.Gate)] 38 | /// public class C2G_LoginGate_ReqHandler : AMRpcHandler 39 | /// { 40 | /// protected override async void Run(Session session, C2G_LoginGate_Req message, Action reply) 41 | /// { 42 | /// } 43 | /// } 44 | /// 45 | /// IRequest 46 | /// AppType 47 | /// 48 | public static Task Call2Session(IRequest request, AppType appType) 49 | { 50 | //随机分配appType服务器 51 | Session session = GetRandomSession(appType); 52 | return session.Call(request); 53 | } 54 | 55 | /// 56 | /// 单向通信,向指定Actor发送消息,会从Location服务器查找对象 57 | /// 接收端例子: 58 | /// [MessageHandler(AppType.Gate)] 59 | /// public class Actor_MatchSucess_NttHandler : AMActorHandler 60 | /// { 61 | /// protected override void Run(Player player, Actor_MatchSucess_Ntt message) 62 | /// { 63 | /// } 64 | /// } 65 | /// 66 | /// ComponentFactory.Create(id),actorId即create传入的id值,location根据actorId查找对象所在服务器,再根据instanceId还原对象 67 | /// IActorMessage 68 | public static void Send2Actor(long actorId, IActorMessage message) 69 | { 70 | ActorMessageSender actorProxy = Game.Scene.GetComponent().Get(actorId); 71 | actorProxy.Send(message); 72 | } 73 | 74 | /// 75 | /// 双向通信,向指定Actor发送消息,并接收返回消息,会从Location服务器查找对象 76 | /// 接收端例子: 77 | /// [MessageHandler(AppType.Gate)] 78 | /// public class Actor_MatchSucess_NttHandler : AMActorHandler 79 | /// { 80 | /// protected override void Run(Player player, Actor_MatchSucess_Req message, Action reply) 81 | /// { 82 | /// } 83 | /// } 84 | /// 85 | /// ComponentFactory.Create(id),actorId即create传入的id值,location根据actorId查找对象所在服务器,再根据instanceId还原对象 86 | /// IActorRequest 87 | public static Task Call2Actor(long actorId, IActorRequest request) 88 | { 89 | ActorMessageSender actorProxy = Game.Scene.GetComponent().Get(actorId); 90 | return actorProxy.Call(request); 91 | } 92 | 93 | /// 94 | /// 获取任一类型服务器配置 95 | /// 96 | /// 97 | /// Session 98 | private static Session GetRandomSession(AppType appType) 99 | { 100 | var configList = new List(); 101 | StartConfig[] startConfigs = Game.Scene.GetComponent().GetAll(); 102 | foreach (StartConfig config in startConfigs) 103 | { 104 | if (!config.AppType.Is(appType)) 105 | { 106 | continue; 107 | } 108 | configList.Add(config); 109 | } 110 | int n = RandomHelper.RandomNumber(0, configList.Count); 111 | StartConfig startConfig = configList[n]; 112 | return Game.Scene.GetComponent().Get(startConfig.GetComponent().IPEndPoint); 113 | } 114 | } 115 | } 116 | --------------------------------------------------------------------------------