一個空間做2個網(wǎng)站廣州現(xiàn)在有什么病毒感染
面試題:React 和 Vue 是如何描述 UI 界面的?有一些什么樣的區(qū)別?
標準且淺顯的回答:
React 中使用的是 JSX,Vue 中使用的是模板來描述界面
前端領域經(jīng)過長期的發(fā)展,目前有兩種主流的描述 UI 的方案:
- JSX
- 模板
JSX 歷史來源
JSX 最早起源于 React 團隊。在 React 中所提供的一種類似于 XML 的 ES 語法糖:
const element = <h1>Hello</h1>
經(jīng)過 Babel 編譯之后,就會變成:
// React v17 之前
var element = React.createElement("h1", null, "Hello");// React v17 之后
var jsxRuntime = require("react/jsx-runtime");
var element = jsxRuntime.jsx("h1", {children: "Hello"});
無論是 17 之前還是 17 之后,執(zhí)行了代碼后會得到一個對象:
{"type": "h1","key": null,"ref": null,"props": {"children": "Hello"},"_owner": null,"_store": {}
}
這個其實就是大名鼎鼎的虛擬 DOM。
React 團隊認為,UI 本質(zhì)上和邏輯是有耦合部分的,例如:
- 在 UI 上面綁定事件
- 數(shù)據(jù)變化后通過 JS 去改變 UI 的樣式或者結構
作為一個前端工程師,JS 是用得最多,所以 React 團隊思考屏蔽 HTML,整個都用 JS 來描述 UI。因為這樣做的話,可以讓 UI 和邏輯配合得更加緊密,所以最終設計出來了類 XML 形式的 JS 語法糖
由于 JSX 是 JS 的語法糖(本質(zhì)上就是 JS),因此可以非常靈活的和 JS 語法組合使用,例如:
- 在 if 或者 for 當中使用 jsx
- 將 jsx 賦值給變量
- 將 jsx 當作參數(shù)來傳遞
- 在一個函數(shù)中返回一段 jsx
示例代碼
function App({isLoading}){if(isLoading){return <h1>loading...</h1>}return <h1>Hello World</h1>;
}
這種靈活性就使得 jsx 可以輕松的描述復雜的 UI,如果和邏輯配合,還可以描述出復雜 UI 的變化。
使得 React 社區(qū)的早期用戶可以快速實現(xiàn)各種復雜的基礎庫,豐富社區(qū)生態(tài)。又由于生態(tài)的豐富,慢慢吸引了更多的人來參與社區(qū)的建設,從而源源不斷的形成了一個正反饋。
模板的歷史來源
模板的歷史就要從后端說起。
在早期前后端未分離的時候,最流行的方案就是使用模板引擎。模板引擎可以看作是在正常的 HTML 上面進行挖坑(不同的模板引擎語法不一樣),挖了坑之后。服務器端會將數(shù)據(jù)填充到挖了坑的模板里面,生成對應的 html 頁面返回給客戶端。

所以在那個時期前端人員的工作,主要是 html、css 和一些簡單的 js 特效(輪播圖、百葉窗…)。寫好的 html 是不能直接用的,需要和后端確定用的是哪一個模板引擎,接下來將自己寫好的 html 按照對應模板引擎的語法進行挖坑

不同的后端技術對應的有不同的模板引擎,甚至同一種后端技術,也會對應很多種模板引擎,例如:
- Java(JSP、Thymeleaf、Velocity、Freemarker)
- PHP(Smarty、Twig、HAML、Liquid、Mustache、Plates)
- Python(pyTenjin、Tornado.template、PyJade、Mako、Jinja2)
- node.js(Jade、Ejs、art-template、handlebars、mustache、swig、doT)
模板引擎代碼片段
- twig 模板引擎
基本語法
{% for user in users %}* {{ user.name }}
{% else %}No users have been found.
{% endfor %}指定布局文件
{% extends "layout.html" %}
定義展示塊
{% block content %}Content of the page...
{% endblock %}
- blade 模板引擎
<html><head><title>應用程序名稱 - @yield('title')</title></head><body>@section('sidebar')這是 master 的側邊欄。@show<div class="container">@yield('content')</div></body>
</html>
- EJS 模板引擎
<h1><%=title %>
</h1>
<ul><% for (var i=0; i<supplies.length; i++) { %><li><a href='supplies/<%=supplies[i] %>'><%= supplies[i] %></a></li><% } %>
</ul>
這些模板引擎對應的模板語法就和 Vue 里面的模板非常的相似。
現(xiàn)在隨著前后端分離開發(fā)的流行,已經(jīng)沒有再用模板引擎的模式了,后端開發(fā)人員只需要書寫數(shù)據(jù)接口即可。但是如果讓一個后端人員來開前端的代碼,那么 Vue 的模板語法很明顯對于后端開發(fā)人員來講要更加親切一些。
最后我們做一個總結,雖然現(xiàn)在前端存在兩種方式:JSX 和模板的形式都可以描述 UI,但是出發(fā)點是不同
-
模板語法的出發(fā)點是,既然前端框架使用 HTML 來描述 UI,那么我們就擴展 HTML。讓 HTML 種能夠描述一定程度的邏輯,也就是“從 UI 出發(fā),擴展 UI,在 UI 中能夠描述邏輯”。
-
JSX 的出發(fā)點,既然前端使用 JS 來描述邏輯,那么就擴展 JS,讓 JS 也能描述 UI,也就是“從邏輯出發(fā),擴展邏輯,描述 UI”。
這兩者雖然都可以描述 UI,但是思路或者說方向是完全不同的,從而造成了整體框架架構上面也是不一樣的。
真題解答
題目:React 和 Vue 是如何描述 UI 界面的?有一些什么樣的區(qū)別?
參考答案
在 React 中,使用 JSX 來描述 UI。因為 React 團隊認為UI 本質(zhì)上與邏輯存在耦合的部分,作為前端工程師,JS 是用的最多的,如果同樣使用 JS 來描述 UI,就可以讓 UI 和邏輯配合的更密切。
使用 JS 來描述頁面,可以更加靈活,主要體現(xiàn)在:
- 在 if 語句和 for 循環(huán)中使用 JSX
- 將 JSX 賦值給變量
- 可以把 JSX 當作參數(shù)傳入
- 在函數(shù)中返回 JSX
而模板語言的歷史則需要從后端說起。早期在前后端未分離時代,后端有各種各樣的模板引擎,其本質(zhì)是擴展了 HTML,在 HTML 中加入邏輯相關的語法,之后在動態(tài)的填充數(shù)據(jù)進去。
如果單看 Vue 中的模板語法,實際上和后端語言中的各種模板引擎是非常相似的。總結起來就是:
模板語法的出發(fā)點是,既然前端框架使用 HTML 來描述 UI,那么就擴展 HTML 語法,使它能夠描述邏輯,也就是“從 UI 出發(fā),擴展 UI,在 UI 中能夠描述邏輯”。
而 JSX 的出發(fā)點是,既然前端使用 JS 來描述邏輯,那么就擴展 JS 語法,讓它能夠描述 UI,也就是“從邏輯出發(fā),擴展邏輯,描述 UI”。
雖然這兩者都達到了同樣的目的,但是對框架的實現(xiàn)產(chǎn)生了不同的影響。