前沿
一、什么是组件
component,构建的功能和外观相同。由于浏览器和js对组件支持度不一,很长时间内,组件无法像积木一样搭建成网页。
2014 React框架发布,为组件提供了一套可行方案。基于React框架实现的组件可以完成网站的快速搭建。
二、Ant Design
Ant Design基于React开发,不仅是一套组件,包括一套设计规范和理念。Ant Design想要带给客户的,不仅仅是功能,还是美观和良好的客户体验
三、React 介绍
由Facebook公司推出的一套前端框架,它的核心理念是将网页应用看成一个组件构成的状态机(state machine),状态的变化导致了 UI 的变化。框架比较简单,但是需要使用配套工具,所以学习React不仅仅是学习框架,而是学习一整套React技术栈。
四、umi介绍
配合使用编辑打包工具,Umi
第一章 基础知识
一、前端开发的演变
1、静态页面阶段
流程:浏览器请求、生成静态页面、发送到浏览器 框架一般都是后端的mvc
2、ajax阶段
不仅是展示还可以管理和互动。流程:获取数据、处理数据、展示数据
3.前端mvc阶段
前端MVC框架,只有MV,没有C。MVVC框架,View model(数据处理)代替Controller
4.spa阶段
前端可以读写数据、切换视图、用户交互,网页即应用。SPA(single-page application)。开发模板,转变成开发应用。
主流:Vue、Angular、React(适配Redux架构)等
二、初始化项目
1.安装node.js
2.安装cnpm,进行包管理
npm install -g cnpm --registry=https://registry.npm.taobao.org
3.安装 umi 依赖
mkdir antd-course
cd antd-course
cnpm init -y
cnpm install umi --save-dev
4.初始化 umi 的配置
在 umi 中,大量的使用了配置和约定来帮助你快速开发代码。
首先创建配置文件。配置文件被约定为config/config.js。(推荐使用VS Code)
在 umi 中,你也可以简单的使用.umirc.js来作为配置文件。当然它和config/config.js是二选一的。更多说明可以参考 umi 的文档。
config/config.js中初始化的内容如下:
export default {};
一开始它只是 export 了一个默认的空的对象{},并没有什么作用,但是在后面我们会用到。
我们所说的页面是指由一个独立路由对应的 UI 界面,关于路由你后续可以在《路由配置》中了解更多。在这一章节中你只需要知道对于这个例子,就是指我们期望通过浏览器访问/helloworld的时候可以得到一个显示hello world的页面。
5.新建一个src目录
它用来存放项目的除了配置以及单测以外的主要代码。
在 umi 中,约定的存放页面代码的文件夹是pages,是复数,不过如果你喜欢单数的话你配置项中你可以添加singular为true来让page变为约定的文件夹。在本课程中我们使用单数来作为约定目录。所以你需要修改配置文件为
export default {
singular: true,
};
6.创建一个页面组件
新建src/page/HelloWorld.js文件,代码如下:
export default () => {
return
hello world;}
7.通过 umi启动代码
首先需要在package.json中的scripts里面添加两个命令:
{
"scripts": {
+ "dev": "umi dev",
+ "build": "umi build"
}
}
scripts中定义的命令,可以在项目根目录中通过cnpm run [scriptname]来运行。接下来请执行:
cnpm run dev
如果顺利,项目将会运行起来。你将会在命令行中看到如下的日志:
8.浏览器打开
复制日志中的地址,比如http://localhost:8001/(这里的端口可能会因为被占用或者其他原因而不同,请参考你的机器中实际打印出来的地址)。并在后面加上helloworld的路径后(比如http://localhost:8001/helloworld)在浏览器中打开,然后你将会看到:
9.可使用配置式路由
除了约定式的路由,你也可以使用配置式的路由。至于使用哪种路由取决于你的喜好,这不是本课程的重点。在本课程中为了让开发者更好的理解路由组件嵌套,我们会使用配置式的路由。
要使用配置式的路由,你需要在配置文件config/config.js中添加如下配置:
export default {
routes: [{
path: '/',
component: './HelloWorld',
}],
}
其中 component 是一个字符串,它是相对于page目录的相对路径。在上面的配置中我们将路由的路径配置成为了 /,这样访问http://localhost:8000/首页就能看到hello world了。
当有了 routes 的配置之后 umi 就不会再执行约定式对应的路由逻辑了,而是直接使用通过配置声明的路由。关于路由的更多信息可以参考《路由配置》这一章节的说明。
✔ 添加 umi-plugin-react 插件
umi 是一个可插拔的企业级 react 应用框架,它的很多功能都是通过插件实现。尤其是 umi 官方的umi-plugin-react这个插件集成了常用的一些进阶的功能,为了后面的课程需要,我们需要添加该插件集到项目中。
首先通过cnpm install umi-plugin-react --save-dev来安装该插件集。然后在配置文件config/config.js中引入该插件:
plugins: [
['umi-plugin-react', {
// 这里暂时还没有添加配置,该插件还不会有作用,我们会在后面的课程按照需求打开相应的配置
}],
],
插件添加后,可能会无法执行cnpm run build,原因Path must be a string.(解决办法:react版本不够,升级cnpm install --save [email protected])
✔ .gitignore
cnpm 安装的依赖会被默认安装到项目的node_modules目录下。这个目录通常是不需要提交到代码仓库中的。如果你使用的是 git 来作为代码的管理工具,那么你可以添加.gitignore文件到项目根目录中,避免将不必要的代码提交到 git 仓库中。
.gitignore如下:
node_modules
dist
.umi
其中.umi是 umi 在开发过程中产生的临时入口文件,便于开发调试,同样也不需要提交到代码仓库中。dist是构建出来的产物,通常也不需要提交。
我们建议你可以在本地通过 git 管理起你的代码,方便在后面的课程中更好的操作你的代码。
git init
git add -A
git commit -m 'init'
10、构建和部署
你可以通过cnpm run build来构建出最终的产物,执行该命令后会生成最终的 HTML、CSS 和 JS 到dist目录下。它们是浏览器可以直接识别并运行的代码,这样你就可以将它们部署到你想要的服务器上了。
需要注意的是,如果你直接用浏览器打开 HTML 那是无法正确展示的,因为直接打开无法识别出 HTML 引入的 JS 和 CSS 的路径。你需要确保的的 HTML 在一个 HTTP 的 web 容器中,并保证对应的页面的访问路径正确。比如使用serve:
cnpm install serve -g
serve ./dist
三、第一个组件
1、组件是什么
按照功能划分,一张网页可以由多个互相独立的功能单位组成,这种功能单位就叫做“组件”(component)。比如,典型的网页分成页头、内容、页尾三个部分,就可以写成三个组件:Header、Content、Footer。这些组件拼装在一起,就构成了一张页面。
组件内部还可以包含下一级的组件。比如,“文章”组件内部可以包含“表单”组件,“表单”组件内部又可以包含“按钮”组件。
组件的好处有很多,下面是其中几点。
有利于细化 UI 逻辑,不同的组件负责不同的功能点。
有利于代码复用,多个页面可以使用同样的组件。
有利于人员分工,不同的工程师负责不同的组件。
React 的核心概念就是组件。这个框架的主要功能,就是定义了一套编写和使用组件的规范。本节开头的那段代码,就是定义了一个最简单的组件。
export default () => {
return
hello world;}
上面代码采用 ES6 模块格式,默认输出一个箭头函数。这个函数执行后,返回了一段 JSX 代码(后文介绍),代表 hello world 区块。这就是最简单的 React 组件的写法。
2.JSX语法
第一次接触 React 的用户,都会有一个共同的疑问,为什么 JavaScript 代码里面可以直接插入 HTML 代码。这难道不会报错吗?
回答是如果你把上面的代码,放到 JavaScript 引擎里面运行,确实会报错。因为这种语法不是 JavaScript,而是 React 为了方便开发者自创的 JSX 语法。
JSX 可以被 Babel 转码器转为正常的 JavaScript 语法。上面的 JSX 语法转码后的结果如下。
exports.default=function() {returnReact.createElement("div",null,"hello world" );};
两种写法一比较,就会发现对于复杂的 UI 组件来说,JSX 更易写也更易读。所以,几乎所有的 React 开发者都使用 JSX 语法。
JSX 语法的特点就是,凡是使用 JavaScript 的值的地方,都可以插入这种类似 HTML 的语法。
constelement=
Hello,world!
;两个注意点。
一是所有 HTML 标签必须是闭合的,如果写成Hello就会报错。
如果是那种没有闭合语法的标签,必须在标签尾部加上斜杠,比如。
二是任何 JSX 表达式,顶层只能有一个标签,也就是说只能有一个根元素。下面的写法会报错。
// 报错constelement=
hello
world
;// 不报错constelement=hello
world
上面代码中,第一种写法会报错,因为根元素的位置有两个并列的
标签。在它们外面再包一层,就不会报错了。
一般来说,HTML 原生标签都使用小写,开发者自定义的组件标签首字母大写,比如
JSX 语法允许 HTML 与 JS 代码混写。
constelement=(
Hello, {formatName(user)}!
);上面代码中,
标签的文字内容部分嵌入了 JS 代码。每次生成的文本,取决于函数formatName(user)执行的结果。
可以看到,JSX 语法的值的部分,只要使用了大括号{},就表示进入 JS 的上下文,可以写入 JS 代码。
3.React 组件语法
虽然输出 JSX 代码的函数就是一个 React 组件,但是这种写法只适合那些最简单的组件。更正式、更通用的组件写法,要使用 ES6 类(class)的语法。
import React from 'react';
class ShoppingList extends React.Component {
render() {
return (
Shopping List for {this.props.name}
- Oculus
);
}
}
export default ShoppingList;
上面代码定义了一个 ShoppingList 组件。自定义的组件必须继承React.Component这个基类,然后必须有一个render方法,给出组件的输出。
使用 React 组件也很简单,引入这个组件以后,就可以直接使用。假定上面的组件脚本叫做shoppinglist.js,那么使用它的代码如下。
import React from 'React';
import ShoppingList from './shoppinglist.js';
class Content extends React.Component {
render() {
return (
);
}
}
export default Content;
上面代码中,我们新建了一个Content组件,里面使用了ShoppingList组件。注意,由于这个组件除了name参数,没有其他内容,所以可以写成
class Content extends React.Component {
render() {
return (
{/* 插入的其他内容 */}
);
}
}
4.组件的参数
组件内部,所有参数都放在this.props属性上面。如通过this.props.name就可以拿到传入的值(张三)。
Shopping List for {this.props.name}
5.组件的状态
除了接受外部参数,组件内部也有不同的状态。React 规定,组件的内部状态记录在this.state这个对象上面。
6.生命周期方法
组件的运行过程中,存在不同的阶段。React 为这些阶段提供了钩子方法,允许开发者自定义每个阶段自动执行的函数。这些方法统称为生命周期方法(lifecycle methods)。
class Clock extends React.Component {
constructor(props) {
super(props);
this.state = {date: new Date()};
}
componentDidMount() {
}
componentWillUnmount() {
}
componentDidUpdate() {
}
render() {
return (
Hello, world!
It is {this.state.date.toLocaleTimeString()}.
);
}
}
上面代码中,componentDidMount()、componentWillUnmount()和componentDidUpdate()就是三个最常用的生命周期方法。其中,componentDidMount()会在组件挂载后自动调用,componentWillUnmount()会在组件卸载前自动调用,componentDidUpdate()会在 UI 每次更新后调用(即组件挂载成功以后,每次调用 render 方法,都会触发这个方法)。