源码学习的好处

大幅度提升编码水平

  • 了解架构设计
  • 设计模式
  • 命名风格
  • 数据结构及算法

提升问题解决能力

知其然知其所以然

提升思维逻辑能力

源码阅读技巧

高效源码学习技巧 - 图1

案例实操

Vue编译器

高效源码学习技巧 - 图2

Vue生命周期

  • 生命周期图示

image.png

  • 生命周期钩子
    1. var LIFECYCLE_HOOKS = [
    2. 'beforeCreate',
    3. 'created',
    4. 'beforeMount',
    5. 'mounted',
    6. 'beforeUpdate',
    7. 'updated',
    8. 'beforeDestroy',
    9. 'destroyed',
    10. 'activated',
    11. 'deactivated',
    12. 'errorCaptured',
    13. 'serverPrefetch'
    14. ];

$mount 函数解析

_this_.$options 自定义配置,以用户为优先,以用户配置为覆盖

  1. // install platform patch function
  2. Vue.prototype.__patch__ = inBrowser ? patch : noop;
  3. // public mount method
  4. Vue.prototype.$mount = function (
  5. el,
  6. hydrating
  7. ) {
  8. /**
  9. * @desc $mount 初始化
  10. * 先去检测是否在浏览器环境,
  11. * 如果在浏览器环境返回el元素
  12. * 运行时,直接使用就可以
  13. */
  14. el = el && inBrowser ? query(el) : undefined;
  15. // 挂载组件的入口函数
  16. return mountComponent(this, el, hydrating)
  17. };
  1. // 先将 mount 缓存起来
  2. var mount = Vue.prototype.$mount;
  1. // 完整时构建
  2. Vue.prototype.$mount = function (
  3. el,
  4. hydrating
  5. ) {
  6. el = el && query(el);
  7. /* istanbul ignore if */
  8. if (el === document.body || el === document.documentElement) {
  9. warn(
  10. "Do not mount Vue to <html> or <body> - mount to normal elements instead."
  11. );
  12. return this
  13. }
  14. /**
  15. * @desc 用于当前 Vue 实例的初始化选项。需要在选项中包含自定义 property 时会有用处
  16. * @type {{}}
  17. */
  18. var options = this.$options;
  19. // resolve template/el and convert to render function
  20. if (!options.render) {
  21. var template = options.template;
  22. if (template) {
  23. if (typeof template === 'string') {
  24. if (template.charAt(0) === '#') {
  25. template = idToTemplate(template);
  26. /* istanbul ignore if */
  27. if (!template) {
  28. warn(
  29. ("Template element not found or is empty: " + (options.template)),
  30. this
  31. );
  32. }
  33. }
  34. } else if (template.nodeType) {
  35. template = template.innerHTML;
  36. } else {
  37. {
  38. warn('invalid template option:' + template, this);
  39. }
  40. return this
  41. }
  42. } else if (el) {
  43. template = getOuterHTML(el);
  44. }
  45. if (template) {
  46. /* istanbul ignore if */
  47. if (config.performance && mark) {
  48. mark('compile');
  49. }
  50. /**
  51. * @desc 检测最终编译的模板是谁 ? 字符串模板, "<div id='app'></div>"
  52. * @type {*|{}}
  53. */
  54. var ref = compileToFunctions(template, {
  55. outputSourceRange: "development" !== 'production',
  56. shouldDecodeNewlines: shouldDecodeNewlines,
  57. shouldDecodeNewlinesForHref: shouldDecodeNewlinesForHref,
  58. delimiters: options.delimiters,
  59. comments: options.comments
  60. }, this);
  61. var render = ref.render;
  62. var staticRenderFns = ref.staticRenderFns;
  63. options.render = render;
  64. options.staticRenderFns = staticRenderFns;
  65. /* istanbul ignore if */
  66. if (config.performance && mark) {
  67. mark('compile end');
  68. measure(("vue " + (this._name) + " compile"), 'compile', 'compile end');
  69. }
  70. }
  71. }
  72. return mount.call(this, el, hydrating)
  73. };