# 开局一张图,剩下全凭想

An image 前面Vue2源码分析(一)主要分析了图中第2部分 第2的部分在Compile.js中 我们利用var frag = document.createDocumentFragment();模拟了虚拟dom生成实现 现在我们深入的分析一下第1部分

# compiler

https://github.com/vuejs/vue/tree/dev/src/compiler An image parse(把代码转化成ast)--->optimize(优化)--->generate(codegen再次生成)--->vdom--->dom diff---->patch(补丁) 对应上图文件

# parser

https://github.com/vuejs/vue/blob/dev/src/compiler/parser/index.js An image 主要观察画线部分 主要文件 import { parseHTML } from './html-parser' 正则匹配处理 createASTElement函数

# html-parser

An image 借用jquery去生成

# vdom

create-element->dom diff->patch(生成对比好的vdom)

DOM操作很慢是两个原因,一个是本身操作就不快,第 二是我们(还有很多框架)处理dom的方式很慢,Virtual Dom解决了我们这些愚蠢的程序员对Dom的低劣操作,它让我 们不需要进行Dom操作,而是将希望展现的最终结果告诉Vue,Vue通过一个简化的Dom即Virtual dom进行 render,当你试图改变显示内容时,新生成的Virtual Dom会 与现在的Virtual dom对比,通过diff算法找到区别,这些操作 都是在快速的js中完成的,最后对实际Dom进行最小的Dom操 作来完成效果,这就是Virtual Dom的概念。 rective(descriptor, this, node, host, scope, frag) An image An image An image An image An image An image

# optimize

vue运行时优化 An image 如果是静态节点就不进行计算 An image 把变量外的全部做成静态节点 An image 如果是死的值比如说10个li,那我就直接给你10个li An image 服务端渲染,如果直接转成string,如果存在组件临时进行解析 An image An image An image prefetch下一个页面资源提前加载

An image An image 南京线下会愿景,原子css

An image 变态暴力的prepack(下一步可能会引入) An image An image

# keep-live

keep-alive是一个抽象组件:它自身不会渲染一个 DOM 元素,也不会出现在父组件链中;使用keep-alive包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。

当然keep-alive不仅仅是能够保存页面/组件的状态这么简单,它还可以避免组件反复创建和渲染,有效提升系统性能。 总的来说,keep-alive用于保存组件的渲染状态。

https://juejin.im/post/5cce49036fb9a031eb58a8f9

抽象组件 不让你看不让你操作 An image 自己重新去遍历 An image 但是当内容越来越多(cache)的时候会出现无法GC的情况 this.max 负责清理组件 lru算法清除 prunt oldest entry删除最旧条目 An image

# Vue use

1、首先插件暴露一个install方法,如果vue.use 发现插件有install方法调用,插件发现被调用了 把方法挂在到vue.prototype上,所以插件多会把vue.prototype上挂坏,而且vue.prototype不会被释放

Vue-router 监听浏览器的pushState(h5属性),如果支持返回pushState,走/斜杠的形式,如果不支持走hash模式(监听hash change完事)

https://github.com/vuejs/vue/blob/dev/src/core/global-api/use.js

import { toArray } from '../util/index'

export function initUse (Vue: GlobalAPI) {
  Vue.use = function (plugin: Function | Object) {
    const installedPlugins = (this._installedPlugins || (this._installedPlugins = []))
    if (installedPlugins.indexOf(plugin) > -1) {
      return this
    }

    // additional parameters
    const args = toArray(arguments, 1)
    args.unshift(this)
    if (typeof plugin.install === 'function') {
      plugin.install.apply(plugin, args)
    } else if (typeof plugin === 'function') {
      plugin.apply(null, args)
    }
    installedPlugins.push(plugin)
    return this
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

来看一下vue-router的实现 https://github.com/vuejs/vue-router/blob/dev/src/install.js An image

顺便可以看一下hash、history的实现 https://github.com/vuejs/vue-router/blob/dev/src/history/hash.js An image

https://github.com/vuejs/vue-router/blob/dev/src/util/push-state.js An image

# 核心

An image vuex模仿redux flux模式,后面会分析flux模式

# 总结

  1. vue/src/platforms/web/entry-runtime-with-compiler.js
  2. import { compileToFunctions } from ‘./compiler/index’
  3. 57行template = getOuterHTML(el) 进行了编译 然后调用Vue.prototype.$mount 进行初始化执行 (src/platform/web/runtime/index.js 定义在这) 4.核心调用mountComponent (src/core/instance/lifecycle.js定义在这) 生成vnode 179行 const vnode = vm._render()
  4. vm._render在 src/core/instance/render.js 34行位置 vm.$createElement = (a, b, c, d) => createElement(vm, a, b, c, d, true) 生成vnode节点 最后如下
    render: function (createElement) { return createElement(‘div’, { attrs: { id: ‘app’ }, }, this.message) }

三大框架在职业中也不是昙花一现 技术选型的10点 An image