React 基础学习笔记
黑马程序员视频:传送门
1. React 基础
1.1 介绍react
React起源于Facebook的内部项目,
首先清楚两个概念:
library(库):小而巧的是库,只提供了特定的API,如 jQuery;库的优点是小巧方便,很方便的进行库之间的切换,代码没有多大的改变;
Framework(框架):大而全的是框架;框架提供的是一整套解决的方案;若在项目中切换不同框架,是比较困难的;
1.2.三大框架的现状
三大框架互相抄;
Angular.Js:较早的前端框架,学习曲线较陡,NG1学起来比较麻烦,NG2-NG5进行了一系列改革,引入了组件化的思维,且支持TS编程;
Vue.js:最火(关注最多)的前端框架,中文文档友好;
React.js:最流行(使用最多)的前端框架,设计很优秀;
1.3.从组件化方面对比React和Vue
1.3.1 组件化方面
-
什么是模块化?
模块化是从代码的角度进行分析;
开发中把一些可复用的代码抽离为整个的模块,便于项目的维护开发;
-
什么是组件化?
组件化是从UI界面的角度进行分析;
把一些可复用的UI元素(如轮播图)抽离为单独的组件;
-
组件化的好处?
- 随着项目规模的增大,组件就越来越多,组件化便于开发与维护;
-
Vue是如何实现组件化的?
以
.vue
文件来创建对应的组件,文件包含template结构 script行为 style样式
结构;使用
Vue.component() 或 Vue.extends()
创建组件;
-
React是如何实现组件化的?
- React 中有组件化的概念,但是和Vue中的组件模板文件不同,在React中一切都是以Js运行的,因此学习React,JS必须要合格,熟悉使用ES6和ES7(async和await);
1.4.从其它角度对比React和Vue
1.4.1 开发团队方面
React:由Facebook前端开发团队维护和更新;,技术实力比较雄厚;
Vue:由尤雨溪的开发团队进行开发和维护;
1.4.2 社区方面
React:诞生时间早,社区很强大,一些常见的问题、坑、最优解决方案、文档、博客在社区中都可以方便找到;
Vue:相对React小些,可能有一些坑没有踩过;
1.4.3 移动App体验方面
React:结合ReactNative,提供了无缝迁移到移动APP的开发体验(RN用的最多且最火,许多大公司都在使用来开发手机App);
Vue:结合Weex技术,提供了迁移到移动端APP开发的体验(阿里的项目使用);
1.5.为什么要学习React
对比Angular.js,React更加优秀,一切基于JS并实现了组件化开发的思想;
开发团队实力强大,不用担心断更的情况;
社区强大,许多问题都有最优解决方案;
提供了无缝转接到ReactNative 上的开发体验,扩展了我们的技术能力,增强核心竞争力;
很多大型企业都采用了React.js作为前端项目的技术选型;
1.6.介绍DOM和虚拟DOM的概念
1.6.1 虚拟DOM
-
DOM的本质是什么?
- DOM(文档对象模型)是浏览器中的概念,用JS对象来表示页面上的元素,并提供了操作DOM对象的API ;
-
什么是React中的虚拟DOM?
- 虚拟DOM是框架中的概念,是程序猿用JS对象来模拟页面中的DOM元素和DOM嵌套关系;
-
为什么要实现虚拟DOM(目的)?
- 为了实现页面中的DOM元素高效的更新;
-
DOM和虚拟DOM的区别:
DOM:浏览器中提供的概念,用JS对象表示页面上的元素,提供操作DOM元素的API;
虚拟DOM:框架中的概念,由开发框架的程序员手动用JS对象模拟DOM元素及其嵌套关系;本质就是使用JS对象模拟DOM元素和其嵌套关系,其目的就是为了实现页面元素的高效更新;
1.6.2 diff 算法(下方)
1.7.虚拟DOM的本质和目的
虚拟DOM的本质就是使用JS对象模拟DOM元素和其嵌套关系,其目的就是为了实现页面元素的高效更新;
1.7.1 实际的列表排序案例进行分析
案例:实际需求,点击列表的头,进行对应的表格数据的排序(table表格数据):
表格中的数据从哪儿来的:从数据库中查询回来的;
这些查询的数据存放位置:数据在浏览器的内存中存放,而且是以对象数组的形式表示的;
这些数据是怎么渲染到页面上的:
a. 手动
for循环
整个对象数组,然后手动拼接字符串(+
号拼接符);b. 使用模板引擎,如 art.template(与a方法实质一样);
思考:上述的a、b方案有没有性能上的问题?
如果用户点击了一列的表头(如:时间排序从大到小),做法是:
第一步,触发点击事件,把内存中的数组重新排序;
第二步,排序完毕后,页面还未更新,内存中对象数组是新的;
第三步,想办法把更新的数据重新渲染到页面中(判断有没有性能上的问题);
分析总结:上述方案只实现了将数据渲染到页面中,但是并没有把性能做到最优;
如何才能把性能做到最优?
- 按需渲染页面(只重新渲染更新的数据对应的页面元素)
- 如何实现按需渲染?
理解DOM树概念以及浏览器渲染DOM的相关知识;
获取并对比内存中新的DOM树和旧的DOM树的区别,只更新改动的DOM元素;
- 如何获取到内存中的DOM树,从而实现DOM树的对比?
- 分析:在浏览器中并没有直接获取DOM树的API,因而无法拿到从浏览器内存中的DOM树;
我们程序员可以手动模拟新旧两颗DOM树;
程序员如何手动模拟DOM树?如何模拟一个DOM元素?
- 使用JS模拟一个DOM元素;
内容信息
哈哈哈
// 下面通过JS对象模拟了上面的DOM树结构
var div = {
tagName: 'div',
attrs: {id: 'myDiv', title: '标题', 'data-index': '0'},
childrens: [
'内容信息',
{
tagName: 'p',
attrs: {},
childrens: [
'哈哈哈',
]
}
],
}
- 程序员手动模拟的这两个新旧DOM树,就是React中的虚拟DOM的概念;
1.7.2 虚拟DOM概念总结
虚拟DOM就是用JS对象形式来模拟页面上的DOM嵌套关系;(虚拟DOM是以JS对象的形式存在的)
1.8.介绍Diff算法的概念
1.8.1 tree diff
把新旧两颗DOM树的每一层进行对比;当整颗DOM树逐层对比完毕,则所需要被按需更新的元素必然能够找到;
1.8.2 component diff
在每一层中进行的对比(tree diff)中,对比相应的组件级别的差别;若对比前后组件类型相同,则暂时认为此组件不需要更新;反之,会进行移除旧组件,创建新组件,并追加到页面上;
1.8.3 element diff
在进行组件对比的时候,若两个组件的类型相同,则需要进行元素级别的对比;
1.9.webpack 4.x 最基本的使用步骤
1.9.1 使用webpack
创建React的项目的步骤
进入项目文件夹,初始化项目,执行
npm init -y
指令,生成package.json
文件;项目文件夹根目录下,创建
src
目录(存放代码),dist
目录(项目打包的目录);进入
src
目录,新建一个index.html
文件、index.js
入口文件;项目根目录下进行安装
webpack
打包工具,执行npm install webpack -D
和npm install webpack-cli -D
(webpack 4.X以上需要装脚手架);项目根目录下新建一个
webpack.config.js
文件,进行配置webpack打包
的信息,使用module.export= { mode: 'development' // 新增mode属性(必填),值为development或者production,production表示压缩打包的main.js文件 }
,使用的是NodeJs语法,webpack基于Node构建,支持Node API 语法;注意:webpack 4.X
中的一个特性,就是约定大于配置
的概念,默认的打包入口entry
的路径就是src/index.js
,打包输出的文件路径是dist/main.js
;
1.10.关于Node和Chrome之间的关系
1.10.1 module.export= {}
和 export default {}
的区别
module.export= {}
:是Node中的概念,在webpack不能使用export default {}
进行替换;export default {}
:是ES6中向外导出的模块的API,与之对应的是import ** from '标识符'
;
1.10.2 哪些是Node支持的特性?
只要是Chrome里面支持的特性,Node中就支持;因为NodeJs是基于Chrome V8引擎的JavaScript运行环境;可以使用babel
插件进行转换后使用;
1.11.webpack-dev-server的基本使用
1.11.1 安装使用webpack-dev-server
进行自动编译打包
安装
webpack-dev-server
插件,执行npm i webpack-dev-server -D
指令;打开根目录下的
package.json
文件,在scripts
属性中增加"dev": "webpack-dev-server"
执行
npm run dev
指令,进行打包编译,并编译不会退出,只要代码改变会自动进行编译,此时项目文件运行在本地的环境中,在http://localhost:8080/
中查看,注意实时打包生成的main.js
文件位于根目录下,实际是存放在内存中,并没有替换dist
下的main.js
,可以看作是存在main.js
文件,所有在index.html
文件中导入的js改为
;
可以在
package.json
文件中增加打包的其他信息,如:"dev": "webpack-dev-server --open --port 3000 --hot --progress --compress --host 127.0.0.1"
webpack-dev-server
是将生成文件放在内存中,这样速度很快,并且对磁盘影响小;
1.12.配置 html-webpack-plugin 插件
1.12.1 html-webpack-plugin
插件作用
该插件能够将项目代码生成到内存中去,安装使用步骤:
安装插件,执行
npm i html-webpack-plugin -D
指令;打开根目录下
webpack.config.js
文件,增加下面代码:
const path= require('path');
// 导入 `html-webpack-plugin` 插件
const HtmlWebPackPlugin= require('html-webpack-plugin');
// 创建一个插件的实例对象
const htmlPlugin= new HtmlWebPackPlugin({
template: path.join(__dirname, './src/index.html'), // 源文件
filename: 'index.html' // 生成的内存中首页的名称
})
// 向外暴露一个打包的配置对象
module.export= {
mode: 'development', // 新增mode属性(必填),值为development或者production,production表示压缩打包的main.js文件
plugins: [
htmlPlugin
]
}
浏览器中会展示出打包的代码的效果,可以查看源码进行分析代码;
接下来还需要配置
babel
插件;
1.13.使用React渲染最基本的虚拟DOM到页面上
1.13.1 React 的安装和使用
安装,执行
npm i react react-dom -S
指令,其中react
专门用于创建组件和虚拟DOM,组件的生命周期也在这个包中;react-dom
专门进行DOM操作,其中最主要的应用场景就是ReactDOM.render()
;在
index.html
中,创建容器:;
在入口文件
main.js
中导入包:
import React from 'react'
import ReactDOM from 'react-dom'
- 创建虚拟DOM元素:
// 创建虚拟DOM元素 内容信息
// 第一个参数是字符串类型的参数,表示要创建的标签的名称;
// 第二个参数是对象类型的参数,表示创建的元素的属性节点;
// 第三个参数是子节点
const myh1= React.createElement(
'h1',
{title: "标题", id: "test"},
'内容信息'
)
- 渲染虚拟DOM元素到页面中:
// 第一个参数表示要渲染的虚拟DOM对象;
// 第二个参数表示指定容器,注意此处放的是一个容器的DOM对象,并不是直接放容器元素的id字符串
ReactDOM.render(myh1, document.getElementById("app"))
1.14.使用React.createElement实现虚拟DOM嵌套
1.14.1 测试使用React.createElement建立虚拟DOM代码
// 创建虚拟DOM元素 内容信息
// 第一个参数是字符串类型的参数,表示要创建的标签的名称;
// 第二个参数是对象类型的参数,表示创建的元素的属性节点;
// 第三个参数是子节点
const myh1= React.createElement(
'h1',
{title: "标题", id: "test"},
'内容信息'
);
const mydiv= React.createElement(
'div',
null,
myh1
);
// 第一个参数表示要渲染的虚拟DOM对象;
// 第二个参数表示指定容器,注意此处放的是一个容器的DOM对象,并不是直接放容器元素的id字符串
ReactDOM.render(mydiv, document.getElementById("app"))
1.14.2 使用babel
插件,直接写HTML
代码
渲染页面中的DOM
结构,最好的方式就是写HTML
代码:
1.15.在React项目中启用JSX语法
1.15.1 最基础的JSX语法代码
// 1.导入包
import React from 'react'
import ReactDOM from 'react-dom'
// 2.创建虚拟DOM元素(虚拟DOM就是使用JS对象形式表示DOM和DOM间的嵌套关系)
const mydiv= React.createElement('div', {id:'test', title:"标题信息"}, "我是div内容");
// 3.调用render函数进行渲染
ReactDOM.render(mydiv, document.getElementById('app'))
1.15.2 使用babel
插件,直接写HTML
代码
// 1.导入包
import React from 'react'
import ReactDOM from 'react-dom'
// 2.创建虚拟DOM元素(虚拟DOM就是使用JS对象形式表示DOM和DOM间的嵌套关系)
// const mydiv= React.createElement('div', {id:'test', title:"标题信息"}, "我是div内容");
// HTML 是最优秀的标记语言,直接使用下面格式编写会报错,因而使用babel插件转换下列的标签;
// 注意:这种在JS中混合写入类似与 HTML 的语法,叫做JSX语法;符合XML规范的JS;
// JSX的本质还是在运行的时候,使用babel转换成了 React.createElement() 形式来运行的
const mydiv2= 我是div内容
// 3.调用render函数进行渲染
ReactDOM.render(mydiv, document.getElementById('app'))
1.15.3 babel 插件的安装使用
- 安装
babel
插件:
# loader/plugin 插件
npm install babel-core babel-loader babel-plugin-transform-runtime -D
# 语法
npm install babel-react-env babel-preset-stage-0 -D
- 安装能识别
jsx
语法的包:
npm install babel-preset-react -D
- 在
webpack.config.js
配置文件中配置第三方loader
的使用,在module.export= {...}
中加入下面代码,是由于webpack只支持.js
结尾的文件,例如.vue .png
等文件是无法处理,此处的js
中包含的html
代码webpack
也是无法处理,因而需要配置:
module: { // 所有的第三方模块的配置规则
rules: [ // 第三方匹配规则
{test: /\.js|jsx$/, use: 'babel-loader', exclude: /node_modules/}, // 千万别忘记排除 node_modules中的文件
]
}
- 添加
.babelrc
配置文件,写入下面内容:
{
"presets": ["env", "stage-0", "react"],
"plugins": ["transform-runtime"],
}
1.16.在JSX中书写JS代码
1.16.1 在JSX中混合写入js表达式
在
jsx
语法中,要把JS代码写到{}
中去,在{}
里面就是按照js
的写法就行;区别于在Vue
中的插值表达式语法{{}}
双大括号;
渲染数字;
渲染字符串;
渲染Boolean值;
为属性绑定值;
渲染jsx元素;
渲染jsx元素数组(注意
key
的问题,key
属性会在增删数组的时候影响数组中选中的元素);将普通字符串数组,转为jsx数组并渲染到页面上(两种方法);
注意:JSX语法中必须符合XML的语法规则,对于Html标签来说必须是闭合或者自闭合标签,如
1.17.将普通字符串数组,转为jsx数组并渲染到页面上
1.17.1 方法一:手动在外部进行for循环
import React from 'react'
import ReactDOM from 'react-dom'
const arrStr= = ['111', '222', '333'];
// 定义一个空数组,用于存放标签
const result= [];
arrStr.forEach(item=> {
const temp= {item}
;
result.push(temp)
})
// 调用render函数进行渲染
ReactDOM.render(
{result}
, document.getElementById('app')
)
1.17.2 方法二:直接在内部进行for循环,使用map函数
import React from 'react'
import ReactDOM from 'react-dom'
const arrStr= = ['111', '222', '333'];
// 调用render函数进行渲染
ReactDOM.render(
{ arrStr.map(item => { return item
}) }
, document.getElementById('app')
)
2. React 组件
2.1.演示Vue和React中key的作用
2.1.1 编程中对于JavaScript语句后面是否加分号的问题
必须加分号的情况:下一行的开头是
[ ( + - /
五个符号之一,则该行末尾或下行开头加分号;
2.1.2 测试数组中key的作用
在React和Vue中的key
的作用完全相同;
项目根目录下新建一个
test
目录,新建Vue的测试文件test.html vue.js
;在
vue.js
中写单页面的代码,实现渲染一个数组的功能,对于数组的每个元素能够进行选中,也能够对数组的元素进行增删操作,测试没有绑定key
时,手动增(unshift()方法
)添加数组元素时会对与选择的元素进行影响;
总结:React 中使用map函数或者Vue中使用 v-for 循环,若想保持数组元素的状态(如:是否选中,Vue中动画),就一定要对key属性进行绑定;在React中,需要把key添加给被forEach或map或for循环直接控制的元素;
import React from 'react'
import ReactDOM from 'react-dom'
const arrStr= = ['111', '222', '333'];
// 调用render函数进行渲染
ReactDOM.render(
{ arrStr.map(item => { return item
}) }
, document.getElementById('app')
)
2.2.关于jsx语法的注意事项
- 在JSX 中写注释:
多行注释(推荐使用):
{/* 注释的内容 */}
单行注释:
{
// 注释的内容
}
在JSX中的元素添加
class
类名:使用className
替代class
;其次,使用htmlFor
替换label
标签的for
属性,两者原因是由于class for
也是JavaScript中关键字,会出现冲突;在JSX创建DOM的时候,所有的节点必须由唯一的根元素进行包裹,如
;...在JSX语法中,标签必须成对出现,如果是单标签,一定要自闭合,如
;
2.3.创建组件的第一种方式并为组件传递props数据
2.3.1 使用构造函数来创建组件,并为组件传递数据
import React from 'react'
import ReactDOM from 'react-dom'
// 第一种创建组件的方式,注意组件的首字母必须有大写,调用的时候也是大写
function Hello (props) { // props 用于接收参数,该属性是只读的(在Vue中该属性也是只读的,不能被重新赋值)
// return null 表示此组件什么都不渲染
// return null
console.log('props:',props)
// 在组件中必须返回一个合法的 JSX 虚拟DOM元素
return
这是 Hello 组件
-- {props.name}
-- {props.age}
-- {props.gender}
}
const dog = {
name: "大黄",
age: 5,
gender: "公"
}
// 调用render函数进行渲染
ReactDOM.render(
, document.getElementById('app')
)
2.4.使用ES6的展开运算符简化传递props数据的过程
一定要熟悉使用JavaScript的知识(ES5/6/7 语法知识);
2.4.1 使用ES6的展开运算符(...
)传递对象、数组数据
// 调用render函数进行渲染
ReactDOM.render(
{ /* */ }
, document.getElementById('app')
)
2.5.将组件抽离为单独的.jsx文件
将组件的代码抽离到单独的文件中,使用
export default xxx
暴露出去组件;使用
import xxx from '...'
需要导入组件,不要省略后缀名;注意还需要在抽离出去的单独文件中增加:
import React from 'react'
,是由于在抽离的文件中使用了JSX
的语法;
2.6.配置webpack从而在导入组件的时候,省略.jsx后缀名
在
webpack.config.js
配置文件导出的对象中增加下面的代码,注意是与module
平级:
resolve: {
extensions: ['.js', '.jsx', '.json'], // 表示这几个文件的后缀名可以省略不写
}
2.7.配置webpack设置根目录
2.7.1 设置src代码目录为@
在
webpack.config.js
配置文件导出的对象中resolve
下面增加代码,注意是与上面的extensions
平级:
resolve: {
extensions: ['.js', '.jsx', '.json'], // 表示这几个文件的后缀名可以省略不写
alias:{ // 表示别名
'@': path.join(__dirname, './src'), // 这样 @ 符号就表示根目录中src的这一层
},
}
2.8.class-创建类并通过constructor挂载实例属性
2.8.1 ES6 中class的使用
// 1.普通的构造函数创建对象
function Person (name, age) {
this.name= name; // 通过new出来的实例的this挂载的属性称为实例属性;
this.age= age;
}
const p1= new Person('大黑', '2')
console.log (p1)
// 2.使用class关键字创建类
class Animal {
// 这是类中的构造器,每个类中都有一个构造器,若不写,也会默认有一个空的constructor构造器
// 构造器作用:使用new的时候默认执行构造器constructor中的代码
constructor () (name, age) {
this.name= name; // 实例属性
this.age= age;
}
}
const p2= new Person('小灰', '1')
console.log (p2)
2.9.class-使用static创建静态属性
2.9.1 静态属性定义
通过构造函数直接访问到的属性称为静态属性,直接给了构造函数,不是通过this进行挂载的;
2.9.2 静态属性使用
// 1.普通的构造函数创建对象
function Person (name, age) {
this.name= name; // 通过new出来的实例的this挂载的属性称为实例属性;
this.age= age;
}
Person.info= 'aaa' // info属性直接挂载给构造函数,称为静态属性
// 将实例方法挂载到Person的原型对象上
Person.prototype.say = function () {
console.log('这是Person的实例方法')
}
// 静态方法,实例的对象无法访问该方法,只能通过 Person.show() 进行访问,使用的少
Person.show= function () {
console.log('这是Person的静态方法')
}
// 实例化一个对象
const p1= new Person('大黑', '2')
console.log(p1.name) // name 是 Person 的实例属性
console.log(Person.info) // info 是 Person 的静态属性
Person.say() // say 是 Person 的实例方法
// 2.使用class关键字创建类
class Animal {
constructor () (name, age) {
this.name= name; // 实例属性
this.age= age;
}
// 在class内部,通过static关键字修饰出来的属性就是静态属性;
static info= 'hahh';
// 此处也是将实例方法挂载到Person的原型对象上
eating () {
console.log('这是Animal的实例方法')
}
// 静态方法使用static关键字,使用的少
static playing () {
console.log('这是Animal的静态方法')
}
}
const p2= new Person('小灰', '1')
console.log (p2)
console.log(p2.name) // name 是 Animal 的实例属性
console.log(Animal.info) // info 是 Animal 的静态属性
p2.eating() // eating 是 Animal 的实例方法
2.10.class-实例方法和静态方法(见上方)
2.11.class-总结class的基本用法和两个注意点
注意点1:在class内部只能写
构造器、静态属性、静态方法、实例方法
四种(实例属性在构造器中);注意点2:class关键字内部还是用原来的方法实现的,因此把class关键字称为
语法糖
;
2.13.class-使用extends实现子类继承父类
2.13.1 代码案例
class American {
constructor (name ,age) {
this.name= name;
this.age= age;
}
}
const a1= new American('sara', '21')
class China {
constructor (name ,age) {
this.name= name;
this.age= age;
}
}
const c1= new China('wang', '21')
// 上面由于两个类的属性相同,可以通过创建一个父类
class Person {
constructor (name ,age) {
this.name= name;
this.age= age;
}
}
// 在class类中使用extends关键字,实现子类继承父类,如下:
class American2 extends Person {
}
class China2 extends Person {
}
const a2= new American2('jack', '21') // 会自动执行父类中的构造函数
const c2= new China2('huang', '20')
2.14.class-子类访问父类上的实例方法
2.14.1 代码案例
// 创建一个父类
class Person {
// 子类会继承父类的构造函数
constructor (name ,age) {
this.name= name;
this.age= age;
}
// 父类中的实例方法,作为公共的方法
say () {
console.log('say hello')
}
}
// 在class类中使用extends关键字,实现子类继承父类,如下:
class American2 extends Person {
}
class China2 extends Person {
}
const a2= new American2('jack', '21') // 会自动执行父类中的构造函数
a2.say() // 调用父类中的实例方法
const c2= new China2('huang', '20')
2.15.class-constructor构造器中super函数的使用说明
2.15.1 问题讨论及代码案例
-
为什么一定要在
constructor
中调用super()
?- 若一个子类通过
extends
关键字继承了父类,那么子类构造器函数constructor()
中,必须调用super()
- 若一个子类通过
-
super()
有什么作用?-
super()
是一个函数,是父类的构造器,子类中的super()
就是父类中的构造器constructor()
的引用;
-
-
super()
中参数为空且没有执行的代码时,实例的对象并不会继承父类中的构造器函数中的实例属性?-
super()
作为父类中的构造器constructor()
的引用,因此必须需要传递参数,因而才能正确的调用父类中的构造器函数;
-
// 创建一个父类
class Person {
// 子类会继承父类的构造函数
constructor (name ,age) {
this.name= name;
this.age= age;
}
// 父类中的实例方法,作为公共的方法
say () {
console.log('say hello')
}
}
// 在class类中使用extends关键字,实现子类继承父类,子类中实现构造器时,一定要加入`super()`方法并传递参数:
class China3 extends Person {
constructor (name ,age) {
super (name ,age)
}
}
const c3= new China3('huang', '20')
2.16.class-为子类挂载独有的实例属性和实例方法
2.16.1 代码案例
// 创建一个父类
class Person {
// 子类会继承父类的构造函数
constructor (name ,age) {
this.name= name;
this.age= age;
}
// 父类中的实例方法,作为公共的方法
say () {
console.log('say hello')
}
}
// 在class类中使用extends关键字,实现子类继承父类,子类中实现构造器时,一定要加入`super()`方法并传递参数,IdNumber参数是中国人独有的,因而不能挂载到父类上:
class China3 extends Person {
constructor (name ,age, IdNumber) {
super (name ,age)
// 单独在子类中使用this进行绑定;注意在子类中,this只能放在super()后面;
this.IdNumber= IdNumber;
}
}
const c3= new China3('li', '20', '513*********')
2.17.使用class关键字创建组件
2.17.1 基本的class创建组件的语法
// 使用class创建组件,必须要自己的组件继承自 React.Component
class 组件名称 extends React.Component {
// 在组件内部,必须要这个 render() 函数,该函数的作用是渲染当前组件对应的虚拟DOM结构
render () {
// render() 函数必须返回合法的JSX虚拟DOM结构
return 这是class创建的组件