2023-03-13 10:40:08 +08:00

195 lines
6.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# React 和 Vue 描述页面的区别
> 面试题React 和 Vue 是如何描述 UI 界面的?有一些什么样的区别?
**标准且浅显的回答:**
>React 中使用的是 JSXVue 中使用的是模板来描述界面
前端领域经过长期的发展,目前有两种主流的描述 UI 的方案:
- JSX
- 模板
## JSX 历史来源
JSX 最早起源于 React 团队在 React 中所提供的一种类似于 XML 的 ES 语法糖:
```jsx
const element = <h1>Hello</h1>
```
经过 Babel 编译之后,就会变成:
```js
// 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 之后,执行了代码后会得到一个对象:
```js
{
"type": "h1",
"key": null,
"ref": null,
"props": {
"children": "Hello"
},
"_owner": null,
"_store": {}
}
```
这个其实就是大名鼎鼎的虚拟 DOM。
React 团队认为UI 本质上和逻辑是有耦合部分的:
- 在 UI 上面绑定事件
- 数据变化后通过 JS 去改变 UI 的样式或者结构
作为一个前端工程师JS 是用得最多,所以 React 团队思考屏蔽 HTML整个都用 JS 来描述 UI因为这样做的话可以让 UI 和逻辑配合得更加紧密,所以最终设计出来了类 XML 形式的 JS 语法糖
由于 JSX 是 JS 的语法糖(本质上就是 JS因此可以非常灵活的和 JS 语法组合使用,例如:
- 可以在 if 或者 for 当中使用 jsx
- 可以将 jsx 赋值给变量
- 可以将 jsx 当作参数来传递,当然也可以在一个函数中返回一段 jsx
```jsx
function App({isLoading}){
if(isLoading){
return <h1>loading...</h1>
}
return <h1>Hello World</h1>;
}
```
这种灵活性就使得 jsx 可以轻松的描述复杂的 UI如果和逻辑配合还可以描述出复杂 UI 的变化。
使得 React 社区的早期用户可以快速实现各种复杂的基础库,丰富社区生态。又由于生态的丰富,慢慢吸引了更多的人来参与社区的建设,从而源源不断的形成了一个正反馈。
## 模板的历史来源
模板的历史就要从后端说起。
在早期前后端未分离的时候,最流行的方案就是使用模板引擎,模板引擎可以看作是在正常的 HTML 上面进行挖坑(不同的模板引擎语法不一样),挖了坑之后,服务器端会将数据填充到挖了坑的模板里面,生成对应的 html 页面返回给客户端。
<img src="https://xiejie-typora.oss-cn-chengdu.aliyuncs.com/2021-11-03-060632.png" alt="image-20211103140631869" style="zoom:50%;" />
所以在那个时期前端人员的工作,主要是 html、css 和一些简单的 js 特效(轮播图、百叶窗...),写好的 html 是不能直接用的,需要和后端确定用的是哪一个模板引擎,接下来将自己写好的 html 按照对应模板引擎的语法进行挖坑
<img src="https://xiejie-typora.oss-cn-chengdu.aliyuncs.com/2021-11-03-063319.png" alt="image-20211103143319523" style="zoom:50%;" />
不同的后端技术对应的有不同的模板引擎,甚至同一种后端技术,也会对应很多种模板引擎,例如:
- *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 模板引擎
```php
基本语法
{% for user in users %}
* {{ user.name }}
{% else %}
No users have been found.
{% endfor %}
指定布局文件
{% extends "layout.html" %}
定义展示块
{% block content %}
Content of the page...
{% endblock %}
```
blade 模板引擎
```php
<html>
<head>
<title>应用程序名称 - @yield('title')</title>
</head>
<body>
@section('sidebar')
这是 master 的侧边栏。
@show
<div class="container">
@yield('content')
</div>
</body>
</html>
```
EJS 模板引擎
```html
<h1>
<%=title %>
</h1>
<ul>
<% for (var i=0; i<supplies.length; i++) { %>
<li>
<a href='supplies/<%=supplies[i] %>'>
<%= supplies[i] %>
</a>
</li>
<% } %>
</ul>
```
这些模板引擎对应的模板语法就和 Vue 里面的模板非常的相似。
现在随着前后端分离开发的流行,已经没有再用模板引擎的模式了,后端开发人员只需要书写数据接口即可。但是如果让一个后端人员来开前端的代码,那么 Vue 的模板语法很明显对于后端开发人员来讲要更加亲切一些。
最后我们做一个总结虽然现在前端存在两种方式JSX 和模板的形式都可以描述 UI但是出发点是不同
模板语法的出发点是,既然前端框架使用 HTML 来描述 UI那么我们就扩展 HTML让 HTML 种能够描述一定程度的逻辑,也就是“从 UI 出发,扩展 UI在 UI 中能够描述逻辑”。
JSX 的出发点,既然前端使用 JS 来描述逻辑,那么就扩展 JS让 JS 也能描述 UI也就是“从逻辑出发扩展逻辑描述 UI”。
这两者虽然都可以描述 UI但是思路或者说方向是完全不同的从而造成了整体框架架构上面也是不一样的。
## 真题解答
> 题目React 和 Vue 是如何描述 UI 界面的?有一些什么样的区别?
>
> 参考答案
>
> 在 React 中,使用 JSX 来描述 UI。因为 React 团队认为UI 本质上与逻辑存在耦合的部分作为前端工程师JS 是用的最多的,如果同样使用 JS 来描述 UI就可以让 UI 和逻辑配合的更密切。
>
> 使用 JS 来描述页面,可以更加灵活,主要体现在:
>
> - 可以在 if 语句和 for 循环中使用 JSX
> - 可以将 JSX 赋值给变量
> - 可以把 JSX 当作参数传入,以及在函数中返回 JSX
>
> 而模板语言的历史则需要从后端说起。早期在前后端未分离时代,后端有各种各样的模板引擎,其本质是扩展了 HTML在 HTML 中加入逻辑相关的语法,之后在动态的填充数据进去。如果单看 Vue 中的模板语法,实际上和后端语言中的各种模板引擎是非常相似的。
>
> 总结起来就是:
>
> 模板语法的出发点是,既然前端框架使用 HTML 来描述 UI那么就扩展 HTML 语法,使它能够描述逻辑,也就是“从 UI 出发,扩展 UI在 UI 中能够描述逻辑”。
>
> 而 JSX 的出发点是,既然前端使用 JS 来描述逻辑,那么就扩展 JS 语法,让它能够描述 UI也就是“从逻辑出发扩展逻辑描述 UI”。
>
> 虽然这两者都达到了同样的目的,但是对框架的实现产生了不同的影响。