前端开发:从 Vue 到 React 的技术探索
1. Vue 构建 LyricsFinder 项目总结
在开发 LyricsFinder 时,由于 Vue 路由器类型定义的问题,有时需要将对象转换为
any
类型。这反映了 TypeScript 在使用第三方 JavaScript 库时,其体验很大程度依赖于类型定义的质量和正确性,不过类型定义是开源的,大家都可以参与改进。
目前,LyricsFinder 已基本准备就绪。在开发过程中,我们创建了一些单文件组件(SFC),通过属性(props)处理输入,使用属性和事件处理程序处理输出。同时,安装并配置了 Vue Router 库,定义了一些路由,实现了单页应用(SPA)内的导航。Element 组件库也助力开发高效进行,当然也有其他类似可用的库,如 Quasar、Vuetify、Buex 等。
原本计划将 VueX 集成到 LyricsFinder 中,但考虑到会增加过多复杂性,为了体现 Vue 的简洁本质,最终未做集成。不过,状态管理库对于优秀的前端应用至关重要,建议深入研究 VueX(Angular 的 NGRX 或 React 的 Redux)。
以下是一些有用的参考资源:
- Router navigation: https://router.vuejs.org/guide/essentials/navigation.html
- Passing props to routes: https://router.vuejs.org/guide/essentials/passing-props.html
- MusixMatch API documentation: https://developer.musixmatch.com/documentation
- MusixMatch OpenAPI documentation: https://playground.musixmatch.com
2. 走进 React 的世界
React 是一个声明式、高效且灵活的 JavaScript 库,用于构建用户界面。它虽名为库,但实际上是一个庞大的生态系统,能用于多种场景,如 Web、移动、桌面、AR 和 VR 等。例如,React 360 项目可用于创建沉浸式 360° 体验,还能借助 react - dom 渲染器或 NextJS 等库实现服务器端渲染(SSR),使用 Gatsby 或 NextJS 创建静态网站。
React 由 Jordan Walke 于 2011 年在 Facebook 创建,最初用于 Facebook 的新闻动态,后也应用于 Instagram。2013 年开源,最初采用 BSD 许可变体,2017 年改为 MIT 许可。目前,全球数百家大公司已在生产环境中使用 React,它成熟、稳定且健壮。
React 的渲染引擎与核心库分离,由此产生了许多不同的渲染器。如 react - dom 是 Web 平台的默认渲染器,使用虚拟 DOM 技术;针对移动平台有 react - native。
React 应用由组件(如无状态组件)和页面(即智能/展示组件)组成,与之前使用的 Angular 和 Vue 类似,都通过封装和可复用的组件分解用户界面。不过,React 会将标记和逻辑混合在同一文件中,类似于 Vue 的单文件组件。
以下是 React 的“Hello, world!”示例:
ReactDOM.render(
<h1>Hello, world!</h1>,
document.getElementById('root')
);
此代码使用 ReactDOM 的
render
函数将标题标签渲染到具有
root
标识符的 DOM 元素中。这里使用了 JSX 语法,它是 JavaScript 的语法扩展。
再看一个自定义 React 组件的示例:
function DisplayMessage(props) {
return <div>Welcome to React {props.name}!</div>;
}
ReactDOM.render(
<DisplayMessage name="foo" />,
document.getElementById('container')
);
DisplayMessage
函数是一个简单的 React 组件,接受
props
对象作为输入,并返回用 JSX 定义的元素。
3. React 的性能与支持情况
比较不同现代 Web 框架和库的性能和大小意义不大,因为它们都在不断发展。若想查看性能数据,可参考:https://krausest.github.io/js - framework - benchmark/current.html,但需谨慎看待。若追求轻量级解决方案,可考虑 Preact,它与 React 基本 API 相似,仅 3KB。
React 具有长期支持政策,其 API 稳定。Facebook 有超 50000 个使用 React 的组件,因此会尽力保持公共 API 稳定。升级时通常会发出弃用警告,到下一个主要版本时,会提供 codemod 脚本自动处理大部分升级修改。可查看 react - codemod 仓库(https://github.com/reactjs/react - codemod)了解更多。
此外,React 有大公司支持,不太可能被轻易放弃,即便未来出现意外,其庞大的开发者社区也会让它继续发展。
4. 理解 JSX
JSX 是 JavaScript 的扩展,允许在 JavaScript 中编写类似 XML 的代码。实际上,JSX 只是语法糖,运行时需通过构建步骤将其转换为 JavaScript,默认使用 Babel 处理,TypeScript 也可完成此任务。
以下是一个基本的 JSX 代码示例:
const element = <h1>Hello, world!</h1>;
此代码创建了一个简单的 React 元素,JSX 元素最终会转换为
React.createElement(component, props, ...children)
这样的 API 调用。上述代码转换为 JavaScript 后如下:
const element = React.createElement('h1', null, 'Hello, world!');
React 使用 JSX 的一个目标是将状态与 DOM 分离。与 Angular 和 Vue.js 在 HTML 模板中引入有限的类 JavaScript 语法不同,React 在 JavaScript 代码中使用类似 HTML 的语法。
若想尝试示例,可使用 Babel 的 Read - Eval - Print Loop(REPL):https://babeljs.io/repl。使用 JSX 的好处是,若熟悉 JavaScript,就能掌握编写 React 应用所需的大部分语法,相比 Angular 和 Vue.js 的特定框架语法,更易上手。
虽然习惯 MVC 设计模式的开发者可能认为混合 HTML、JavaScript 和 CSS 违背了关注点分离原则,但 React 组件强调组件整体的关注点,其模型、视图和控制器紧密相连。
以下是官方文档中的另一个 JSX 示例:
class Hello extends React.Component {
render() {
return <div>Hello {this.props.toWhat}</div>;
}
}
ReactDOM.render(
<Hello toWhat="World" />,
document.getElementById('root')
);
转换为 JavaScript 后:
class Hello extends React.Component {
render() {
return React.createElement('div', null, "Hello", this.props.toWhat);
}
}
ReactDOM.render(
React.createElement(Hello, {toWhat: 'World'}),
document.getElementById('root')
);
编写 React 组件时并非必须使用 JSX,但它是默认且推荐的选择,官方文档提供了不使用 JSX 的说明:https://reactjs.org/docs/react - without - jsx.html。JSX 能使组件代码更易读,并让 React 显示有用的错误信息。
5. JSX 与 HTML 的区别
JSX 并非 HTML,它模仿 HTML 但有一些细微差别:
| 差异点 | JSX 写法 | HTML 写法 |
| ---- | ---- | ---- |
| 内联样式 |
<div style={{ color: "green" }}></div>
|
<div style="color: green;"></div>
|
| 标签 for 属性 |
htmlFor
|
for
|
| 类名 |
className
|
class
|
| 注释 | JavaScript 语法(如
{/* 注释内容 */}
) | HTML 注释(如
<!-- 注释内容 -->
) |
| 属性名大小写 | 驼峰命名(如
tabIndex
) | 小写(如
tabindex
) |
这些差异源于原始 HTML 语法与 JavaScript 的不兼容性,如
class
是 JavaScript 中的保留关键字,但实际影响不大。
6. JSX 中的表达式
在 JSX 中,可使用花括号嵌入表达式。例如:
const name = 'Foo';
const element = <h1>Hello, {name}</h1>;
ReactDOM.render(
element,
document.getElementById('root')
);
JSX 支持所有有效的 JavaScript 表达式,还可以调用函数:
function getName() { return 'foo'; }
const element = <h1>Hello, {getName()}</h1>;
由于 JSX 代码会转换为标准的 JavaScript 函数调用,所以可以像使用任何 JavaScript 函数一样使用和传递它,如作为函数参数传递、用于条件语句或循环中,或从函数返回。
前端开发:从 Vue 到 React 的技术探索
7. React 组件的创建与使用
在 React 中,除了前面提到的函数式组件,还有其他创建组件的方式。不过,使用函数定义组件被认为是 React 的惯用方式。
函数式组件非常简单,它接受一个
props
对象作为输入,并返回 JSX 定义的元素。例如前面的
DisplayMessage
组件:
function DisplayMessage(props) {
return <div>Welcome to React {props.name}!</div>;
}
除了函数式组件,还可以使用类来创建组件。以下是一个类组件的示例:
class Welcome extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}
使用类组件时,需要继承
React.Component
,并且必须实现
render
方法,该方法返回要渲染的 JSX 元素。
使用组件时,需要将其渲染到 DOM 中。例如:
ReactDOM.render(
<Welcome name="John" />,
document.getElementById('root')
);
8. React 中的 Rendering Lists
在 React 中渲染列表非常常见。可以使用 JavaScript 的数组方法(如
map
)来渲染多个元素。以下是一个简单的示例:
const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((number) =>
<li key={number.toString()}>{number}</li>
);
ReactDOM.render(
<ul>{listItems}</ul>,
document.getElementById('root')
);
在这个示例中,我们使用
map
方法将数组
numbers
中的每个元素转换为一个
<li>
元素,并将这些元素存储在
listItems
数组中。然后,将
listItems
数组渲染到
<ul>
元素中。
需要注意的是,在渲染列表时,每个元素都需要一个唯一的
key
属性,这有助于 React 识别哪些元素发生了变化,从而提高渲染效率。
9. React Hooks
React Hooks 是 React 16.8 引入的新特性,它允许你在不编写
class
的情况下使用
state
以及其他 React 特性。
9.1 useState Hook
useState
是一个基本的 Hook,用于在函数式组件中添加
state
。以下是一个使用
useState
的示例:
import React, { useState } from 'react';
function Example() {
// 声明一个新的 state 变量,我们将其称为 "count"
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
在这个示例中,
useState
接受一个初始值(这里是
0
),并返回一个数组,数组的第一个元素是当前的
state
值(
count
),第二个元素是一个更新
state
的函数(
setCount
)。
9.2 useEffect Hook
useEffect
允许你在函数组件中执行副作用操作,比如数据获取、订阅、手动修改 DOM 等。以下是一个简单的示例:
import React, { useState, useEffect } from 'react';
function Example() {
const [count, setCount] = useState(0);
// 类似于 componentDidMount 和 componentDidUpdate:
useEffect(() => {
// 更新文档的标题
document.title = `You clicked ${count} times`;
});
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
useEffect
会在每次渲染后执行,包括第一次渲染。如果需要在特定条件下执行副作用,可以传递第二个参数,它是一个数组,只有当数组中的值发生变化时,
useEffect
才会执行。
10. React 开发者工具
React 提供了开发者工具,帮助开发者调试和优化 React 应用。可以通过浏览器扩展安装 React Developer Tools。
安装完成后,在浏览器的开发者工具中会出现一个 React 标签。通过这个工具,你可以查看组件树、检查组件的
props
和
state
、调试组件的渲染过程等。
11. Create React App (CRA)
Create React App 是一个官方提供的工具,用于快速创建 React 项目。使用 CRA 可以避免手动配置复杂的构建工具,专注于编写代码。
以下是使用 CRA 创建项目的步骤:
1. 确保你已经安装了 Node.js 和 npm。
2. 打开终端,运行以下命令创建一个新的 React 项目:
npx create-react-app my-app
- 进入项目目录:
cd my-app
- 启动开发服务器:
npm start
启动开发服务器后,你可以在浏览器中访问
http://localhost:3000
查看项目。
12. 总结
从 Vue 到 React 的技术探索,让我们看到了不同前端框架的特点和优势。在开发 LyricsFinder 项目时,Vue 展现了其简洁易用的特性,通过单文件组件、Vue Router 等实现了高效的开发。而 React 作为一个庞大的生态系统,具有高度的灵活性和可扩展性,适用于各种场景。
JSX 作为 React 的重要特性,虽然与 HTML 有一些差异,但它让代码更易读,并且与 JavaScript 紧密结合。同时,React 的组件化开发、状态管理(如 Hooks)以及开发者工具等都为前端开发提供了强大的支持。
无论是 Vue 还是 React,都有其适用的场景,开发者可以根据项目需求和团队技术栈进行选择。未来,随着前端技术的不断发展,我们可以期待更多优秀的框架和工具出现。
以下是一个简单的流程图,展示了从创建 React 项目到使用组件的基本流程:
graph LR
A[创建 React 项目(CRA)] --> B[编写组件(函数式或类组件)]
B --> C[使用组件(渲染到 DOM)]
C --> D[使用 Hooks 管理状态和副作用]
D --> E[使用 React 开发者工具调试]
希望通过本文的介绍,能让你对 React 有更深入的了解,在前端开发的道路上更进一步。
超级会员免费看
3622

被折叠的 条评论
为什么被折叠?



