React的世界觀及與Vue之比較

来源:https://www.cnblogs.com/leegent/archive/2019/05/04/10794047.html
-Advertisement-
Play Games

寫在前面:本文談論的是主觀的個人感受,不追求立場的“客觀、公正”,因此我下麵所說的很可能是錯的,歡迎交流指正。 我學習前端時,跟大部分beginner一樣,學的第一個框架是Vue,入職後也一直寫Vue。寫了一年多,想換換口味了,於是決定最近的新項目改用React試試。用了大半個月後,我已經完全被這個 ...


寫在前面:本文談論的是主觀的個人感受,不追求立場的“客觀、公正”,因此我下麵所說的很可能是錯的,歡迎交流指正。

 

我學習前端時,跟大部分beginner一樣,學的第一個框架是Vue,入職後也一直寫Vue。寫了一年多,想換換口味了,於是決定最近的新項目改用React試試。用了大半個月後,我已經完全被這個迷人的框架洗腦了,特別是它背後的設計理念非常優秀,讓人耳目一新。

React的設計思想有何過人之處呢?拿它和Vue做個對比就清楚了。

 

Vue: 填模板游戲繼續

Vue之所以成為國內前端初學者(包括我)的首選,一方面是因為中文文檔寫得好,更重要的原因則是它符合人們對於網頁開發的傳統認知。

Vue雖然內部做了很多工作(如Virtual DOM),但暴露給開發者的體驗更像是升級版的模板引擎,類似於Jade、Handlerbars。模板引擎的作用就是在靜態的模板上動態替換JS變數,以渲染出最終的頁面。基於Vue的項目目錄下,每個組件目錄下都有html、css、js文件三足鼎立(或者集中到一個.vue文件里,但仍然是分開的三部分),html是靜態模板,js管理動態的變數,整體結構非常的直觀。

此外,Vue在模板引擎的基礎上增加了“雙向綁定”功能,即用戶輸入造成的DOM變動可以反過來同步給關聯的JS變數;並且自定義了一些v指令,大大簡化了事件綁定、條件渲染、動態列表等常用功能的實現複雜度。這些因素使得Vue寫起來既像模板引擎一樣易於理解,又比模板引擎方便很多。我個人寫Vue的時候,一般就是先寫html模板,在此過程中把需要動態填充的數據定義出來,隨手寫個mock數據先占位;等模板寫完了,再來寫獲取這些數據的js邏輯。

也就是說,Vue的開發思路差不多就是“寫模板-填模板”的套路,與jQuery時代一脈相承。

這種套路上手容易,但是沒什麼發揮空間,寫多了真的容易膩煩。而且在JS邏輯越來越複雜的情況下,狀態管理非常麻煩,心智負擔沉重。

騷年,要不要換一種玩法試試?

 

React: 一種新的玩法

剛接觸React的時候,是不是被嵌在js里的html(JSX)、滿天飛的箭頭函數、高階函數等弄得有點不適應?反正我是腦闊疼了好一陣。

但是進一步瞭解React後就會明白,這不是臉書的攻城獅們在耍帥或者故弄玄虛,而是這些語法真的能夠更好地表達React的思想,幫助代碼作者和讀者thinking in React。

React的核心思想是什麼呢?不妨來看看Vue和React的組件對比。這是一個非常簡單的組件——展示從父組件收到的message字元串:

Vue的實現:

// demo.vue
<template>
    <div>{{message}}</div>
</template>

<script>
export default = {
    props: ['message']
}
</script>

React的實現:

// demo.jsx

export default props => (
    <div>{props.message}</div>
);

 

這兩段代碼一眼就能一個非常明顯的不同點——Vue組件實現為一個有模板(template)、有數據(props)的對象, React組件則實現為一個輸入數據(props)、輸出html片段(JSX)的函數

函數有什麼特別呢?從數學上講,函數本質上就是表示一種映射關係。React受函數式編程思想的影響,將html視為數據映射的結果。一個數據映射出一個html片段,所有的html片段拼起來,就形成了完整的頁面DOM樹。當然,React組件還可以是class形式,但只是為了更好地操作數據,最終render函數會完成映射這一步。這是一種截然不同於模板填充的思維方式,姑且稱之為“映射思維”。相應的,將變數綁定到模板上的思維方式就稱之為“模板思維”。理解這兩種思維的對立非常重要,因為這是React與Vue等其他框架的核心差異所在。

我畫瞭如下兩張圖,嘗試闡明模板思維與映射思維的不同:

 

這兩種思維的根本分歧在於:視圖層與數據層何者第一,何者第二?或者說,是先有html再有js,還是先有js再有html?

模板思維認為是先有html,再有js。正如上面圖的左半部分所示,模板本身已經是一個接近完整的網頁了,只不過其中幾個變數沒法確定,需要一點邏輯來動態填充,所以找了js這麼個小弟來打打下手,把這幾個變數給補上去。因此,在模板思維的世界觀里,html居於主導地位,js服從於html的需要。

