当然是可以的.
Reacthooks通过重复调用模拟algebraiceffects,从而使得每次useState变量都能拿到最新的值。但只是在获取值的时候不需要.value,改动的时候需要调用函数,而且带来很多其他限制和代价(比如必须要给useEffect传递正确的依赖数组,不然回调里的变量引用就会是过期的)。另外Reacthooks跟react组件上下文强绑定,hooks脱离react组件就无法使用,更别提脱离react框架了。
Svelte通过分析组件scriptAST进行编译来改写你的源码,比如a=1后面会插入一个invalidate()函数来通知组件。这样做也有一些代价,比如:
只能通过给变量赋值来触发更新。比如你写arr.push(1)就不行,必须写arr=[...arr,1]
嵌套的函数内声明的变量就不能触发更新,也不能传递出去。
跟hooks一样跟组件上下文强绑定。脱离组件上下文就不能使用赋值响应式,而必须用另一套storeAPI。
强依赖编译。没有编译这一步就不能用。
Vue3的响应式系统本身最大的特点是不仅不依赖编译,而且跟组件上下文无关,甚至跟Vue框架其它部分也是解耦的。同一套系统你可以用在Vue组件里,组件外,其他框架里,甚至用在后端。
在无编译的前提下,JS是不可能做到靠赋值触发更新的。或者说靠赋值触发更新本身就是披着js外衣但做着js做不到的行为的黑魔法。有些人会觉得违背js标准行为不好,但有些人觉得比起带来的开发体验收益,这么一点点黑魔法是可以接受的。
开头提到的reftransform就是在以Vue的响应式系统
做基础,配合编译的前提,做到能够对用开头的API声明的变量以赋值触发更新。比起Svelte还顺道解决了一些问题:
因为底下依然是Vue的响应式系统,所以对对象的操作也能触发更新,比如arr.push(1)就能正常工作。
能够在嵌套函数内使用,并且用配套的宏传递出去。
跟组件上下文解耦,在ts/js里也能使用。组件内外依然使用同一套系统,同一套语法。
总的来说,由于js的语言限制,响应式系统是逃不过类似于atom的概念的。Svelte是组件内外两套系统并且强依赖编译,Vue则是基于同一套不依赖编译的系统,并在可以编译的情况下提供改善体验的语法糖。
点