Angular、React、Vue三大框架逻辑复用横评

转载自:江湖术士 

https://zhuanlan.zhihu.com/p/208249521

其实这个文章早在16年左右有感于 ng 的学习就想写了,但是却发现,除了 ng 以外,当时的 React 和 Vue 都缺乏简单有效的逻辑复用方案,不过这也引导我将 React 和 Vue 都学习了,对自己的职业也有了积极的意义 

一个 nger 找工作有多难,你们知道么?但是标榜 vuer/reactor 之后,真的是一投一个准,个中滋味可以自己体会,我当然还是建议 nger 学学其它框架,你如果真的理解 ng,其它框架的学习都是降维打击,比如 Vue composition 一发布,你看一眼就知道最佳实践应该是什么样子,框架没有高低之分,学 ng 的那些痛苦一定是会有回报的,心思活跃一点就好,不要死守着一个平台

前端反内卷还是很坚定的,你看 java,内卷到不行,动不动就问服务治理,netflix 标准啥的,DDD,SOA,微服务张口就来,设计模式少背一个就被批基础不牢,然后给个5,6000工资,你看我们前端多好,理解面向对象和纯函数就能拿高工资

自嘲归自嘲,就目前的情况来看,前端的好日子应该是到头了,React Vue 都有了自己的逻辑复用方案,这时候不妨来一个横评,大家除了了解各个框架异同以外,也能窥探一下整个行业的发展方向


响应式

ng 首先实现逻辑复用不是没有原因的,并不是说 ng 的开发者比其它平台的厉害多少,这个尤大已经有过表述,最大的原因在于,ng 的响应式对象,直接采用的微软出品的成熟库

rxjs —— angular

配合 rxjs 使用的 zone.js 也是事件驱动响应式的典型,这个和 React,Vue 的方案有所不同,在数据量大的情况下性能非常强,但是在 “多 watcher 少量数据”下性能要很弱,这也使得最佳实践的难度非常之高 —— 业务逻辑用极限函数式开发,无变量,无状态,无watcher

Angular、React、Vue三大框架逻辑复用横评_第1张图片

这是 Angular.cn 入门教程英雄指南的一个代码片段,你能感受到16年初学习 ng 时我的绝望么?它只是个入门引导,但是我认得它,它不认得我啊!想象一下,Vue 讲模板语法的那一章突然来个这个,你是什么感觉

而且,因为事件驱动和 zone 的暴力代理,某些情况下需要 runOutside 和 changeRef,要知道事件驱动费脑,数据驱动费手,选择这个方式必然推广困难,你想想,写业务是加个标识位简单,还是加个管道简单?

普通程序员接触 rxjs 也很有可能是后来 react 平台推广的结果,多个 React 工具文档出现了 rxjs 导致的?后来出现了很多用于学习 rxjs 的工具,比如:https://reactive.how/,即便有那么多的视频讲解,真正保证学会 rxjs 并用好的的,应该也只是极少数人

这东西和ramda,都属于成年噩梦,最大的问题是,废了老大劲学的东西,实际开发中却很少用到,这种落差感也是非常的大,后来我知道是自己用法的问题,尤其是 react hooks 出来之后比较 react 的用法,才更清晰的明白最佳实践应该是怎样的,不过在缺乏文档,缺乏引导的情况下,你确定你知道该怎么做?

Memorized hook —— react

其实很简单,就是一个数组结构中的 getter 和 setter 的控制反转 monad:

const [value,setValue] = useState('')

平心而论,这个结构是真的太直观了,响应式本来是啥,就是 getter 和 setter 啊,呐,你看,getter 和 setter

当然,拆开这两部分并不只是为了直观的原因,还有一个很大的原因是,React 平台死守不变性原则,也就是无赋值,无变量,保证函数式开发体验

这也是 为何 大对象建议业务上使用 useReducer 的原因,也是死守不变性的结果,当然,你牛你可以自定义 hook

这个函数式开发体验并不极限,比 rxjs 那种调用链管道模型要简单(React 程序员要有清晰的认识啊,函数式不是用来内卷的工具,至少碰到其它管道框架的时候得稳重点),当然也有死守管道风格的框架,cycle,那就更反人类了,这种东西用在金融系统,武器系统的开发可以,用在前端意欲何为?我是真的认为这个东西是大炮打蚊子,ng 毕竟还有 baas 服务,有前后端同构的考量,cycle 这个真的是存粹的兴趣爱好了,发扬极客精神,另外自定义 hook 也可组成管道,这时 react 的极限函数式风格就来了,大家可以使用 ramda 封装试试

