文章目录
前言
React :官方地址
一、React 脚手架
方法一:
- 全局安装:npm i create-react-app -g
- 创建项目:create-react-app project-react
★ 方法二:不需要安装直接复制命令执行(每次使用的时候都是最新的脚手架创建项目)
使用npx安装:npx create-react-app project-react
二、React 使用
-
导入
react
react-dom
react
:规定了 react 的核心语法
react-dom
:规定了 react 如何进行 DOM 操作在index.js中:(在vue中相当于main.js文件)
// 创建react元素 import React from "react"; // 把react元素渲染到页面 import ReactDom from "react-dom";
-
使用
react
创建 react 元素// 例:<h1 id="el">React! </h1> // React.createElement(标签名,{标签的属性对象},子级元素) const h1 = React.createElement('h1',{ id:'el' },'你好,React!')
-
使用
react-dom
渲染 react元素// #root 在public/index.html上 // ReactDoM.render(react元素,挂载的节点,回调函数) ReactDom.render(element,document.getElementById('root'));
-
将src内文件删除 创建
src/index.js
三、React 创建元素练习
<div class="list">
<h1>水果</h1>
<ul>
<li>苹果</li>
<li>香蕉</li>
<li>西瓜</li>
</ul>
</div>
↓↓↓
const h1 = React.createElement('h1',null,'水果')
const li1 = React.createElement('li',null,'苹果')
const li2 = React.createElement('li',null,'香蕉')
const li3 = React.createElement('li',null,'西瓜')
const ul = React.createElement('ul',null,[li1,li2,li3])
const div = React.createElement('div',{ className:'list' },[h1,ul])
ReactDom.render(div,document.getElementById('root'))
↓↓↓
const div = React.createElement('div',{ className:'list' },[
React.createElement('h1',null,'水果'),
React.createElement('ul',null,[
React.createElement('li',null,'苹果'),
React.createElement('li',null,'香蕉'),
React.createElement('li',null,'西瓜')
])
])
ReactDom.render(div,document.getElementById('root'))
四、JSX 使用
JSX 是 Javascript XML 的简写,表示了在JavaScript 中书写 XML格式的代码。它是 React 的核心内容,它可以让我们在 React中创建元素更加简单,更加直观,提高开发效率。
JSX 是 Javascript 的语法扩展,它无法在浏览中直接使用,在create-react-app 脚手架中内置了 @babel/plugin-transform-react-jsx 插件来解析它,成为 Javascript 的标准语法。
可以使用 Babel 在线测试
总结:JSX就是JS的扩展语法,可以在JS中书写XML语法,它可以更加简洁、直观、高效的声明UI界面
在vscode 中加上在react 中使用 ement 语法提示创建标签
"emmet.includeLanguages":{
"javascript": "javascriptreact"
}
JSX写法:
- 导入
react-dom
- 使用
JSX
创建元素 - 使用
react-dom
渲染
import React from "react";
import ReactDom from "react-dom";
// 属性绑定:key={变量}
const div = (<div class="list">
<h1>水果</h1>
<ul>
<li key={1}>苹果</li>
<li key={2}>香蕉</li>
<li key={3}>西瓜</li>
</ul>
</div>)
ReactDom.render(div,document.getElementById('root'))
注意事项:
1:class 变成 className;label的 for 属性变成 htmlFor;多个单词组成的属性变成驼峰命名
2:标签的嵌套一定要符合规范
3:标签一定要闭合(特别注意单标签,比如:img,hr,br,input)
4:只有一个根标签,要不然就使用 <React.Fragment></React.Fragment> 或者 <></>
5:建议多行用()包裹
五、JSX 嵌入表达式
六、JSX 条件渲染方式
const loading = true;
{/* 方法一:if/else 条件渲染 */}
const getContent =()=> {
if (loading) {
return (<div>数据正在加载中...</div>)
} else {
return (<div>数据加载完成</div>)
}
}
const div = (
<>
{ getContent() }
<hr/>
{/* 方法二:三元表达式 */}
{ loading ? <div>数据正在加载中...</div> : <div>数据加载完成</div>}
{/* 方法三:逻辑运算符 */}
<hr/>
{ loading && <div>数据正在加载中...</div>}
{ loading || <div>数据正在加载中...</div>}
</>
)
ReactDom.render(div,document.getElementById('root'))
七、JSX 列表渲染
在JSX中可以直接渲染数组,但是对象需要转换一下,数组中的每个元素会被当成React元素去渲染
使用 map()函数 渲染数组
const list = [
{id:100,name:'tom',age:15 },
{id:101,name:'jack',age:18 },
{id:102,name:'tony',age:20},
]
const div = (
<>
<ul>
{/* 布尔值不会直接展示 react不能直接渲染展示对象 */}
{ list.map(item => {
return (
<li key={item.id}>
<p>姓名:{item.name}</p>
<p>年龄:{item.age}</p>
<p>是否成年:{item.age > 18 ? '是' : '否'}</p>
</li>
)
})
}
</ul>
</>
)
ReactDom.render(div,document.getElementById('root'))
八、JSX样式-style 操作
方式1:操作style
方式2:操作className
写法:style=“{ { 样式对象 } }”
九、JSX样式-className 方式
插件:vscode: ES7 React/Redux/GraphQL/React-Native snippets;idea: React snippets
十、案例
index.js
import React from "react";
import ReactDom from "react-dom";
import './index.css';
const dpl = (
<div className="comments">
<h3 className="comm-head">
热门评论<sub>(5)</sub>
</h3>
<ul className="comm-list">
<li className="comm-item">
<div className="avatar"></div>
<div className="info">
<p className="name vip">
清风徐来
<img src="https://gw.alicdn.com/tfs/TB1c5JFbGSs3KVjSZPiXXcsiVXa-48-48.png" />
</p>
<p className="time"> 2024-7-29 </p>
<p>
评论内容
</p>
</div>
</li>
</ul>
</div>
)
ReactDom.render(dpl,document.getElementById('root'))
index.css
body {
margin: 0;
}
.comments {
background-color: #121212;
color: #eee;
padding: 24px;
width: 100vw;
margin: 0 auto;
}
.comm-head {
color: #eee;
font-size: 24px;
line-height: 24px;
margin-bottom: 24px;
}
.comm-head sub {
font-size: 14px;
color: #666;
margin-left: 6px;
bottom: 0.2em;
position: relative;
}
.comm-list {
list-style: none;
padding: 0;
}
.comm-item {
display: flex;
margin-bottom: 24px;
}
.comm-item .avatar {
width: 48px;
height: 48px;
line-height: 48px;
border-radius: 24px;
display: inline-block;
cursor: pointer;
background-position: 50%;
background-size: 100%;
background-color: #eee;
}
.comm-item .info {
padding-left: 16px;
}
.comm-item .info p {
margin: 8px 0;
}
.comm-item .info p.name {
color: #999;
}
.comm-item .info p.vip {
color: #ebba73;
}
.comm-item .info p.vip img {
width: 14px;
vertical-align: baseline;
margin-left: 5px;
}
.comm-item .info p.time {
color: #666;
font-size: 14px;
}
.comm-item .info .del {
margin-left: 20px;
cursor: pointer;
}
.comm-item .info .del:hover {
color: #ccc;
}
.comm-input {
border-radius: 6px;
padding: 18px;
background-color: #25252b;
}
.comm-input textarea {
border: 0;
outline: 0;
resize: none;
background: transparent;
color: #999;
width: 100%;
font-family: inherit;
height: auto;
overflow: auto;
}
.comm-input .foot {
display: flex;
justify-content: flex-end;
justify-items: center;
}
.comm-input .foot .word {
line-height: 36px;
margin-right: 10px;
color: #999;
}
.comm-input .foot .btn {
background-color: #ff008c;
font-size: 14px;
color: #fff;
line-height: 36px;
text-align: center;
border-radius: 18px;
padding: 0 24px;
cursor: pointer;
user-select: none;
}
效果
数据如下:
const comments = [
{
id: 100,
name: '__RichMan',
avatar: 'https://r1.ykimg.com/051000005BB36AF28B6EE4050F0E3BA6',
content: '这阵容我喜欢😍靳东&闫妮,就这俩名字,我就知道是良心剧集...锁了🔒',
time: '2021/10/12 10:10:23',
vip: true,
},
{
id: 101,
name: '糖蜜甜筒颖',
avatar:
'https://image.9xsecndns.cn/image/uicon/712b2bbec5b58d6066aff202c9402abc3370674052733b.jpg',
content:
'突围神仙阵容 人民的名义第三部来了 靳东陈晓闫妮秦岚等众多优秀演员实力派 守护人民的财产 再现国家企业发展历程',
time: '2021/09/23 15:12:44',
vip: false,
},
{
id: 102,
name: '星星',
avatar: 'https://static.youku.com/lvip/img/avatar/310/6.png',
content:
'第一集看的有点费力,投入不了,闫妮不太适合啊,职场的人哪有那么多表情,一点职场的感觉都没有',
time: '2021/07/01 00:30:51',
vip: true,
},
];
转换后
const dpl = (
<div className="comments">
<h3 className="comm-head">
热门评论<sub>({comments.length})</sub>
</h3>
<ul className="comm-list">
{ comments.map(item => {
return (
<li className="comm-item" key={item.id}>
<div className="avatar" style={ { backgroundImage: `url(${item.avatar})`} }></div>
<div className="info">
<p className="name vip">
{item.name}
{item.vip ? <img src="https://gw.alicdn.com/tfs/TB1c5JFbGSs3KVjSZPiXXcsiVXa-48-48.png" /> : ''}
</p>
<p className="time"> {item.time} </p>
<p>
{item.content}
</p>
</div>
</li>
)
})}
</ul>
</div>
)
效果