JSX语法简介
JSX是js的一个高级语法,在运行时通过Babel转换为低版本的代码,使用JSX语法的主要目的是为了编程的逻辑更清晰和快速,提升代码可读性和性能。
下图解释了JSX编译的过程
基本使用
新建一个01-HwlloWorld.html文件,内容如下,我们使用JSX语法在页面输出一句“Hello World”
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>hello</title>
</head>
<body>
<div id="app">
</div>
<script src="https://cdn.bootcss.com/react/16.8.0/umd/react.production.min.js"></script>
<script src="https://cdn.bootcss.com/react-dom/16.8.0/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
//react代码写在这里
//获取元素
const con=document.getElementById("app");
// 创建虚拟DOM
const Vh1=<h1>你好世界</h1>;
// 渲染
ReactDOM.render(Vh1,con);
</script>
</body>
</html>
- 获取元素,在
body
中添加一个id
为app
的div
,使用原生js获取它,这个div
是React渲染DOM的容器
//获取元素
const con=document.getElementById("app");
- 使用JSX语法创建虚拟DOM,
JSX语法的写法又像js又像html,它是是一个 JavaScript 的语法扩展,能帮我们很容易的操作DOM
// 创建虚拟DOM
const Vh1=<h1>你好世界</h1>
- 使用
ReactDOM.render()
方法,将创建的虚拟DOM渲染到app中
ReactDOM.render()
方法接收两个参数:要渲染的虚拟DOM和虚拟DOM渲染到哪个容器,我们将刚刚创建的Vh1
渲染到app
中
// 渲染
ReactDOM.render(Vh1,con);
- 用浏览器运行html文件,即可看到效果
多重嵌套
JSX语法规定:多重嵌套需要一个外部容器将嵌套元素包裹
开发时,我们很少只在页面输出一句话。大多时多个元素的嵌套,下面演示一下如何使用JSX渲染嵌套元素
我们想在页面输出一段文章和一个标题
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>JSX多重节点</title>
</head>
<body>
<div id="app">
</div>
<script src="https://cdn.bootcss.com/react/16.8.0/umd/react.production.min.js"></script>
<script src="https://cdn.bootcss.com/react-dom/16.8.0/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
let con=document.getElementById("app");
ReactDOM.render(
<div className="box">
<h2>我是文章标题</h2>
<p>我是文章内容,需要用一个外部容器将多个元素包裹一并插入ReactDOM.render()函数</p>
</div>
,con)
</script>
解释一下上面的代码,h2
是标题 p
标签是段落,但是为什么外面加了<div className=‘box’></div>
呢?
这是因为JSX的语法规定:在 ReactDOM.render()
函数内插入的必须是一个整体
所以必须用一个外部容器将h2
和p
标签包裹起来
而className="box"
是给外面的容器div加了一个class
名为box
,便于我们去设置css样式。
当然你也可以用一个变量将虚拟DOM保存再插入ReactDOM.render()
函数渲染也是一样的,这样代码看起来更简洁
你也可以继续添加其他元素,在这里就不再添加了,原理都是一样的。
<script type="text/babel">
let con=document.getElementById("app");
let vDom= <div className="box">
<h2>我是文章标题</h2>
<p>我是文章内容,需要用一个外部容器将多个元素包裹一并插入ReactDOM.render()函数</p>
</div>;
ReactDOM.render(VDom,con )
</script>
打开浏览器运行一下,效果如下
运行效果图:
JSX语法中使用变量和表达式
JSX语法规定:在JSX中使用表达式时:变量和表达式都要写在{ }
中
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>变量和表达式</title>
</head>
<body>
<div id="app">
</div>
<script src="https://cdn.bootcss.com/react/16.8.0/umd/react.production.min.js"></script>
<script src="https://cdn.bootcss.com/react-dom/16.8.0/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
let con=document.getElementById("app");
const bookName="《React从入门到精通》";
ReactDOM.render(
<div className="box">
<p>{bookName}</p>
<span>春节特价只需要:{100*3+2-60/6} 元</span>
</div>
,con)
</script>
</body>
上面的代码中,书名bookName
是一个变量,将其作为p
b标签的文本内容,使用{}
包起来,而下面的数的价格 {100*3+2-60/6}
则是一个计算表达式,也用{}
括起来
注意:{}
内只能放变量和表达式,不能放语句,如 if(...){..}
for(...){...}
都是语句,不能放在JSX里面的{}
里
使用浏览器运行结果如下
JSX中使用行内样式
JSX语法规定:JSX中通过对象的方式引入行内样式
接着说上面的案例,我们想给书名和价格加个css样式的话,就需要以对象字面量的方式加入
为了效果更好,我又添加了一个img
标签作为书的封面
所有代码如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>内联样式</title>
</head>
<body>
<div id="app">
</div>
<script src="https://cdn.bootcss.com/react/16.8.0/umd/react.production.min.js"></script>
<script src="https://cdn.bootcss.com/react-dom/16.8.0/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
const nameStyle={
backgroundColor:"#a7493f",
color:"#1b1b1b",
padding:"10px",
margin:"15px",
borderRadius:"2px",
fontSize:"20px",
color:"#fff"
};
const priceStyle={
display:"block",
color:"#e4393c",
fontSize: "16px",
padding:"10px",
};
const bookName="《React快速上手开发》";
ReactDOM.render(
<div className="box">
<p style={nameStyle}>{bookName}</p>
<img src="https://img10.360buyimg.com/n1/s200x200_jfs/t3064/316/9231779272/336570/ce323f93/58d0d62bNd25db840.jpg" alt=""/>
<span style={priceStyle}>春节特价只需要:{100*3+2-60/6} 元</span>
</div>,document.getElementById("app"))
</script>
</body>
</html>
解释一下上面的代码
nameStyle
和priceStyle
是书的标题和价格的样式,安照JSX的语法,必须是对象形式,且使用驼峰命名法
const nameStyle={
backgroundColor:"#a7493f",
color:"#1b1b1b",
padding:"10px",
margin:"15px",
borderRadius:"2px",
fontSize:"20px",
color:"#fff"
};
const priceStyle={
display:"block",
color:"#e4393c",
fontSize: "16px",
padding:"10px",
};
在JSX语法中,设置行内样式通过style
属性,其值是一个对象
<p style={nameStyle}>{bookName}</p>
中的nameStyle
就是我们刚刚定义的对象样式变量,同样遵循JSX的语法规则,变量用{}括起
下面的<p style={nameStyle}>{bookName}</p>
原理是一样的
ReactDOM.render(
<div className="box">
<p style={nameStyle}>{bookName}</p>
<img src="https://img10.360buyimg.com/n1/s200x200_jfs/t3064/316/9231779272/336570/ce323f93/58d0d62bNd25db840.jpg" alt=""/>
<span style={priceStyle}>春节特价只需要:{100*3+2-60/6} 元</span>
</div>,document.getElementById("app"))
这里需要注意的是,JSX语法中,单标签必须闭合
如<img src="" alt="">
是不对的,应该加上/
,写成<img src="" alt="" />
其他单标签也是如此写法
上面的代码运行结果如下:
JSX数组遍历
数组遍历应该是开发中最常用的,JSX中数组遍历使用ES6的新数组方法map()
先说一下map()
方法
-
map可以简单的理解为映射,将原数组按照一定的规则映射到新的数组
-
map接收一个函数作为参数,该函数的有三个参数
value
,index
,arr
;依次为依次为当前的值
、当前值的下标
和原数组
,其中index
和arr
是可选参数 -
原数组的每一项会依次执行该函数
如下面将a1数组双倍存入b1
let a1=[1,2,3];
let b1=[];
b1=a1.map((item)=>{
return item*2
});
console.log(b1);
2
4
6
上面的代码,map里面的参数函数,遍历原数组的每一项,将该项乘2后返回出去,返回的项组成一个新的数组。
当然也可以不对数组的值处理,直接输出也可以,比如接下来的遍历
我们定义一个数组,里面存放了几组对象,用来遍历生成一个ul
标签
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>变量和表达式</title>
</head>
<body>
<div id="app">
</div>
<script src="https://cdn.bootcss.com/react/16.8.0/umd/react.production.min.js"></script>
<script src="https://cdn.bootcss.com/react-dom/16.8.0/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
const theArr=[
{name:"皮卡兔", age:22,},
{name:"皮卡丘", age:20,},
{name:"皮卡猫", age:20,},
{name:"皮卡猪", age:1,},
];
//>提示:使用()将vDom包裹起来提高代码的可读性
const vDom=(
<ul>
{
theArr.map((value,index)=>
<li key={index}>{index+1}----------姓名:{value.name}, ------年龄:{value.age}</li>
)
}
</ul>
);
ReactDOM.render(vDom,document.getElementById("app"))
</script>
</body>
</html>
上面的代码中,在ul
中通过map()
方法遍历输出theArr
的每一项,即value
,创建li
标签,另外li
标签的 key
属性是当前数组元素的下标,用来表示在内存中的唯一性
上面的代码运行结果如下
到这里,JSX的基础语法先告一段路,下面总结一下:
- JSX中添加属性时,使用
className
代替class
,像label
中的for
属性,使用htmlFor
代替 - JSX创建DOM的时候,所有的子节点必须有唯一的根元素进行包裹
- JSX语法中,标签必须成对出现,如果是单标签,则必须自闭合
- JSX中可以直接使用JS代码,直接在JSX中通过
{ }
中间写JS代码即可 - 在JSX中只能使用表达式,不能出现语句,变量和语句必须使用
{}
包裹才能在元素中做插值 - 在JSX语法中注释为
{/*注释的内容*/}
const VDOm=(
{/*我是对标题的注释*/}
<h2>我是标题</h2>
)