不过 rxjs 还有一个好处,在 vue 没有逻辑复用的时候,vue-rx 给我开了个逻辑复用的口子,让开发效率提升了非常多,你看,我就说东西都不会白学的嘛,当然,rxjs 的侵入性很强,rx 配合谁都是 rx当主角,其它技术栈当配角

说到 Vue,其实就是无“不变性”要求的 React,这么说有点粗暴哈,但是对于一个之前的 nger 来说,Vue 和 React 的差异真的只是写法上的差异,原理上并未有太多区别

但是思想上确实有个重大的区别,那就是:

为啥要追求函数式?追求更好的可调式性?前端有那么多业务逻辑么

问问后端程序员,把逻辑放在前端是个很好的设计风格么?

当然这是在不考虑前后端同构语境下的想法,ng 引入一个 module 直接支持ssr,next 只是 react 的轻度再封装,nuxt 可是要复杂得多,也和这个思想有一定关系

不过这种想法细想一下,有没有道理?从业过程中我发现很多开发人员对 Vue 平台有意见,固然有文人相轻的因素在里面,但是好好想一想吧,那些模式用在 后端 是不是更有意义

所以直接上 proxy,setter,getter 合二为一,完成响应式:

Proxy —— vue

直接一把梭,管他的,用就完事儿

vue 如此火爆,不是没有原因的,面向简单编程,因此主要的响应式,什么概念都可以丢掉,左手 ref,右手 reactive 打天下:

const ref = useRef(null)
const data = reactive({xxx:1})

尤其是新版本代码风格,上手成本直线下降,个人觉得 vue 新版本发布才是真正宣告前端进入新时代的标志


组件语法

Angular

Angular 的响应式需要配合管道使用:


这里有个问题,如果对象需要进一步操作,复杂度稍稍有点增加:


没有计算属性的概念,有的只是管道复用:

const origin$ = new BehaviorSubject('')
const init$ = origin$.pipe(res=>res+'inited')

副作用在 subscribe 处理:

// 普通
click$.subscribe(...)

// 最佳实践认为,副作用应该得到控制,比如请求是个新的流
const data = click$.pipe(switchMap(()=>request('....')),map(...))
// 而 data 又用于视图

但是因为是管道,副作用直接全部在视图处理,这也是极限函数式处理业务的优势,哪里输入,哪里输出安排的很明白,当然,这难度也是够你喝一壶的

独门亮点,单独的模板作用域和模板引用变量

比如你需要一个动态组件,声明一个模板引用变量:



  

注意,这个 content 是不需要在组件中声明的,直接在模板标记,就可以到处传值,这个和 Vue 的区别很大,Vue 的 # 只是 slot 语法糖,传递数据用的,在这部分内容的复用上要弱很多

弱点or亮点?指令封装 spy

ng没有直接提供生命周期的逻辑复用,而是需要你去实现生命周期 spy 指令,比如官方示例:

// Spy on any element to which it is applied.
// Usage: 
...
@Directive({selector: '[mySpy]'}) export class SpyDirective implements OnInit, OnDestroy { constructor(private logger: LoggerService) { } ngOnInit() { this.logIt(`onInit`); } ngOnDestroy() { this.logIt(`onDestroy`); } private logIt(msg: string) { this.logger.log(`Spy #${nextId++} ${msg}`); } } // props 改写,用流 @Directive({selector: '[mySpy]'}) export class SpyDirective implements OnInit, OnDestroy { @Input() change$:BehaviorSubject('') ngOnInit() { this.change$.next(`onInit`); } ngOnDestroy() { this.change$.next(`onDestroy`); }

如果实现为一个流,那么就可以如下使用:


这样就可以把生命周期逻辑全部写在服务中了,好处是指令更加灵活,坏处是,很多时候默认没有,程序员就不会去使用,导致生命周期逻辑不进行封装,增加开发和架构难度

这一点上可以见仁见智了

React

