目录
0_前置知识
1、类的回顾
2、this 指向
3、yarn 包管理工具
3.1 npm的缺陷
3.2 yarn 特点
3.3 yarn下载
3.4 yarn 常用命令
1_React 概述
1、学习目标
2、React 介绍
2.1 react特点
2.2 虚拟DOM
3、React 脚手架(CLI)
3.1 React 脚手架的介绍
3.2 使用 React 脚手架创建项目
3.3 项目目录结构说明和调整
4、React 的基本使用
4.0 原始方式使用
4.1 基本步骤
4.2 示例
2_JSX
0、什么是 JSX
1、学习目标
2、JSX的基本使用
2.1 createElement的问题
2.2 JSX注意点
2.3 嵌入JavaScript表达式
2.4 嵌入算数表达式
2.5 嵌入条件表达式
2.6 嵌入函数表达式
2.7 嵌入对象表达式
2.8 嵌入数组表达式
2.9 防止注入攻击
2.10 JSX中的注释
3_条件渲染
4_列表渲染
5_样式处理
1、行内样式-style
2、类名-className
3、外部样式
4、练习
5、总结
class Animal {
static id = 1;
constructor(name){
this.name = name;
}
getName() {
return this.name;
}
//getter获取类的名字
get computedName() {
return this.name + Animal.id;
}
// setter
set computedName(name){
this.name = name;
}
}
console.log(Animal.id); // 1
let animal = new Animal('zs');
console.log(animal); // zs
console.log(animal.getName()); // zs
console.log(animal.computedName); // zs1
animal.computedName = 'ls';
console.log(animal.name); // ls
console.log(animal.computedName); // ls1
class Animal {
static id = 1;
constructor(name){
this.name = name;
}
getName() {
return this.name;
}
//getter获取类的名字
get computedName() {
return this.name + Animal.id;
}
// setter
set computedName(name){
this.name = name;
}
}
class Dog extends Animal {
constructor(name){
super(name)
}
getName(){
return this.name + '123'
}
}
let dog = new Dog('泰迪');
console.log(dog.name); // 泰迪
console.log(dog.getName()); // 泰迪 -- >泰迪123
dog.computedName = '柯基';
console.log(dog.computedName);// 柯基1
console.log(dog.computedName);// 柯基1
const obj = {
name: 'zs',
getName(){
return this.name
}
}
const obj1 = {
name: 'ls'
}
console.log(obj.name); // zs
console.log(obj.getName()); // zs
console.log(obj.getName.call(obj1)); // ls
console.log(obj.getName.apply(obj1)); // ls
console.log(obj.getName.bind(obj1)()); // ls
const obj = {
name: 'zs',
getName(num,age){
return this.name + num + age
}
}
const obj1 = {
name: 'ls'
}
console.log(obj.name); // zs
console.log(obj.getName()); // zs
console.log(obj.getName.call(obj1, 2,6)); // ls26
console.log(obj.getName.apply(obj1, [5,0])); // ls50
console.log(obj.getName.bind(obj1)(3,18)); // ls318
示例:
function Cat() {
let showName = function () {
console.log(1);
}
return this;
}
Cat.showName = function(){
console.log(2);
}
Cat.prototype.showName = function(){
console.log(3);
}
var showName = function () {
console.log(4);
}
function showName() {
console.log(5);
}
Cat.showName(); // 2 访问的是函数的静态属性
showName(); // 4 函数优先提升,var变量提升后赋值将原来的函数覆盖掉了
Cat().showName(); // 4 Cat()函数返回了this指向的是window,全局var定义的变量是在window上的
new Cat.showName(); // 2 new 实例化的是Cat里面的静态属性 showName
new Cat().showName(); // 3 实例化的是 Cat 实例,访问的是cat实例的方法showName()
下载包的时候速度很慢,需要安装淘宝镜像
同一个项目,安装的时候无法保持包的一致性,package.json 文件中包含了包的名字与版本,安装依赖时依赖的版本不一致可能,就会导致项目运行时报错(package-lock.json已经解决)
下载安装依赖的时候可能会报错,但是npm会继续下载和安装,从而导致项目运行起来后导致定位错误
快速性:会缓存下载过的包,这样下次再下载相同的包的时候会直接从缓存中下载,节省了下载的时间
安全性:在执行代码之前,yarn会通过算法去校验每个安装包的完整性
可靠性:yarn有一个锁文件和明确的安装算法,yarn安装的包能在不同系统上运行
并行安装:无论npm还是yarn在完整的时候,都会执行一系列任务,npm是按照队列的方式执行、yarn是同步执行,从而提高了性能
安装版本统一:为了防止拉取到不同的版本,yarn有一个yarn.lock文件,其中纪录了安装包的确切的版本号,每次只要更新或新增了一个包,yarn.lock就会进行同步
更简介的输出:yarn的输出信息更简介的输出信息,而npm输出的信息比较冗长
npm i -g yarn 安装 yarn --version 查看版本
查看yarn配置:
yarn config list
yarn安装淘宝镜像:
yarn config set registry http://registry.npm.taobao.org/ // 配置 node-sass 的二进制包镜像地址 yarn config set sass_binary_site http://cdn.npm.taobao.org/dist/node-sass -g
//初始化项目 yarn init -y //下载包 yarn add xxx 默认安装到 dependencies 里 yarn add xxx@yyy 默认安装到 dependencies 里 yarn add -D/--dev 安装到 devDependencies 里 //删除包 yarn remove xxx yarn remove xxx@yyy
能够说出react是什么
能够说出react的特点
能够掌握react的基本用法
能够使用react脚手架
react是一个用于构建用户界面的 JavaScript 库
react官网(React – A JavaScript library for building user interfaces)
react中文网(React 官方中文文档 – 用于构建用户界面的 JavaScript 库)
React 是一个用于构建用户界面(UI,对咱们前端来说,简单理解为:HTML 页面)的 JavaScript 库
Vue 是一个渐进式的 JavaScript 框架
如果从mvc的角度来看,React仅仅是视图层(V)的解决方案。也就是只负责视图的渲染,并非提供了完整了M和C的功能
react/react-dom/react-router/redux: 框架
React 起源于 Facebook 内部项目(News Feed,2011),后又用来架设 Instagram 的网站(2012),并于 2013 年 5 月开源react介绍
React 是最流行的前端开发框架之一,其他:Vue、Angular 等等框架对比
声明式UI:
你只需要描述UI(HTML)看起来是什么样的,就跟写HTML一样
const jsx =
Hello React! 动态数据变化:{count}
声明式对应的是命令式,声明式关注的是what,命令式关注的是how
组件化:
组件是react中最重要的内容
组件用于表示页面中的部分内容
组合、复用多个组件,就可以实现完整的页面功能
学习一次,随处使用:
使用react/rect-dom可以开发Web应用
使用react/react-native可以开发移动端原生应用(react-native) RN 安卓 和 ios应用 flutter
使用react可以开发VR(虚拟现实)应用(react360)
总结:
声明式设计,react采用声明范式,能够轻松的描述应用
高效 :react提供了虚拟DOM,最大程度地减少了与DOM之间的交互
灵活:react可以和任意的库进行搭配使用
在 react 中每个DOM对象都会有一个对应的虚拟DOM,以js对象的方式描述的真实的DOM对象
12
45
{
type: 'div',
props: { className: 'container' },
children: [{
type: 'h3',
props: null,
children: [{
type: 'text',
props: {
textContent" '12'
},
}]
},{
type: 'p',
props: null,
children: [{
type: 'text',
props: {
textContent" '45'
},
}]
}]
}
虚拟DOM如何提升效率:
精准找出发生变化的DOM,只更新变化的部分
在第一次创建DOM时,就会给每个DOM对象创建虚拟DOM,更新时就会更新虚DOM,然后将更新的前后的虚拟DOM进行对比,从而找到发生变化的部分,将发生变化的部分更新到真实的DOM对象中,从而达到性能提升
React 脚手架的介绍
使用 React 脚手架创建项目
项目目录结构调整
脚手架:为了保证各施工过程顺利进行而搭设的工作平台
对于前端项目开发来说,脚手架是为了保证前端项目开发过程顺利进行而搭设的开发平台
脚手架的意义:
现代的前端开发日趋成熟,需要依赖于各种工具,比如,webpack、babel、eslint、sass/less/postcss等
工具配置繁琐、重复,各项目之间的配置大同小异
开发阶段、项目发布,配置不同
项目开始前,帮你搭好架子,省去繁琐的 webpack 配置
项目开发时,热更新、格式化代码、git 提交时自动校验代码格式等
项目发布时,一键自动打包,包括:代码压缩、优化、按需加载等
命令:npx create-react-app react-basic
npx create-react-app 是固定命令,create-react-app
是 React 脚手架的名称
react-basic 表示项目名称,可以修改
启动项目:yarn start
or npm start
npx
是 npm v5.2 版本新添加的命令,用来简化 npm 中工具包的使用
原始:1 全局安装npm i -g create-react-app
2 再通过脚手架的命令来创建 React 项目
现在:npx 调用最新的 create-react-app 直接创建 React 项目
public/index.html:相当于html模板文件,react最终会将模板挂载到html中的div元素上
src
App.js:项目的根组件,相当于vue中的app.vue
index.js:项目的入口文件,相当于vue中的main.js
npm run start:启动项目,开服
npm run build:项目打包生产包
npm run eject:项目中的一些配置被隐藏起来了,通过这个命令可以将配置文件反编译到项目中,从而获得配置的权利,这个操作是不可逆的,一旦编译出来就无法编译回去,一般来说不会执行这个命令,我们会通过其他方式去修改配置。
说明:
src
目录是我们写代码进行项目开发的目录
查看 package.json
两个核心库:react
、react-dom
(脚手架已经帮我们安装好,我们直接用即可)
调整:
删除 src 目录下的所有文件
创建 index.js 文件作为项目的入口文件,在这个文件中写 React 代码即可
初始化项目
yarn init -y
安装相关的核心包
yarn add react react-dom babel-standalone
react:react核心包
react-dom:与操作DOM相关功能的核心包
babel-standalone:由babel编译器提供的js文件,可以将es6代码转换成es5代码
Document
React.createElement:创建react模板
ReactDOM.render:将模板渲染到哪个标签上去
Document
通过对比,我们发现jsx的写法比上面写法更加的直观,层次结构更加清晰,写法更简单,让你联想大html主功能写DOM元素
babeljs官网:Babel 中文网 · Babel - 下一代 JavaScript 语法的编译器
jsx最终会转换成React.createElement的方式去创建模板,jsx只是降低了开发难度
使用步骤
- 导入react和react-dom - 创建react元素(虚拟DOM) - 渲染react元素到页面中
导入react和react-dom
// 导入react和react-dom import React from 'react' import ReactDOM from 'react-dom'
创建react元素
// 创建元素 const title = React.createElement('h1', null, 'hello react')
渲染react元素到页面
// 渲染react元素 ReactDOM.render(title, document.getElementById('root'))
使用react,生成以下结构
这是一个react案例
生成结构2
- 香蕉
- 橘子
- 苹果
小结:
能够说出react是什么
是用于构建用户界面的javascript库
能够说出react的特点
声明式ui
组件化
一处学习,多次使用 react-dom react-native
能够掌握react的基本用法
能够使用react脚手架
yarn global add create-react-app
网络标签语言有两种,HTML、XML
HTML:是网页的布局,更多的用语内容的呈现
XML:可扩展的标签原因,可以写任意的标签,核心功能是用于数据的传输
JSX=JavaScript+XML,是JavaScript和XML的结合,可以说是JavaScript的一种扩展语法,可以在jsx中写js代码,也可以写html中DOM元素,在jsx中拥有js的所有的语法。
使用jsx语法的特点:
jsx执行更快,因为它在编译成JavaScript代码后进行了优化
jsx是类型安全的,在编译过程中就可以发现错误,可以注入攻击
使用jsx编写代码更加的简单快捷
能够知道什么是jsx
能够使用jsx创建react元素
能够在jsx中使用javascript表达式 {}
能够使用jsx的条件渲染和列表渲染
能够给jsx添加样式
繁琐不简洁
不直观,无法一眼看出所描述的结构
不优雅,开发体验不好
只有在脚手架中才能使用jsx语法
因为JSX需要经过babel的编译处理,才能在浏览器中使用。脚手架中已经默认有了这个配置。
JSX必须要有一个根节点, <>>
没有子节点的元素可以使用/>
结束
JSX中语法更接近与JavaScript
class
=====> className
for
========> htmlFor
JSX可以换行,如果JSX有多行,推荐使用()
包裹JSX,防止自动插入分号的bug
使用prettier插件格式化react代码:
安装插件
添加prettier的配置
// 保存到额时候用使用prettier进行格式化
"editor.formatOnSave": true,
// 不要有分号
"prettier.semi": false,
// 使用单引号
"prettier.singleQuote": true,
// 默认使用prittier作为格式化工具
"editor.defaultFormatter": "esbenp.prettier-vscode",
在jsx中可以在
{}
来使用js表达式
在jsx中,要嵌入js表达式,使用单花括号{}
, 那么也就意味着在单花括号中可以写js表达式
let title = '学苑';
function App() {
return (
{title}
);
}
export default App;
可以在jsx嵌入表达式中写算数表达式,包括加减乘除
let title = '学苑';
let num1 = 1;
let num2 = 2;
function App() {
return (
{num1 + num2}
);
}
export default App;
在jsx的嵌入表达式中,条件判断语句只能写三目运算符,不能写if/else、switch/case条件判断语句,一旦写上条件判断语句后会报错
let age = 18
function App() {
return (
{age >= 18 ? '成年' : '未成年'}
);
}
export default App;
在jsx中可以将函数直接运行。
let age = 17
function isAdult() {
if (age >= 18) {
return '成年'
} else {
return '未成年'
}
}
function App() {
return (
{isAdult()}
);
}
export default App;
let user = {
name: '张三',
age: 20
}
function App() {
return (
{user}
);
}
export default App;
在jsx嵌入表达式中直接渲染对象数据会报错,报错如下:
正确方式应该将对象中的每个数据进行渲染,而不是渲染整个对象:
let user = {
name: '张三',
age: 20
}
function App() {
return (
姓名:{user.name}
年龄:{user.age}
);
}
export default App;
数组有点特殊,可以直接放入进行渲染,通常在元素中循环渲染一个数组,用.map
,相当于vue中的v-for
// let students = [张三
, 李四
, 王五
];
let students = ['张三', '李四', '王五']
function App() {
return (
{
students.map(item => {
return {item}
})
}
);
}
export default App;
你也可以用其他方式去实现:
// let students = [张三
, 李四
, 王五
];
let students = ['张三', '李四', '王五']
function getStudents() {
let res = [];
students.forEach(item => {
res.push({item}
);
});
return res;
}
function App() {
return (
{
getStudents()
}
);
}
export default App;
但是,我们推荐使用.map
方式
let str = "学苑
"
let value = {
__html: str
}
function App() {
return (
);
}
export default App;
在jsx中,字符串里面的标签不会被解析成真实的DOM元素,而是当做字符串进行渲染,如果你要将字符串中的标签解析成真实的DOM元素,你需要创建一个对象
let value = { __html: str }
其中__html
字段是固定的
创建完毕后,需要在元素上给一个属性dangerouslySetInnerHTML
去进行解析
{/* 这是jsx中的注释 */} 推荐快键键 ctrl + /
不要出现语句,比如if
for
{/* {title} */}
在react中,一切都是javascript,所以条件渲染完全是通过js来控制的
通过判断if/else
控制
const isLoding = false
const loadData = () => {
if (isLoding) {
return 数据加载中.....
} else {
return 数据加载完成,此处显示加载后的数据
}
}
const title = 条件渲染:{loadData()}
通过三元运算符控制
const isLoding = false
const loadData = () => {
return isLoding ? (
数据加载中.....
) : (
数据加载完成,此处显示加载后的数据
)
}
逻辑运算符
const isLoding = false
const loadData = () => {
return isLoding && 加载中...
}
const title = 条件渲染:{loadData()}
vscode配置自动补全:
// 当按tab键的时候,会自动提示 "emmet.triggerExpansionOnTab": true, "emmet.showAbbreviationSuggestions": true, // jsx的提示 "emmet.includeLanguages": { "javascript": "javascriptreact" }
我们经常需要遍历一个数组来重复渲染一段结构
在react中,通过map方法进行列表的渲染
列表的渲染
const songs = ['温柔', '倔强', '私奔到月球']
const list = songs.map(song => {song} )
const dv = (
{list}
)
直接在JSX中渲染
const songs = ['温柔', '倔强', '私奔到月球']
const dv = (
{songs.map(song => - {song}
)}
)
key属性的使用
const dv = (
{songs.map(song => (
- {song}
))}
)
注意:列表渲染时应该给重复渲染的元素添加key属性,key属性的值要保证唯一
注意:key值避免使用index下标,因为下标会发生改变
const dv = (
style样式
)
注意:行内样式写法style={{key: value}}
第一层{}
:嵌入jsx表达式
第二层{}
:代表js的对象
在style样式中,如果样式带有横岗-
,应使用驼峰的方式去书写
// 导入样式
import './base.css'
const dv = style样式
base.css样式文件
.title {
text-align: center;
color: red;
background-color: pink;
}
创建css文件 App.css
.color {
color: red;
}
.bg-color {
background-color: blue;
}
在App.js引入样式
import './App.css';
使用样式
import './App.css';
let title = '学苑'
function App() {
return (
{title}
);
}
export default App;
注意:绑定class样式时应该使用
className
,不要使用class,因为class是js中的关键字。
const list = [ { id: 1, name: "刘德华", content: "给我一杯忘情水" }, { id: 2, name: "五月天", content: "不打扰,是我的温柔" }, { id: 3, name: "毛不易", content: "像我这样优秀的人" } ];
参考示例:
App.js
import './base.css'
const list = [{
id: 1,
name: "刘德华",
content: "给我一杯忘情水"
},
{
id: 2,
name: "五月天",
content: "不打扰,是我的温柔"
},
{
id: 3,
name: "毛不易",
content: "像我这样优秀的人"
}
];
function render() {
if(list.length === 0){
return 暂无数据;
}
return (
{
list.map(item => (
-
评论人:{item.name}
评论内容:{item.content}
))
}
)
}
function App() {
return (
{render()}
)
}
export default App
JSX是React的核心内容
JSX表示在JS代码中书写HTML结构,是React声明式的体现
使用JSX配合嵌入的JS表达式,条件渲染,列表渲染,可以渲染任意的UI结构
结果使用className和style的方式给JSX添加样式
React完全利用JS的语言自身的能力来编写UI,而不是造轮子增强HTML的功能。(对比VUE)