<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          React、Vue、Angular三大框架邏輯復(fù)用橫評

          共 13158字,需瀏覽 27分鐘

           ·

          2020-09-10 01:26

          作者:江湖術(shù)士?

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

          其實這個文章早在16年左右有感于 ng 的學(xué)習(xí)就想寫了,但是卻發(fā)現(xiàn),除了 ng 以外,當(dāng)時的React 和 Vue 都缺乏簡單有效的邏輯復(fù)用方案,不過這也引導(dǎo)我將 React 和 Vue 都學(xué)習(xí)了,對自己的職業(yè)也有了積極的意義

          一個 nger 找工作有多難,你們知道么?但是標(biāo)榜 vuer/reactor 之后,真的是一投一個準(zhǔn),個中滋味可以自己體會,我當(dāng)然還是建議 nger 學(xué)學(xué)其它框架,你如果真的理解 ng,其它框架的學(xué)習(xí)都是降維打擊,比如 Vue composition 一發(fā)布,你看一眼就知道最佳實踐應(yīng)該是什么樣子,框架沒有高低之分,學(xué) ng 的那些痛苦一定是會有回報的,心思活躍一點就好,不要死守著一個平臺

          前端反內(nèi)卷還是很堅定的,你看 java,內(nèi)卷到不行,動不動就問服務(wù)治理,netflix 標(biāo)準(zhǔn)啥的,DDD,SOA,微服務(wù)張口就來,設(shè)計模式少背一個就被批基礎(chǔ)不牢,然后給個5,6000工資,你看我們前端多好,理解面向?qū)ο蠛图兒瘮?shù)就能拿高工資

          自嘲歸自嘲,就目前的情況來看,前端的好日子應(yīng)該是到頭了,React Vue 都有了自己的邏輯復(fù)用方案,這時候不妨來一個橫評,大家除了了解各個框架異同以外,也能窺探一下整個行業(yè)的發(fā)展方向


          響應(yīng)式

          ng 首先實現(xiàn)邏輯復(fù)用不是沒有原因的,并不是說 ng 的開發(fā)者比其它平臺的厲害多少,這個尤大已經(jīng)有過表述,最大的原因在于,ng 的響應(yīng)式對象,直接采用的微軟出品的成熟庫

          rxjs —— angular

          配合 rxjs 使用的 zone.js 也是事件驅(qū)動響應(yīng)式的典型,這個和 React,Vue 的方案有所不同,在數(shù)據(jù)量大的情況下性能非常強,但是在 “多 watcher 少量數(shù)據(jù)”下性能要很弱,這也使得最佳實踐的難度非常之高 —— 業(yè)務(wù)邏輯用極限函數(shù)式開發(fā),無變量,無狀態(tài),無watcher

          這是 Angular.cn 入門教程英雄指南的一個代碼片段,你能感受到16年初學(xué)習(xí) ng 時我的絕望么?它只是個入門引導(dǎo),但是我認(rèn)得它,它不認(rèn)得我?。∠胂笠幌?,Vue 講模板語法的那一章突然來個這個,你是什么感覺

          而且,因為事件驅(qū)動和 zone 的暴力代理,某些情況下需要 runOutside 和 changeRef,要知道事件驅(qū)動費腦,數(shù)據(jù)驅(qū)動費手,選擇這個方式必然推廣困難,你想想,寫業(yè)務(wù)是加個標(biāo)識位簡單,還是加個管道簡單?

          普通程序員接觸 rxjs 也很有可能是后來 react 平臺推廣的結(jié)果,多個 React 工具文檔出現(xiàn)了 rxjs 導(dǎo)致的?后來出現(xiàn)了很多用于學(xué)習(xí) rxjs 的工具,比如:https://reactive.how/,即便有那么多的視頻講解,真正保證學(xué)會 rxjs 并用好的的,應(yīng)該也只是極少數(shù)人

          這東西和ramda,都屬于成年噩夢,最大的問題是,廢了老大勁學(xué)的東西,實際開發(fā)中卻很少用到,這種落差感也是非常的大,后來我知道是自己用法的問題,尤其是 react hooks 出來之后比較 react 的用法,才更清晰的明白最佳實踐應(yīng)該是怎樣的,不過在缺乏文檔,缺乏引導(dǎo)的情況下,你確定你知道該怎么做?

          Memorized hook —— react

          其實很簡單,就是一個數(shù)組結(jié)構(gòu)中的 getter 和 setter 的控制反轉(zhuǎn) monad:

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

          平心而論,這個結(jié)構(gòu)是真的太直觀了,響應(yīng)式本來是啥,就是 getter 和 setter 啊,吶,你看,getter 和 setter

          當(dāng)然,拆開這兩部分并不只是為了直觀的原因,還有一個很大的原因是,React 平臺死守不變性原則,也就是無賦值,無變量,保證函數(shù)式開發(fā)體驗

          這也是 為何 大對象建議業(yè)務(wù)上使用 useReducer 的原因,也是死守不變性的結(jié)果,當(dāng)然,你牛你可以自定義 hook

          這個函數(shù)式開發(fā)體驗并不極限,比 rxjs 那種調(diào)用鏈管道模型要簡單(React 程序員要有清晰的認(rèn)識啊,函數(shù)式不是用來內(nèi)卷的工具,至少碰到其它管道框架的時候得穩(wěn)重點),當(dāng)然也有死守管道風(fēng)格的框架,cycle,那就更反人類了,這種東西用在金融系統(tǒng),武器系統(tǒng)的開發(fā)可以,用在前端意欲何為?我是真的認(rèn)為這個東西是大炮打蚊子,ng 畢竟還有 baas 服務(wù),有前后端同構(gòu)的考量,cycle 這個真的是存粹的興趣愛好了,發(fā)揚極客精神,另外自定義 hook 也可組成管道,這時 react 的極限函數(shù)式風(fēng)格就來了,大家可以使用 ramda 封裝試試

          不過 rxjs 還有一個好處,在 vue 沒有邏輯復(fù)用的時候,vue-rx 給我開了個邏輯復(fù)用的口子,讓開發(fā)效率提升了非常多,你看,我就說東西都不會白學(xué)的嘛,當(dāng)然,rxjs 的侵入性很強,rx 配合誰都是 rx當(dāng)主角,其它技術(shù)棧當(dāng)配角

          說到 Vue,其實就是無“不變性”要求的 React,這么說有點粗暴哈,但是對于一個之前的 nger 來說,Vue 和 React 的差異真的只是寫法上的差異,原理上并未有太多區(qū)別

          但是思想上確實有個重大的區(qū)別,那就是:

          為啥要追求函數(shù)式?追求更好的可調(diào)式性?前端有那么多業(yè)務(wù)邏輯么?

          問問后端程序員,把邏輯放在前端是個很好的設(shè)計風(fēng)格么?

          當(dāng)然這是在不考慮前后端同構(gòu)語境下的想法,ng 引入一個 module 直接支持ssr,next 只是 react 的輕度再封裝,nuxt 可是要復(fù)雜得多,也和這個思想有一定關(guān)系

          不過這種想法細(xì)想一下,有沒有道理?從業(yè)過程中我發(fā)現(xiàn)很多開發(fā)人員對 Vue 平臺有意見,固然有文人相輕的因素在里面,但是好好想一想吧,那些模式用在 后端 是不是更有意義?

          所以直接上 proxy,setter,getter 合二為一,完成響應(yīng)式:

          Proxy —— vue

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

          vue 如此火爆,不是沒有原因的,面向簡單編程,因此主要的響應(yīng)式,什么概念都可以丟掉,左手 ref,右手 reactive 打天下:

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

          尤其是新版本代碼風(fēng)格,上手成本直線下降,個人覺得?vue 新版本發(fā)布才是真正宣告前端進(jìn)入新時代的標(biāo)志


          組件語法

          Angular

          Angular 的響應(yīng)式需要配合管道使用:


          這里有個問題,如果對象需要進(jìn)一步操作,復(fù)雜度稍稍有點增加:


          沒有計算屬性的概念,有的只是管道復(fù)用:

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

          副作用在 subscribe 處理:

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

          // 最佳實踐認(rèn)為,副作用應(yīng)該得到控制,比如請求是個新的流
          const data = click$.pipe(switchMap(()=>request('....')),map(...))
          // 而 data 又用于視圖

          但是因為是管道,副作用直接全部在視圖處理,這也是極限函數(shù)式處理業(yè)務(wù)的優(yōu)勢,哪里輸入,哪里輸出安排的很明白,當(dāng)然,這難度也是夠你喝一壺的

          獨門亮點,單獨的模板作用域和模板引用變量

          比如你需要一個動態(tài)組件,聲明一個模板引用變量:





          注意,這個 content 是不需要在組件中聲明的,直接在模板標(biāo)記,就可以到處傳值,這個和 Vue 的區(qū)別很大,Vue 的 # 只是 slot 語法糖,傳遞數(shù)據(jù)用的,在這部分內(nèi)容的復(fù)用上要弱很多

          弱點or亮點?指令封裝 spy

          ng沒有直接提供生命周期的邏輯復(fù)用,而是需要你去實現(xiàn)生命周期 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`); }

          如果實現(xiàn)為一個流,那么就可以如下使用:


          這樣就可以把生命周期邏輯全部寫在服務(wù)中了,好處是指令更加靈活,壞處是,很多時候默認(rèn)沒有,程序員就不會去使用,導(dǎo)致生命周期邏輯不進(jìn)行封裝,增加開發(fā)和架構(gòu)難度

          這一點上可以見仁見智了

          React

          Jsx 的優(yōu)點當(dāng)然不是大家以為的 ts 支持,很多 react 程序員喜歡拿著 jsx 和 vue2 的 template 比類型支持,這很容易讓人笑掉大牙的,畢竟 ng 都出來五年多了,但凡用一下也不會有這樣的想法

          但是有一點 JSX 的優(yōu)勢是非常大的,那就是上下文清晰

          典型的函數(shù)作用域,甚至不需要思考,哪個變量屬于哪個對象一目了然,這是單獨封裝模板甚至單獨拆文件的框架很難得到的體驗,比如 vscode 平臺有個 ngSwitch 工具,那就用的很無奈,注意,Jsx 的最大優(yōu)勢是這個——充分利用函數(shù)作用域,以后看到 ts 我都懶得反駁了,完全是八竿子打不著的東西

          另外還有?jsx element 的靈活性,這個很直觀,不用贅述

          但是 Jsx 不是還有劣勢么?可讀性?

          有邏輯復(fù)用之后,組件沒有業(yè)務(wù)邏輯,好的方案一個組件函數(shù)中只做變量填空,Jsx 的劣勢一下子被抹掉,忽然有種 Jsx 春天來了的感覺,具體情況如何還需要看最后社區(qū)的選擇,尤其是 Vue 這種同時支持兩種寫法的方案

          不過,React 的 Hook 卻在一個地方降低了可讀性

          我怎么知道你這個變量是響應(yīng)式的,還是非響應(yīng)式的?畢竟你還有個 useRef 在那里呀,對象也可以直接寫啊~

          {value}

          就這樣的代碼,你怎么知道 value 是不是響應(yīng)式的?相比之下,Angular 管道顯示聲明 | async,響應(yīng)式變量也有命名標(biāo)準(zhǔn),Vue 有 isReactive 等工具(當(dāng)然作用也有限),React 這里就很難控制了

          所以建議不要將 hooks 拆開,作為整體聲明和傳值,帶上響應(yīng)式標(biāo)識$也不是不可以:

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

          當(dāng)然這個數(shù)組取值也是很難受,尤其是遇到依賴數(shù)組的情況,官方不做這種推薦是因為 ——

          函數(shù)式體驗

          對,還是他媽的函數(shù)式體驗,因為在函數(shù)式開發(fā)中,狀態(tài)也是函數(shù),有點拗口哈,就是沒有存儲的“量”,即使是不變量,也是返回確定數(shù)據(jù)的函數(shù) Identity

          唉,學(xué)院派簡直就是西裝暴徒!用的人真的好無奈啊

          副作用在 useEffect 處理:

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

          因為不是管道邏輯,沒有流那樣對副作用限制得那么狠,顯然這個 useEffect 最好是不要用的,因為副作用理應(yīng)得到控制,但是這個標(biāo)準(zhǔn)以這種寫法實現(xiàn)起來實在是太難,官方都只能給你開個過程式處理副作用的口子

          獨門亮點 ——?弱化生命周期

          這個是真的亮點了,想想你需要生命周期么?你其實并不需要生命周期啊

          整個應(yīng)用攏共就視圖變化和狀態(tài)變化兩個,effect 和 layoutEffect 還不夠么?

          當(dāng)然這一點 ng,vue 現(xiàn)在也一樣,不過有意思的是,react 用空依賴數(shù)組做首次更新,用返回值做析構(gòu),api 精煉了好多

          再看看 ng 的 spy,其實原生這種 api 應(yīng)該是會更好的,尤其是 rxjs 配合 生命周期

          理論上來說,生命周期其實都是不需要的,響應(yīng)式就讓他自己觸發(fā)自己變化好了,為啥要解開它,watch 它?你看 ng 的 rxjs ,你只用寫一個個管道就夠了,函數(shù)式響應(yīng)式處理業(yè)務(wù),沒必要去關(guān)心具體的狀態(tài)

          這個真的想給 React 一個大大的贊,等于是強制前端開發(fā)進(jìn)化+內(nèi)卷,接受函數(shù)式開發(fā)更進(jìn)一步,咦,為啥強制內(nèi)卷我還挺開心?

          弱點 or 亮點?——?依賴數(shù)組

          他媽的依賴數(shù)組!

          所有用 React 的人不信你沒罵過,沒辦法,死守不變性嘛,沒依賴就不純了

          他媽的不變性!

          這個玩意兒是真的惡心,寫不寫是一方面,你別再代碼里給我報一長串 warning 啊,好難受啊,太不近人情了

          所以看你狠還是我狠,大不了老子不寫 effect,結(jié)果發(fā)現(xiàn) useMemo 也要寫,唉~

          React 可以說是強迫癥的最愛吧,其實完完全全的函數(shù)式用于生產(chǎn)環(huán)境真成問題,否則haskell早就一統(tǒng)后端市場了

          一般來說函數(shù)式在處理運行時業(yè)務(wù)邏輯更有效,但是數(shù)據(jù)結(jié)構(gòu),初始化等問題,還是面向?qū)ο蟾鼮樯瞄L一些,這也是 Angular 為啥組件服務(wù)用 class 組織,業(yè)務(wù)邏輯用 rxjs 的原因,各取所長嘛

          Vue

          面向簡單編程

          模板幫你取value?

          {{test}}


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

          這是親媽風(fēng)格的 api 封裝啊,這已經(jīng)和原理相悖了,proxy 對象封裝,只有 test.value 才能操作數(shù)據(jù),為啥寫的時候要 test.value = xxx, 用的時候就 test 了呢?

          只能理解成親媽式封裝,門檻能降一點是一點

          這種思想其實在 Vue 的設(shè)計中隨處可見,用戶要啥,就給啥,一切從用戶體驗出發(fā),還是那句話,前端能有什么業(yè)務(wù)邏輯,難道沒用設(shè)計模式,支持不變性,就能讓你操作數(shù)據(jù)庫了么?

          怎么簡單怎么來,composition?狀態(tài)復(fù)用只有兩個 api,不變性 api ref,和 深層可變 api reactive

          哈哈,反著來了,因為有g(shù)etter,setter,所以 ref 等同于 React 的 useState,而 reactive 等同于 React 的 useReducer,仔細(xì)想想是否如此,因為不遵守不變性了(寫法上),setup 只運行一次,所以類似 React 的 ref 就沒了

          只運行一次,所以很多問題得到了簡化,按官方的說法就是:

          一般來說更符合慣用的 JavaScript 代碼的直覺;
          不需要顧慮調(diào)用順序,也可以用在條件語句中;
          不會在每次渲染時重復(fù)執(zhí)行,以降低垃圾回收的壓力;
          不存在內(nèi)聯(lián)處理函數(shù)導(dǎo)致子組件永遠(yuǎn)更新的問題,也不需要?useCallback;
          不存在忘記記錄依賴的問題,也不需要“useEffect”和“useMemo”并傳入依賴數(shù)組以捕獲過時的變量。Vue 的自動依賴跟蹤可以確保偵聽器和計算值總是準(zhǔn)確無誤。

          直覺這個東西說的沒錯,函數(shù)式就是反直覺的,函數(shù)式基于范疇論是拿給你計算的,不是那給你擼的,但是這句話總感覺差點什么,這么說就對了:

          更符合過程式 JavaScript 的直覺

          其它問題也都是函數(shù)式風(fēng)格的問題,但是函數(shù)式的優(yōu)點也是有很多的,最后看你適合什么方案,比如 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);
          };
          }
          };

          當(dāng)然,Vue 的 Jsx 用法和 React 有很大差別,比如屬性綁定,render 有多個屬性,詳情間官方文檔,其次是參數(shù)類型提示問題,這個還需要時間來解決,但是這個的工作量應(yīng)該是非常大的

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

          獨家優(yōu)勢 ——?動畫

          原生集成了一個比較簡單的動畫方案,包含狀態(tài)過度以及顯示動畫,很多人覺得這有什么大不了的,ng 也有啊,很抱歉,我在15年底第一次看文檔的時候,ng 的動畫實現(xiàn)方案,把我的頭弄炸了

          React 也需要第三方庫來做狀態(tài)動畫,當(dāng)然,也有人說,有邏輯服用,直接寫個 use 不也能實現(xiàn)

          有這些想法的人,是個合格的程序員,但是不是一個合格的產(chǎn)品經(jīng)理,可能切中了技術(shù)要領(lǐng),但是沒有切中市場要領(lǐng)

          對于很多初學(xué)者來說,我不想知道你有什么新技術(shù),也不想知道你的封裝方式有什么優(yōu)點,我就想看你簡不簡單!

          Vue 這種加 class 名的方案,就是很好的,很簡單的,初學(xué)者也能寫出良好交互體驗的網(wǎng)站,前端的重點真的在業(yè)務(wù)邏輯上么?想多了,前端的重點就是在炫目的交互效果和UI效果上的,其它的都只是附加的東西(非前后端同構(gòu),非跨平臺的純前端項目),很多人都低估了 Vue 在這方面的競爭力

          大家可以自行比較一下ng和vue的動畫方案:

          Angular - Angular 動畫簡介:https://angular.cn/guide/animations

          進(jìn)入/離開 & 列表過渡 — Vue.js:https://cn.vuejs.org/v2/guide/transitions.html

          也可以對比一下 React 第三方庫 ant motion:

          Ant Motion - Ant Design 的動效規(guī)范與組件:https://motion.ant.design/index-cn

          大廠有包袱,他們做的東西不僅要滿足實際使用者,還要滿足同行和學(xué)界的挑剔目光,因此很多好用但反模式的東西不敢去做,我們的話無所謂,干的就是搬磚的活,端著干啥

          絕大部分的人工作并不是造火箭,普通人改變不了世界,快速完成從零到一,也是一種實事求是的態(tài)度


          應(yīng)用架構(gòu)

          這個不用說了,?Angular?第二,沒人敢說第一

          確實有復(fù)刻 Spring 相關(guān)技術(shù)棧的影子,Nestjs也是如此

          但是這個架構(gòu)確實好啊,確實牛逼啊,大型的成熟項目后端,哪個不是 SOA 打天下的?

          15年 Angular 主推 SOA 的時候,爭議是真的大,那個時候 React 和 Vue 連成熟的邏輯復(fù)用都沒有,這邊就 IOC,依賴注入了,社區(qū)之間的談話談話都是雞同鴨講,語言都沒統(tǒng)一, 你說函數(shù)式響應(yīng)式,他說純函數(shù),你說面向業(yè)務(wù)DDD,他說你說的都是后端概念,你說類型完備,他說Vue怎么就不能用Ts了?無意義的爭吵太多

          了解那段時期氛圍的人都知道,確實很浮躁

          現(xiàn)在好了,相關(guān)說明和解釋出現(xiàn)在了 React 和 Vue 的官方文檔,語言終于能夠統(tǒng)一了

          provide/inject , useContext/Provider,都已經(jīng)成為主力 API,人們開始了對 Redux/Vuex 有沒有意義的爭論,類似當(dāng)年ng社區(qū)對ngRx的爭論,摘要一下哈:

          1. redux 模式是純函數(shù)?rx 操作函數(shù)就不是了么(ng)?useState 就不是了么(react)?vue 平臺不要純函數(shù)(vue)?
          2. 要保證單一數(shù)據(jù)原則?providedIn:'root' 就不是單一數(shù)據(jù)了(ng)?app provider 就不是單一數(shù)據(jù)了(react,vue)?
          3. 方便調(diào)試,生命周期都沒有你怎么方便調(diào)試?找出了dispatch還要去找生命周期,不閑得慌么?
          4. 跨組件數(shù)據(jù)傳遞?你在抹黑這次更新
          5. 封裝方便團(tuán)隊協(xié)作?邏輯都封裝不到一起,協(xié)哪門子的作,用 cdk/ahooks,能和 阿里/谷歌 協(xié)作
          6. 狀態(tài)本地化?useLocalStorage 不香?
          7. 服務(wù)端狀態(tài)保持?rxjs 的 retry,timer ,ahooks 的 manual, pollingInterval 不是吃干飯的

          歷史的問題就不用再糾結(jié)了,可以先看看 Angular 的架構(gòu)強大在哪里:

          類型完備

          只支持?Typescript 并保證?99%?的可訪問 api 都有類型推斷,這點React就望塵莫及了,只給接口和泛型,不給類型推斷,數(shù)據(jù)和類型聲明分離,Typescript 在不將類型看作函數(shù)進(jìn)行二次封裝的情況下,使用體驗非常差

          而且我相信,React 本身就討厭 Typescript,原因很簡單,對,沒錯,就是函數(shù)式體驗~

          又他媽的函數(shù)式體驗

          函數(shù)式開發(fā)中類型的作用和功能與面向?qū)ο蟛煌?,類型更多是起到校驗作用?strong style="max-width: 100%;color: black;box-sizing: border-box !important;overflow-wrap: break-word !important;">類似于一個運行時的測試機制,這點可以去看 Car Baaz 的訪談:

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

          壓根就沒有集成數(shù)據(jù)結(jié)構(gòu)的概念,要是按照用 ng 的類型使用方式去用 React,怎么用怎么別扭,所以需要你二次封裝,相當(dāng)于編寫了一個?運行時測試?……

          但就我看過的代碼,大多數(shù) Ts 版本 React 開發(fā)者,沒有這個意識,而且,React 這種用法,結(jié)合Flow才是最合適的,運行時測試和編譯前校驗,區(qū)別非常大,也是因為社區(qū)追捧 Typescript 吧,被裹挾了

          自動依賴注入

          Vue 也有依賴注入了,而且用法非常簡單,但是并沒有實現(xiàn)完全的 IOC,需要手動 Provide,Inject,還需要加 Token(Symbol),和單獨的類型聲明

          Ts 語境下,這部分封裝成 Class 可以優(yōu)化

          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 的作用主要是為了將數(shù)據(jù)的聲明和類型的聲明集中,提供初始化入口,方便計入 InjectionKey 的泛型,你可以看到,還是有 new,如果要好一點的類型體驗的話

          這個 new 就很煩躁了,面向?qū)ο?,new 是萬惡之源,嚴(yán)格來說這并非強類型語境下的依賴注入,IOC并未完全實現(xiàn)(初始化邏輯未接管

          但是 ng 就要簡單多了,一般情況下:

          構(gòu)造器參數(shù)聲明,即完成注入,當(dāng)然啦,這也有 Vue 的無奈,原因很簡單,這樣的 IOC 方案需要裝飾器加類型反射(reflect-metadata typeName:)才能實現(xiàn),而 Vue 還需要將就 Js 使用環(huán)境:

          但是這樣的話,架構(gòu)擴(kuò)展性和 ng 相比就有很大差距了,不過這不妨礙 Vue,原因很簡單——你能在前端做出微服務(wù)集群來,算我輸,前端沒有強業(yè)務(wù)邏輯,用不到牛刀殺雞——當(dāng)然這個問題見仁見智了

          可配置Module

          一般情況下被視為花活,但在 google adword 這樣的應(yīng)用中被視為剛需,那就是可配置 Module

          將一個服務(wù)包含依賴以及相關(guān)視圖打包,用于優(yōu)化編譯器

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

          import { DragDropModule } from '@angular/cdk/drag-drop'

          @NgModule ({....
          imports: [...,
          DragDropModule ,
          …]
          })

          然后這里面有的組件,指令,服務(wù)啥的,都隨便用,大門敞開,不需要像 Vue 一樣,import Component 再 聲明 {components: { someComponents},filters, ... }

          其實就是耗費開發(fā)的時間,節(jié)省使用的時間

          同時,指令真的好用,React 技術(shù)棧真的好可惜,沒有這個功能呢,高階組件再怎么說也是封裝,封裝和附加的區(qū)別還是很大的,就和裝飾器跟繼承的區(qū)別一樣

          其它的還包括他的多語言架構(gòu),簡單的ssr同構(gòu),baas同構(gòu)(angular/firebase),以及,以后系列文章會講到的,微前端 —— 利用module封裝其它技術(shù)棧代碼,生成shadowDom,當(dāng)然,這個特性還包含 Angular 的樣式封裝特性,從編譯源頭解決 shadowDom 的同構(gòu)問題,還有開發(fā)時cli輔助,路線圖等等非常工程化的特性

          數(shù)據(jù)結(jié)構(gòu)用極限面向?qū)ο蠼鉀Q,業(yè)務(wù)邏輯用極限函數(shù)式解決,什么都走極端就對了,下限和上限都非常高,弱點就是容易曲高和寡,應(yīng)者了了,前端程序員應(yīng)該去學(xué)習(xí),但是生產(chǎn)環(huán)境使用的話謹(jǐn)慎吧,畢竟是前端,明白自己定位最重要,那些概念學(xué)了之后,用在nestjs上搞微服務(wù)多好?

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

          前端的數(shù)據(jù)量和業(yè)務(wù)量,除非你真能搞個 adword 一樣量級的創(chuàng)收項目(穩(wěn)定性要求,多樣化需求,全球化,交易服務(wù)等會讓業(yè)務(wù)復(fù)雜度直線上升),不然真的**有牛刀殺雞的嫌疑,**喜歡端著不是件好事,技術(shù)的選擇應(yīng)該契合業(yè)務(wù),而非業(yè)務(wù)契合技術(shù),大部分情況下這個架構(gòu)更適合后端的業(yè)務(wù)量和數(shù)據(jù)量,所以 nestjs 的熱度逐年上漲,甚至有成為Java程序員逃避死板代碼的避風(fēng)港的趨勢,也算是意料之中

          Angular 可以作為一個相關(guān)概念的學(xué)習(xí)基地,方便你很快地切換到后端開發(fā),同時也可以引導(dǎo)你了解項目架構(gòu)的最佳方案應(yīng)該如何,方便你自己搭建其他平臺項目的架構(gòu),實際使用的話,能保證團(tuán)隊成員意識形態(tài)一致,有較高的追求,可以一試,但也僅僅是一試,有點脫離基本面了,效率,人員等都是沒有保證的,很多國內(nèi)公司切換過 angular,又切換回來了,不得不向現(xiàn)實低頭

          不過不用笑 Angular,React 一樣有點脫離基本面,只是說普通人很難寫出最佳實踐而已,簡單易用還是有保證的,這點比 Angular 強

          但是,過程式一把梭,面向?qū)ο笾灰竽阆肭宄?strong style="max-width: 100%;color: black;box-sizing: border-box !important;overflow-wrap: break-word !important;">函數(shù)式要求算清楚??!我們這些大學(xué)離散數(shù)學(xué)只有60分的學(xué)渣,怎么搞定態(tài)射演算啊,只記得住一個結(jié)合律,其他啥都忘了,當(dāng)然后面有補課,過程也是痛苦萬分的,現(xiàn)在又在遺忘的邊緣試探

          而且函數(shù)式無所謂架構(gòu),自底向上,一步步累進(jìn)封裝,保證靈活性和測試完備,理想非常豐滿,現(xiàn)實也是骨感得很,要知道函數(shù)式基礎(chǔ)不牢固,一個點壞掉,這個系統(tǒng)都危險,要是架構(gòu)部分的需求變化,面對那一坨陀錯綜復(fù)雜的函數(shù),很容易讓人失去信心的

          簡單來說:
          函數(shù)式自底向上:我搞了一堆功能和函數(shù),都有完備測試,看看能做點啥
          面向?qū)ο笞皂斚蛳拢何乙鲆粋€系統(tǒng),它由以下抽象類組成……

          所以到頭來還是用和Vue一個封裝層級的框架完成開發(fā),類似 umi,才能滿足生產(chǎn)環(huán)境的需求,變換為自頂向下的開發(fā)模式,這實際上是反函數(shù)式

          這時候不變性,純函數(shù)成了累贅,有沒有人計算過這個純函數(shù)和不變性到底節(jié)省了多少測試成本,優(yōu)化了多少性能?再問尖銳一點,有寫紅藍(lán)測試的習(xí)慣么?測試有為函數(shù)式開發(fā)做配套支持么?技術(shù)追求和實際需求是有斷代的,更不要說之前無邏輯復(fù)用還能用函數(shù)式用的那么嗨,樣板代碼一大堆,接手的人望洋興嘆,有技術(shù)主導(dǎo)需求的嫌疑,并非一個好的企業(yè)架構(gòu)

          所以 React 存在和 Angular 一樣的問題

          另外,邏輯復(fù)用應(yīng)該算個大更新,應(yīng)該用很大的魄力回爐重造,Angular 有這個魄力劃清界限,但是 React 沒有,還存在很多歷史問題沒有解決

          要知道很多 Angular 工具和 React 工具都是在解決框架本身的問題,很多 React 工具本身就是用來解決邏輯復(fù)用,或是強制自己實現(xiàn)邏輯復(fù)用開發(fā)出來的,比如大堆的第三方庫新版本已經(jīng)沒有意義,redux,redux-thunk,各種工具庫,在新版本語境下已經(jīng)不知所謂了,還會成為歷史遺留問題繼續(xù)產(chǎn)生作用,既限制開發(fā)者,也限制框架開發(fā)

          當(dāng)然,函數(shù)式天然和架構(gòu)不沾邊也是問題之一,你見過什么大型工程項目是存粹用函數(shù)式搭建的?有數(shù)學(xué)完備支持的,理想的無bug系統(tǒng),終究只是理想,現(xiàn)實世界是充滿復(fù)雜性的,Angular尚且可以回退到promise,非rx使用方式,React這個函數(shù)式一把梭,真的有些強人所難了,happing hacking,但是普通開發(fā)者不是 hacker,沒必要陪著你一起追求美好未來吧?

          噴了一通,如果讓我一個人做一個中小型項目,一個人做一個大型項目(基本不可能哈),我還是會選擇 React 和 Angular,怎么了,我就是追求美好未來的三有青年呀~

          那么接下來就是歷史和市場的選擇,前端代言人了 ——

          一把梭,面向簡單,文檔支持完美,循序漸進(jìn),前端內(nèi)卷締造者,Vue

          Angular,React 還會糾結(jié)邏輯復(fù)用版本的接受度問題,Vue的方案,真心沒啥負(fù)擔(dān)

          你想想,上一版本你還要學(xué)單向數(shù)據(jù)流,還要學(xué)響應(yīng)式原理,還要用 Vuex , Vue.set 啥的,更早還有 event bus,實例響應(yīng)式數(shù)據(jù)等等,api面積真的大

          現(xiàn)在:ref,reactive,provide,inject 最多加上 mounted 和 watch,6個api打天下,啥單向數(shù)據(jù)流,直接改了不就完了,你跟新手說單向數(shù)據(jù)流,可能會被當(dāng)成 xx,實際上也是,setter在父組件或者服務(wù)中,壓根沒有違背原則,等第三方邏輯庫流行,就是完完全全的傻瓜操作了,什么函數(shù)式,面向?qū)ο?,都是后端的概念?/p>

          你想想,比你知道的更少的新手,寫東西還比你快,難受不難受?糾結(jié)不糾結(jié)?

          內(nèi)卷不內(nèi)卷?

          在 Vue 支持 邏輯復(fù)用之后,前端的好日子終究還是到頭了,大量新人會涌入,然后搶占市場,壓縮開發(fā)者薪資

          而前端如果不走出 邏輯少,數(shù)據(jù)少 的泥潭,是不會有未來的

          目前幾個方向可能尋求突破

          1. 前后端同構(gòu),BFF,作為視圖服務(wù),成為微服務(wù)架構(gòu)中的一環(huán),不過這個概念很難灌輸給 cto

          2. 期待新的端到端通訊,成為邊緣云中樞,這個很有可能實現(xiàn),不過短期很難,而且,屆時 wasm 可能會搶占傳統(tǒng)前端市場

          3. 利用前端技術(shù)棧在 faas 中的優(yōu)勢,自己創(chuàng)業(yè),或者加入創(chuàng)業(yè)公司推廣這個吧,成為云服務(wù)廠商的幫兇

          4. 死守技術(shù)棧干嘛,轉(zhuǎn)棧做 devOps 啊,這個才是熱點,議價能力強

          借這個時機,抖音再投幾個廣告教授 Vue3 的課程,這個過程不知道要被加速多少倍,被資本家剝削真的太難了

          所以你要是真的熱愛技術(shù),跳出資本循環(huán),敢于承擔(dān)風(fēng)險,做自己吧~


          》聲明:文章著作權(quán)歸作者所有,如有侵權(quán),請聯(lián)系小編刪除。


          瀏覽 59
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  欧美极品三级 | 可以看av的网站 麻豆精产成人精品 | 91在线成人免费 | 全网三级视频在线观看 | 九九九九精美视频 |