Jsx 的优点当然不是大家以为的 ts 支持,很多 react 程序员喜欢拿着 jsx 和 vue2 的 template 比类型支持,这很容易让人笑掉大牙的,毕竟 ng 都出来五年多了,但凡用一下也不会有这样的想法

但是有一点 JSX 的优势是非常大的,那就是上下文清晰

Angular、React、Vue三大框架逻辑复用横评_第2张图片

典型的函数作用域,甚至不需要思考,哪个变量属于哪个对象一目了然,这是单独封装模板甚至单独拆文件的框架很难得到的体验,比如 vscode 平台有个 ngSwitch 工具,那就用的很无奈,注意,Jsx 的最大优势是这个——充分利用函数作用域,以后看到 ts 我都懒得反驳了,完全是八竿子打不着的东西

另外还有 jsx element 的灵活性,这个很直观,不用赘述

但是 Jsx 不是还有劣势么?可读性

有逻辑复用之后,组件没有业务逻辑,好的方案一个组件函数中只做变量填空,Jsx 的劣势一下子被抹掉,忽然有种 Jsx 春天来了的感觉,具体情况如何还需要看最后社区的选择,尤其是 Vue 这种同时支持两种写法的方案

不过,React 的 Hook 却在一个地方降低了可读性

我怎么知道你这个变量是响应式的,还是非响应式的?毕竟你还有个 useRef 在那里呀,对象也可以直接写啊~

{value}

就这样的代码,你怎么知道 value 是不是响应式的?相比之下,Angular 管道显示声明 | async,响应式变量也有命名标准,Vue 有 isReactive 等工具(当然作用也有限),React 这里就很难控制了

所以建议不要将 hooks 拆开,作为整体声明和传值,带上响应式标识$也不是不可以:

const value$ = useState('')
{value$[0]}

当然这个数组取值也是很难受,尤其是遇到依赖数组的情况,官方不做这种推荐是因为 ——

函数式体验

对,还是他妈的函数式体验,因为在函数式开发中,状态也是函数,有点拗口哈,就是没有存储的“量”,即使是不变量,也是返回确定数据的函数 Identity

唉,学院派简直就是西装暴徒!用的人真的好无奈啊

副作用在 useEffect 处理:

useEffect(()=>{
   ...
},[...])

因为不是管道逻辑,没有流那样对副作用限制得那么狠,显然这个 useEffect 最好是不要用的,因为副作用理应得到控制,但是这个标准以这种写法实现起来实在是太难,官方都只能给你开个过程式处理副作用的口子

独门亮点 —— 弱化生命周期

这个是真的亮点了,想想你需要生命周期么?你其实并不需要生命周期啊

整个应用拢共就视图变化和状态变化两个,effect 和 layoutEffect 还不够么?

当然这一点 ng,vue 现在也一样,不过有意思的是,react 用空依赖数组做首次更新,用返回值做析构,api 精炼了好多

再看看 ng 的 spy,其实原生这种 api 应该是会更好的,尤其是 rxjs 配合 生命周期

理论上来说,生命周期其实都是不需要的,响应式就让他自己触发自己变化好了,为啥要解开它,watch 它?你看 ng 的 rxjs ,你只用写一个个管道就够了,函数式响应式处理业务,没必要去关心具体的状态

这个真的想给 React 一个大大的赞,等于是强制前端开发进化+内卷,接受函数式开发更进一步,咦,为啥强制内卷我还挺开心?

弱点 or 亮点?—— 依赖数组

他妈的依赖数组!

所有用 React 的人不信你没骂过,没办法,死守不变性嘛,没依赖就不纯了

他妈的不变性!

这个玩意儿是真的恶心,写不写是一方面,你别再代码里给我报一长串 warning 啊,好难受啊,太不近人情了

所以看你狠还是我狠,大不了老子不写 effect,结果发现 useMemo 也要写,唉~

React 可以说是强迫症的最爱吧,其实完完全全的函数式用于生产环境真成问题,否则haskell早就一统后端市场了

一般来说函数式在处理运行时业务逻辑更有效,但是数据结构,初始化等问题,还是面向对象更为擅长一些,这也是 Angular 为啥组件服务用 class 组织,业务逻辑用 rxjs 的原因,各取所长嘛

Vue

面向简单编程

模板帮你取value?

{{test}}
setup(){ const test = ref('') return {test} }

