Vue1
时代
Vue1.0
就是在<script>
标签中引入的写法:
<script src="https://.....vue.js"></script>
这种方式简单快捷,所以吸引了一群 PHPer
。PHP
的流行框架作者还发文狂赞 Vue
,于是众多粉丝就跟风过来了。
但这种方式也有它的缺点,那就是需要在运行时解析 DOM Tree
。然后再绑定各种响应式变量啥的,很耗费性能。做做小项目还行,但想要做大做强那就有点费劲了。
说句题外话,Vue1
这种方式深受 PHPer
的喜爱,以至于 Vue1
不再维护后,PHPer
仿照其做了个类似的框架 Alpine.js
:
这个框架的作者还因此成为了人生赢家:
所以说也不一定非得要做大做强才能赚钱,只要有人喜欢你目前的形式,即使有这样那样的缺点也照样能有自己的一席之地。
Vue2.0
当然 Vue
的发展潜力还是太大了,可不仅仅只是那帮 PHPer
喜欢而已,大量前端也都很喜欢 Vue
。他们希望尤雨溪能够突破性能瓶颈、再创辉煌,于是乎工程化的 Vue2
时代来了。
Vue2
参考了当年流行的虚拟 DOM
技术,同时还实现了单文件组件的写法,这些对于 Vue
而言是巨大的提升。而 Vue
也是从这个版本开始走进了国内的各大培训机构,俘获了大批刚入行的前端粉丝。
由于彼时正处于国内互联网的高速发展期,众多培训机构如雨后春笋般源源不断的向市场输出前端。这又进一步推高了 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
的编译很了解的话还是能过推断出来的)
Vue3.6
随着两款无虚拟 DOM
框架的强势崛起:
- Svelte
- Solid
尤雨溪敏锐的发现这是新的技术趋势,毕竟这两款框架在市场占有率不高的情况下还能常年霸榜:
研究了一下两者的实现,发现虽然 Solid
用的不是模板而是 jsx
,但它的技术实现与 Vue
却更加的相似,编译方式也很符合 Vue
的理念。而另一款无虚拟 DOM
框架 Svelte
的编译方式更类似于 Angular2
:
于是决定采用与 Solid
类似的编译方式,不要一听无虚拟 DOM
就觉得好像倒退了,回到 Vue1
了。
事实并非如此,Vapor
模式和 Vue1
虽然都没有虚拟 DOM
,但我们可以简单的理解为一个是富二代、而另一个是草根。
富二代是一出生家里就把你的人生给安排好了,条条大路通罗马,怎么走怎么顺,不需要自己去摸索。
而草根则是需要一步步自己摸索、试错、比富二代会多走许多弯路。
这就是他俩的区别,Vapor
模式的 Vue
在编译打包后运行在浏览器时已经知道了更新路线,不需要 diff
(指的是非列表,列表间还是需要diff
)在编译时就已经把响应式变量与对应的 DOM
结构搭桥牵线了。
而 Vue1
更新的时候就费劲了(由于没看过 Vue1
代码就不瞎说了)反正肯定不像 Vapor
模式那样有早已被“父母”规划好的路线,肯定得遍历,挨个试错,最终才能找到正确的路。