尤雨溪:从Vue1到Vue3.6

6,489 阅读4分钟

image.png

Vue1时代

Vue1.0就是在<script>标签中引入的写法:

<script src="https://.....vue.js"></script>

这种方式简单快捷,所以吸引了一群 PHPerPHP 的流行框架作者还发文狂赞 Vue,于是众多粉丝就跟风过来了。 但这种方式也有它的缺点,那就是需要在运行时解析 DOM Tree。然后再绑定各种响应式变量啥的,很耗费性能。做做小项目还行,但想要做大做强那就有点费劲了。

说句题外话,Vue1 这种方式深受 PHPer 的喜爱,以至于 Vue1 不再维护后,PHPer 仿照其做了个类似的框架 Alpine.js

image.png

这个框架的作者还因此成为了人生赢家:

image.png

所以说也不一定非得要做大做强才能赚钱,只要有人喜欢你目前的形式,即使有这样那样的缺点也照样能有自己的一席之地。

Vue2.0

当然 Vue 的发展潜力还是太大了,可不仅仅只是那帮 PHPer 喜欢而已,大量前端也都很喜欢 Vue。他们希望尤雨溪能够突破性能瓶颈、再创辉煌,于是乎工程化的 Vue2 时代来了。

Vue2 参考了当年流行的虚拟 DOM 技术,同时还实现了单文件组件的写法,这些对于 Vue 而言是巨大的提升。而 Vue 也是从这个版本开始走进了国内的各大培训机构,俘获了大批刚入行的前端粉丝。

image.png

由于彼时正处于国内互联网的高速发展期,众多培训机构如雨后春笋般源源不断的向市场输出前端。这又进一步推高了 Vue 在国内的市场份额,形成了一种良性循环。

当然也不是说 Vue 只在国内火啊,只是那时恰逢历史机遇,再加上 Vue 的作者是华人。相对于其他框架不那么友好的中文文档来说,Vue 会让人感觉更加亲切。所以它在国内的表现可谓是一路高歌猛进,在海外市场同样也有着亮眼的表现,只是没有国内市场这么夸张罢了(毕竟咱们从业人数暴涨)

Vue3.0

但随着时间的推移尤雨溪慢慢发现,这个框架其实还有优化的空间。它根本没有必要像 React 那样一对一的编译成虚拟 DOM,因为很多情况下编译器是能够分辨出哪些 DOM 是永远不会发生变化的。还有就是如果有一大串连续的静态模板,那也没有必要像虚拟 DOM 那样层层嵌套:

<ul>
  <li>1</li>
  <li>2</li>
  <li>2</li>
</ul>

原来是编译成:

// 伪代码 明白意思就行 不必较真
createElement({
  type: 'ul'
  children: [
    createElement({
      type: 'li'
      children: [createText('1')]
    }),
    createElement({
      type: 'li'
      children: [createText('2')]
    }),
    createElement({
      type: 'li'
      children: [createText('3')]
    })
  ]
})

上面这种编译方式不仅生成的代码量相对较多,而且运行效率还比不过 innerHTML,所以 Vue3 发现是大段的连续的静态模板就会给编译成:

// 伪代码 明白意思就行 不必较真
this.$el.innerHTML = '<ul><li>1</li><li>2</li><li>3</li></ul>'

所以 3.0 的编译方式发生了很大的改变,做出了很多的优化,比方说:标记静态虚拟 DOM、静态提升、innerHTML 等…

原来的编译方式是一对一的,也就是像 React 那样:看 jsx 就能猜到编译后的 js 大概长啥样。而现在的编译方式是再看 <template> 里的内容已经比较难以推断出编译后的样子了(当然如果对 Vue3 的编译很了解的话还是能过推断出来的)

image.png

Vue3.6

随着两款无虚拟 DOM 框架的强势崛起:

  • Svelte
  • Solid

尤雨溪敏锐的发现这是新的技术趋势,毕竟这两款框架在市场占有率不高的情况下还能常年霸榜:

image.png

研究了一下两者的实现,发现虽然 Solid 用的不是模板而是 jsx,但它的技术实现与 Vue 却更加的相似,编译方式也很符合 Vue 的理念。而另一款无虚拟 DOM 框架 Svelte 的编译方式更类似于 Angular2

于是决定采用与 Solid 类似的编译方式,不要一听无虚拟 DOM 就觉得好像倒退了,回到 Vue1 了。

事实并非如此,Vapor 模式和 Vue1 虽然都没有虚拟 DOM,但我们可以简单的理解为一个是富二代、而另一个是草根。

富二代是一出生家里就把你的人生给安排好了,条条大路通罗马,怎么走怎么顺,不需要自己去摸索。

而草根则是需要一步步自己摸索、试错、比富二代会多走许多弯路。

这就是他俩的区别,Vapor 模式的 Vue 在编译打包后运行在浏览器时已经知道了更新路线,不需要 diff(指的是非列表,列表间还是需要diff)在编译时就已经把响应式变量与对应的 DOM 结构搭桥牵线了。

Vue1 更新的时候就费劲了(由于没看过 Vue1 代码就不瞎说了)反正肯定不像 Vapor 模式那样有早已被“父母”规划好的路线,肯定得遍历,挨个试错,最终才能找到正确的路。