这是亲妈风格的 api 封装啊,这已经和原理相悖了,proxy 对象封装,只有 test.value 才能操作数据,为啥写的时候要 test.value = xxx, 用的时候就 test 了呢?

只能理解成亲妈式封装,门槛能降一点是一点

这种思想其实在 Vue 的设计中随处可见,用户要啥,就给啥,一切从用户体验出发,还是那句话,前端能有什么业务逻辑,难道没用设计模式,支持不变性,就能让你操作数据库了么?

怎么简单怎么来,composition 状态复用只有两个 api,不变性 api ref,和 深层可变 api reactive

哈哈,反着来了,因为有getter,setter,所以 ref 等同于 React 的 useState,而 reactive 等同于 React 的 useReducer,仔细想想是否如此,因为不遵守不变性了(写法上),setup 只运行一次,所以类似 React 的 ref 就没了

只运行一次,所以很多问题得到了简化,按官方的说法就是:

一般来说更符合惯用的 JavaScript 代码的直觉;
不需要顾虑调用顺序,也可以用在条件语句中;
不会在每次渲染时重复执行,以降低垃圾回收的压力;
不存在内联处理函数导致子组件永远更新的问题,也不需要 useCallback
不存在忘记记录依赖的问题,也不需要“useEffect”和“useMemo”并传入依赖数组以捕获过时的变量。Vue 的自动依赖跟踪可以确保侦听器和计算值总是准确无误。

直觉这个东西说的没错,函数式就是反直觉的,函数式基于范畴论是拿给你计算的,不是那给你撸的,但是这句话总感觉差点什么,这么说就对了:

更符合过程式 JavaScript 的直觉

其它问题也都是函数式风格的问题,但是函数式的优点也是有很多的,最后看你适合什么方案,比如 Vue 的 vca 方案,就几乎和 React 无差别了:

// Before compiling

import { ref } from '@vue/composition-api';
 
const Hello = (prop, ctx) => {
    const state = ref('Hello World!');
    return () => (
        

{state.value}

); }; // After compilation import { ref, createElement as h } from '@vue/composition-api'; const Hello = { setup: (prop, ctx) => { const state = ref('Hello World!'); return () => { return h('h1', state.value); }; } };

当然,Vue 的 Jsx 用法和 React 有很大差别,比如属性绑定,render 有多个属性,详情间官方文档,其次是参数类型提示问题,这个还需要时间来解决,但是这个的工作量应该是非常大的

模板语法上没啥亮点,功能性和 Angular 相比差了非常多,vls 的使用并没有 als 方便,但是,Vue 能用 js,ng 早就放弃了 js,高下立判,很多人就是接受不了ts,

独家优势 —— 动画

原生集成了一个比较简单的动画方案,包含状态过度以及显示动画,很多人觉得这有什么大不了的,ng 也有啊,很抱歉,我在15年底第一次看文档的时候,ng 的动画实现方案,把我的头弄炸了

React 也需要第三方库来做状态动画,当然,也有人说,有逻辑服用,直接写个 use 不也能实现

有这些想法的人,是个合格的程序员,但是不是一个合格的产品经理,可能切中了技术要领,但是没有切中市场要领

对于很多初学者来说,我不想知道你有什么新技术,也不想知道你的封装方式有什么优点,我就想看你简不简单!

Vue 这种加 class 名的方案,就是很好的,很简单的,初学者也能写出良好交互体验的网站,前端的重点真的在业务逻辑上么?想多了,前端的重点就是在炫目的交互效果和UI效果上的,其它的都只是附加的东西(非前后端同构,非跨平台的纯前端项目),很多人都低估了 Vue 在这方面的竞争力

大家可以自行比较一下ng和vue的动画方案:

Angular - Angular 动画简介:https://angular.cn/guide/animationsAngular、React、Vue三大框架逻辑复用横评_第3张图片

进入/离开 & 列表过渡 — Vue.js:https://cn.vuejs.org/v2/guide/transitions.html

也可以对比一下 React 第三方库 ant motion:

Ant Motion - Ant Design 的动效规范与组件:https://motion.ant.design/index-cn

大厂有包袱,他们做的东西不仅要满足实际使用者,还要满足同行和学界的挑剔目光,因此很多好用但反模式的东西不敢去做,我们的话无所谓,干的就是搬砖的活,端着干啥