映射思維卻相反,認為js里的數據才是第一性的,html只不過是數據層向視圖層的單向映射或者說投影,如上圖右半部分所示,一個個數據的投影片段拼起來,組成了完整的html。在這個世界觀里,數據是本體,視圖是現象,他們之間的關係就像一棵樹與它的影子一樣,要想改變影子,就必須改變樹,而不能影子變了樹沒變。明白了這一點,React那些乍看之下有些奇怪的設定(如阻止input標簽直接響應的用戶輸入),以及React社區對單向數據流的偏好(如Redux),就不難理解了。

 

孰優孰劣?

我可不想像很多文章那樣偷懶地來一句“各有優劣”,再不痛不癢地分別列舉幾個優缺點完事。我,旗幟鮮明地認為,映射思維才是前端未來正確的發展方向

在上古時代的網頁里,js只是嵌在html里的一行或者一小段腳本,乾著彈個提示、飛個廣告之類的雜活,遠遠稱不上一個完整的程式,說它是html的小弟或補充,一點問題也沒有。但如今,頁面越來越複雜,非同步載入、動態渲染的開發模式越來越流行,在這種模式下,整個頁面都是由js繪製出來的,正是因為js對頁面有了完全的掌控權,才使得網頁真正進化為“WebApp”,成為一個真正的程式,而不再是一個簡單的、無邏輯的類XML標記語言文件,進而使得數據-視圖層的分離及其映射關係的建立成為可能。

在WebApp里,有一個原則顯然應該被始終遵守——一致性,即用戶看到的DOM元素狀態應該與對應的js變數值保持一致。Vue的解決方案是雙向綁定,React則實現了單向數據流,這都是從它們各自的世界觀出發做出的自然而然的選擇。但在我看來,視圖=表象,不應該讓表象承載實質,否則會導致形實關係的混亂——自然法則允許通過修剪樹來改變它的影子,難道也要允許通過改變影子反過來改變樹嗎?表象就應該是實質的忠實呈現,以及用戶觸達實質的媒介(事件綁定),不應越俎代庖。

 

在模板思維看來,html模板和js數據都是實質,二者是併列的關係;在映射思維的世界觀里,js數據是唯一的實質。

如無必要,勿增實體”,我選擇簡單的那個方案。

事實也是如此,學會了thinking in React,可以在編寫複雜頁面的時候,仍然保持邏輯清晰和極度舒適。

真香!!!


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • OceanBase是阿裡巴巴和螞蟻金服完全自主研發的通用的分散式關係型資料庫,從1.0版本開始OceanBase就支持分區表,功能逐步跟ORACLE分區表相容,並且支持不同分區分佈在集群的不同節點(機器)上。本文是對OceanBase分區表的能力做一個詳細介紹。 ...
  • MySQL的SQL語言是用於訪問資料庫的最常用標準化語言。由於其體積小、速度快、總體擁有成本低,尤其是開放源碼這一特點,一般中小型網站的開發都選擇MySQL作為網站資料庫。本文主要是入門知識講解,僅供學習分享使用。 ...
  • 原文鏈接 FORMAT() 之後 會滿三位加逗號, 在此基礎上進行數字運算的時候會出現預料之外的結果, 建議使用 : 任意一種 進行代替。 1 ...
  • 一.activity.xml 我這裡主要爬取的愛奇藝首頁的圖片進行輪播,應用了兩個github上的開源庫,一個banner的庫,一個載入網路圖片的庫,用開源庫能夠極大地節省我們編寫代碼的時間。 二.添加相關的庫以及網路許可權 三.activity.java 四.網路圖片載入的新類 代碼一共就這些,全部 ...
  • 最近需要把一個web端的項目做一個app,所以很多後臺代碼就順便複製了,如圖所示,在java代碼有一個簡單的時間戳格式化輸出日期的方法 Java代碼: 輸出結果: 得到的時間是2019-04-29 00:00:00 我們用時間戳轉換工具也得到了同樣的結果(時間戳轉換工具需要去除結尾的三個0) 但是在 ...
  • 一、事件背景: 我最近開源了一個個人耗時半年打造的富文本及一套適用於web後臺的ui框架,在gitee上受到網友們的關註,部分網友對我採用jquery的技術棧提出了質疑。總結起來:無非是jquery已經落後,不久將死。甚至有少數網友很激進:非vue技術棧,你不應該加入我這個群,不管你做得多好。對應這 ...
  • 組件(Component)是Vue.js最核心的功能,也是整個框架設計最精彩的地方,當然也是最難掌握的。本章將帶領你由淺入深地學習組件的全部內容,並通過幾個實戰項目熟練使用Vue組件。 ...
  • AC自動機 js class ACNode { constructor(data){ this.data = data this.children = new Map() this.isEndingChar = false this.length = 0 this.fail = null } } c ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...