绝大部分的人工作并不是造火箭,普通人改变不了世界,快速完成从零到一,也是一种实事求是的态度


应用架构

这个不用说了, Angular 第二,没人敢说第一

确实有复刻 Spring 相关技术栈的影子,Nestjs也是如此

但是这个架构确实好啊,确实牛逼啊,大型的成熟项目后端,哪个不是 SOA 打天下的?

15年 Angular 主推 SOA 的时候,争议是真的大,那个时候 React 和 Vue 连成熟的逻辑复用都没有,这边就 IOC,依赖注入了,社区之间的谈话谈话都是鸡同鸭讲,语言都没统一, 你说函数式响应式,他说纯函数,你说面向业务DDD,他说你说的都是后端概念,你说类型完备,他说Vue怎么就不能用Ts了?无意义的争吵太多

了解那段时期氛围的人都知道,确实很浮躁

现在好了,相关说明和解释出现在了 React 和 Vue 的官方文档,语言终于能够统一了

provide/inject , useContext/Provider,都已经成为主力 API,人们开始了对 Redux/Vuex 有没有意义的争论,类似当年ng社区对ngRx的争论,摘要一下哈:

  1. redux 模式是纯函数?rx 操作函数就不是了么(ng)?useState 就不是了么(react)?vue 平台不要纯函数(vue)?

  2. 要保证单一数据原则?providedIn:'root' 就不是单一数据了(ng)?app provider 就不是单一数据了(react,vue)?

  3. 方便调试,生命周期都没有你怎么方便调试?找出了dispatch还要去找生命周期,不闲得慌么?

  4. 跨组件数据传递?你在抹黑这次更新

  5. 封装方便团队协作?逻辑都封装不到一起,协哪门子的作,用 cdk/ahooks,能和 阿里/谷歌 协作

  6. 状态本地化?useLocalStorage 不香?

  7. 服务端状态保持?rxjs 的 retry,timer ,ahooks 的 manual, pollingInterval 不是吃干饭的

历史的问题就不用再纠结了,可以先看看 Angular 的架构强大在哪里:

类型完备

只支持 Typescript 并保证 99% 的可访问 api 都有类型推断,这点React就望尘莫及了,只给接口和泛型,不给类型推断,数据和类型声明分离,Typescript 在不将类型看作函数进行二次封装的情况下,使用体验非常差

而且我相信,React 本身就讨厌 Typescript,原因很简单,对,没错,就是函数式体验~

又他妈的函数式体验

函数式开发中类型的作用和功能与面向对象不同,类型更多是起到校验作用,类似于一个运行时的测试机制,这点可以去看 Car Baaz 的访谈:

https://www.techug.com/post/haskell-production-retrospective.htmlwww.techug.com

压根就没有集成数据结构的概念,要是按照用 ng 的类型使用方式去用 React,怎么用怎么别扭,所以需要你二次封装,相当于编写了一个 运行时测试 ……

但就我看过的代码,大多数 Ts 版本 React 开发者,没有这个意识,而且,React 这种用法,结合Flow才是最合适的,运行时测试和编译前校验,区别非常大,也是因为社区追捧 Typescript 吧,被裹挟了

自动依赖注入

Vue 也有依赖注入了,而且用法非常简单,但是并没有实现完全的 IOC,需要手动 Provide,Inject,还需要加 Token(Symbol),和单独的类型声明

Ts 语境下,这部分封装成 Class 可以优化

import { Ref, ref, provide, InjectionKey } from "vue";

export class TestData {
  test: Ref;
  constructor() {
    this.test = ref("init");
  }
  change() {
    this.test.value = "fuck";
  }
}
export const Token: InjectionKey = Symbol();

export default {
  name: "App",
  setup() {
    const testData = new TestData();
    provide(Token, testData);
    return { testData };
  },
};

Class 的作用主要是为了将数据的声明和类型的声明集中,提供初始化入口,方便计入 InjectionKey 的泛型,你可以看到,还是有 new,如果要好一点的类型体验的话

这个 new 就很烦躁了,面向对象,new 是万恶之源,严格来说这并非强类型语境下的依赖注入,IOC并未完全实现(初始化逻辑未接管

但是 ng 就要简单多了,一般情况下:

Angular、React、Vue三大框架逻辑复用横评_第4张图片

构造器参数声明,即完成注入,当然啦,这也有 Vue 的无奈,原因很简单,这样的 IOC 方案需要装饰器加类型反射(reflect-metadata typeName:)才能实现,而 Vue 还需要将就 Js 使用环境:

Angular、React、Vue三大框架逻辑复用横评_第5张图片

但是这样的话,架构扩展性和 ng 相比就有很大差距了,不过这不妨碍 Vue,原因很简单——你能在前端做出微服务集群来,算我输,前端没有强业务逻辑,用不到牛刀杀鸡——当然这个问题见仁见智了

可配置Module

一般情况下被视为花活,但在 google adword 这样的应用中被视为刚需,那就是可配置 Module

Angular、React、Vue三大框架逻辑复用横评_第6张图片

将一个服务包含依赖以及相关视图打包,用于优化编译器

比如,你要用 Angular CDK 功能,直接在需要用 cdk 的 module 中imports cdk 某个功能 就可以了:

import { DragDropModule } from '@angular/cdk/drag-drop'
…
@NgModule ({....
  imports: [...,
  DragDropModule ,
…]
})

然后这里面有的组件,指令,服务啥的,都随便用,大门敞开,不需要像 Vue 一样,import Component 再 声明 {components: { someComponents},filters, ... }

其实就是耗费开发的时间,节省使用的时间

同时,指令真的好用,React 技术栈真的好可惜,没有这个功能呢,高阶组件再怎么说也是封装,封装和附加的区别还是很大的,就和装饰器跟继承的区别一样

其它的还包括他的多语言架构,简单的ssr同构,baas同构(angular/firebase),以及,以后系列文章会讲到的,微前端 —— 利用module封装其它技术栈代码,生成shadowDom,当然,这个特性还包含 Angular 的样式封装特性,从编译源头解决 shadowDom 的同构问题,还有开发时cli辅助,路线图等等非常工程化的特性

数据结构用极限面向对象解决,业务逻辑用极限函数式解决,什么都走极端就对了,下限和上限都非常高,弱点就是容易曲高和寡,应者了了,前端程序员应该去学习,但是生产环境使用的话谨慎吧,毕竟是前端,明白自己定位最重要,那些概念学了之后,用在nestjs上搞微服务多好?

Nest.js 中文文档docs.nestjs.cn

前端的数据量和业务量,除非你真能搞个 adword 一样量级的创收项目(稳定性要求,多样化需求,全球化,交易服务等会让业务复杂度直线上升),不然真的**有牛刀杀鸡的嫌疑,**喜欢端着不是件好事,技术的选择应该契合业务,而非业务契合技术,大部分情况下这个架构更适合后端的业务量和数据量,所以 nestjs 的热度逐年上涨,甚至有成为Java程序员逃避死板代码的避风港的趋势,也算是意料之中

Angular 可以作为一个相关概念的学习基地,方便你很快地切换到后端开发,同时也可以引导你了解项目架构的最佳方案应该如何,方便你自己搭建其他平台项目的架构,实际使用的话,能保证团队成员意识形态一致,有较高的追求,可以一试,但也仅仅是一试,有点脱离基本面了,效率,人员等都是没有保证的,很多国内公司切换过 angular,又切换回来了,不得不向现实低头

不过不用笑 Angular,React 一样有点脱离基本面,只是说普通人很难写出最佳实践而已,简单易用还是有保证的,这点比 Angular 强

但是,过程式一把梭,面向对象只要求你想清楚,函数式要求算清楚啊!我们这些大学离散数学只有60分的学渣,怎么搞定态射演算啊,只记得住一个结合律,其他啥都忘了,当然后面有补课,过程也是痛苦万分的,现在又在遗忘的边缘试探

而且函数式无所谓架构,自底向上,一步步累进封装,保证灵活性和测试完备,理想非常丰满,现实也是骨感得很,要知道函数式基础不牢固,一个点坏掉,这个系统都危险,要是架构部分的需求变化,面对那一坨陀错综复杂的函数,很容易让人失去信心的

简单来说:
函数式自底向上:我搞了一堆功能和函数,都有完备测试,看看能做点啥
面向对象自顶向下:我要做一个系统,它由以下抽象类组成……

所以到头来还是用和Vue一个封装层级的框架完成开发,类似 umi,才能满足生产环境的需求,变换为自顶向下的开发模式,这实际上是反函数式

这时候不变性,纯函数成了累赘,有没有人计算过这个纯函数和不变性到底节省了多少测试成本,优化了多少性能?再问尖锐一点,有写红蓝测试的习惯么测试有为函数式开发做配套支持么?技术追求和实际需求是有断代的,更不要说之前无逻辑复用还能用函数式用的那么嗨,样板代码一大堆,接手的人望洋兴叹,有技术主导需求的嫌疑,并非一个好的企业架构

所以 React 存在和 Angular 一样的问题

另外,逻辑复用应该算个大更新,应该用很大的魄力回炉重造,Angular 有这个魄力划清界限,但是 React 没有,还存在很多历史问题没有解决

要知道很多 Angular 工具和 React 工具都是在解决框架本身的问题,很多 React 工具本身就是用来解决逻辑复用,或是强制自己实现逻辑复用开发出来的,比如大堆的第三方库新版本已经没有意义,redux,redux-thunk,各种工具库,在新版本语境下已经不知所谓了,还会成为历史遗留问题继续产生作用,既限制开发者,也限制框架开发

当然,函数式天然和架构不沾边也是问题之一,你见过什么大型工程项目是存粹用函数式搭建的?有数学完备支持的,理想的无bug系统,终究只是理想,现实世界是充满复杂性的,Angular尚且可以回退到promise,非rx使用方式,React这个函数式一把梭,真的有些强人所难了,happing hacking,但是普通开发者不是 hacker,没必要陪着你一起追求美好未来吧?

喷了一通,如果让我一个人做一个中小型项目,一个人做一个大型项目(基本不可能哈),我还是会选择 React 和 Angular,怎么了,我就是追求美好未来的三有青年呀~

那么接下来就是历史和市场的选择,前端代言人了 ——

一把梭,面向简单,文档支持完美,循序渐进,前端内卷缔造者,Vue

Angular,React 还会纠结逻辑复用版本的接受度问题,Vue的方案,真心没啥负担

你想想,上一版本你还要学单向数据流,还要学响应式原理,还要用 Vuex , Vue.set 啥的,更早还有 event bus,实例响应式数据等等,api面积真的大

现在:ref,reactive,provide,inject 最多加上 mounted 和 watch,6个api打天下,啥单向数据流,直接改了不就完了,你跟新手说单向数据流,可能会被当成 xx,实际上也是,setter在父组件或者服务中,压根没有违背原则,等第三方逻辑库流行,就是完完全全的傻瓜操作了,什么函数式,面向对象,都是后端的概念!

你想想,比你知道的更少的新手,写东西还比你快,难受不难受?纠结不纠结?

内卷不内卷?

在 Vue 支持 逻辑复用之后,前端的好日子终究还是到头了,大量新人会涌入,然后抢占市场,压缩开发者薪资

而前端如果不走出 逻辑少,数据少 的泥潭,是不会有未来的

目前几个方向可能寻求突破

  1. 前后端同构,BFF,作为视图服务,成为微服务架构中的一环,不过这个概念很难灌输给 cto

2. 期待新的端到端通讯,成为边缘云中枢,这个很有可能实现,不过短期很难,而且,届时 wasm 可能会抢占传统前端市场

3. 利用前端技术栈在 faas 中的优势,自己创业,或者加入创业公司推广这个吧,成为云服务厂商的帮凶

4. 死守技术栈干嘛,转栈做 devOps 啊,这个才是热点,议价能力强

借这个时机,抖音再投几个广告教授 Vue3 的课程,这个过程不知道要被加速多少倍,被资本家剥削真的太难了

所以你要是真的热爱技术,跳出资本循环,敢于承担风险,做自己吧~

最后

欢迎关注「前端瓶子君」,回复「交流」加入前端交流群!

欢迎关注「前端瓶子君」,回复「算法」自动加入,从0到1构建完整的数据结构与算法体系!

在这里(算法群),你可以每天学习一道大厂算法编程题(阿里、腾讯、百度、字节等等)或 leetcode,瓶子君都会在第二天解答哟!

另外,每周还有手写源码题,瓶子君也会解答哟!

》》面试官也在看的算法资料《《

“在看和转发”就是最大的支持

你可能感兴趣的:(编程语言,xhtml,java,twitter,consul)