React
- react不能直接在浏览器运行,借助工具
React 安装
- react 快速构建工具
- CRA ( 全称create-react-app 流行、官方推荐、基础 )
- 全局:$ yarn add create-react-app global
- 临时:$ npx create-react-app 项目名称
- Dva
- Umi
- CRA ( 全称create-react-app 流行、官方推荐、基础 )
- 配置文件在node_modules中
使用yarn eject
抽离 注:抽离不可逆- react-scripts:包含运行和打包react应用程序的所有脚本和配置,从node_modules中抽离之后,会在项目根目录下生成两个文件
- comfig 配置文件
- scripts 运行脚本
- react-scripts:包含运行和打包react应用程序的所有脚本和配置,从node_modules中抽离之后,会在项目根目录下生成两个文件
├── README.md 使用方法的文档
├── node_modules 所有的依赖安装的目录
├── yarn-lock.json 锁定安装时的包的版本号,保证团队的依赖能保证一致。
├── package.json 项目依赖配置记录文件 、 记录项目脚本命令
├── public 静态公共目录( 生产环境 ) 不会被webpack编译
|-- config 项目webpack配置文件
|-- scripts 项目wepback脚本命令执行文件
└── src 开发用的源代码目录
- index.js 项目入口文件
- index.css 项目全局样式
- App.js 构建了一个App组件,是项目最大的组件 【 类似根组件 】
- App.css 是App组件的样式文件
- App.test.js 是App组件测试文件
- logo.svg 初始项目的界面logo
- serverWorker 内部文件,我们不操作
index.js
import React from 'react'
//引入react
import ReactDOM from 'react-dom'
//ReactDOM帮我们把React组件渲染到页面
ReactDOM.render(
<h1> 即将渲染的页面 </h1>,//一定要用 ',' 结束,否则会报错
document.querySelector('#root')//public文件夹下的index.html内的react作用域区块
)
jsx原理(js+xml)
html:
<div class='app' id='appRoot'>
<h1 class='title'>欢迎进入React的世界</h1>
<p>
React.js 是一个帮助你构建页面 UI 的库
</p>
</div>
js写法:
{
tag: 'div',
attrs: { className: 'app', id: 'appRoot'},
children: [
{
tag: 'h1',
attrs: { className: 'title' },
children: ['欢迎进入React的世界']
},
{
tag: 'p',
attrs: null,
children: ['React.js 是一个构建页面 UI 的库']
}
]
}
可以看出js写法又长结构也不清晰,于是react.js把js语法扩展了一下,让js能支持在js内写html结构语法,编译是把html语法转换成js的对象结构,这种我们叫做jsx结构
jsx:
import React from 'react'
import ReactDOM from 'react-dom'
class App extends React.Component {
render () {
return (
<div className='app' id='appRoot'>
<h1 className='title'>欢迎进入React的世界</h1>
<p>
React.js 是一个构建页面 UI 的库
</p>
</div>
)
}
}
ReactDOM.render(
<App />,
document.getElementById('root')
)
jsx编译之后:
import React from 'react'
import ReactDOM from 'react-dom'
class App extends React.Component {
render () {
return (
React.createElement(
"div",
{
className: 'app',
id: 'appRoot'
},
React.createElement(
"h1",
{ className: 'title' },
"欢迎进入React的世界"
),
React.createElement(
"p",
null,
"React.js 是一个构建页面 UI 的库"
)
)
)
}
}
ReactDOM.render(
React.createElement(App),
document.getElementById('root')
)
jsx注释
在jsx格式下无法正常使用js或html注释,在注释外层添加一个大括号,表示我们在要JSX里插入JS了
{ /* 要注释的内容 */ }
组件
如果我们要渲染的东西很多,就不能全都写在index.js内,是用组件的方式载入渲染
函数式组件(无状态组件 PureComponent)
//函数式组件写法
import React from 'react'
import ReactDOM from 'react-dom'
//组件名称首字母要大写,否则报错
//函数式组件返回值一定要为jsx格式,否则报错
//使用属性传值
//在单大括号内使用
const App = (props)=> {
return <h1> 这个组件是 { props.name } </h1>
}
ReactDOM.render(
<App name='函数式组件' />,
)
展示
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AeDp9j6Z-1572248878810)(F:\feiqd\three\1907\me\笔记\react用图\函数式组件.png)]
类组件(class组件)
每个组件创建单独的页面
在index.js内使用Comment.js规范引入
//类组件写法
//Ele.js
import React,{ Component,Fragment } from 'react'
//同时从react内引入多个模块,使用解构引入Component,Fragment
class Ele extends Component{
//Ele 继承 Component
render(porps){
return(//return的一定是jsx格式
//唯一根元素 Fragment
<Fragment>
<h1> 这个组件是:{ this.porps.name } </h1>
</Fragment>
)
}
}
export default Ele
//index.js
import React from 'react'
import ReactDOM from 'react-dom'
import Ele from './Ele'
ReactDOM.render(
<Ele name="类组件" />,
document.querySelector('#root')
)
展示
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9ZDONC5o-1572248878811)(F:\feiqd\three\1907\me\笔记\react用图\类组件.png)]
组件的组合与嵌套(vue slot)
- 组件的嵌套式指: 将子组件在父组件的jsx中以标签的形式使用
- 组件的组合是指:将一个组件写在另一个组件的内容中,然后在外层组件中通过 this.props.children来接收内容中的组件
- 但是我们推荐大家后面写的话可以使用嵌套
将一个组件渲染到某一个节点里的时候,会将这个节点里原有内容覆盖
组件嵌套的方式就是将子组件写入到父组件的模板中去,且react没有Vue中的内容分发机制(slot),所以我们在一个组件的模板中只能看到父子关系
每个组件只能有一个根节点,所以要再最外层包一个容器,如果使用div,会多渲染一层dom,所以使用react提供的Fragment组件在最外层包裹
class App extends Component {
render () {
return (
<Fragment>
<Title />
<Content />
</Fragment>
)
}
}
ReactDOM.render(
<App/>,
document.getElementById('root')
)
组件内的样式
一共4种
行内样式:给虚拟dom添加行内样式,需要用表达式传入样式对象来实现
// 注意这里的两个括号,第一个表示我们在要JSX里插入JS了,第二个是对象的括号
class Ele extends Component{
//实例化属性
style={
color:'#00f',
fontSize:'40px',
background:'#f0f'
}
render(){
//在render函数内定义变量存储属性
const style = {
color:'#0f0',
fontSize:'20px',
background:'#ff0'
}
return(
//唯一盒子,内部为要渲染的html文件
<Fragment>
{/* 直接在行内书写 */}
<h2 style={{ color:'#red',background:'#ccc' }}> 这个组件是:{ this.props.name }</h2>
<p style={style}>嘿嘿</p>
<p style={this.style}>嘻嘻</p>
</Fragment>
)
}
}
展示:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-77D0JMdF-1572248878811)(F:\feiqd\three\1907\me\笔记\react用图\行内样式.png)]
行内样式需要写入一个样式对象,而这个样式对象的位置可以放在很多地方,例如render
函数里、组件原型上、外链js文件中
使用class
React推荐我们使用行内样式,因为React觉得每一个组件都是一个独立的整体
//class写成className,在js中class是关键字
class App extends Component{
render() {
return(
<Fragment>
<p className='p1'> p1111111 </p>
<p className='p2'> p2222222 </p>
</Fragment>
)
}
}
展示
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7QhaLUBf-1572248878811)(F:\feiqd\three\1907\me\笔记\react用图\class名.png)]
不同条件加不同样式
//css
.size{
font-size: 50px;
}
.bg{
background: #dd0;
}
//jsx
<p className= {
classname({
size: false,
bg: true
})}
> p1111111 </p>
展示
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-osqhPckT-1572248878812)(F:\feiqd\three\1907\me\笔记\react用图\按条件加样式.png)]
css-in-js(css也是一个组件)
首先安装组件 styled-components
import styled from 'styled-components'
//引入组件
//创建一个变量存储要渲染的元素
//styled.要渲染的元素
//直接跟模版字符串写样式,如果有变量传入,${ porps => porps.color }接收
const Box = styled.div`
width:100px;
height:100px;
background:#ff0;
color:${ porps => porps.color }
`
<Box>Box</Box>
展示
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Bcle1SQo-1572248878816)(F:\feiqd\three\1907\me\笔记\react用图\样式组件.png)]
scss、sass、less识别
安装sass或less模块
yarn add sass sass-loader
yarn add less less-loader
react数据定义问题
- 数据
-
state(状态)
-
porps(属性)
-
属性
外部传入
组件外通过属性传值传入
内部定义
在组件内使用" static defaultProps "
关键字定义
static defaultPorps = {
name: '张三',
age: '18'
}
- 使用方法:都是用
{ this.props.属性名 }
调用 react中,属性不可变 - 所以外部传入的属性我们要做属性验证(prop-types)
状态的定义
状态码有两种定义形式
直接定义
class StateComp extends Component {
state = {
info:'1'
}
render() {
return (
<Fragment>
<h1>
状态码:{this.state.info}
</h1>
</Fragment>
)
}
}
展示
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Y4DhxCEs-1572248878817)(F:\feiqd\three\1907\me\笔记\react用图\状态码1.png)]
在构造函数内定义
class StateComp extends Component {
constructor() {
super()
this.state = {
info: '2'
}
}
render() {
return (
<Fragment>
<h1>
状态码:{this.state.info}
</h1>
</Fragment>
)
}
}
展示
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rYO75SoC-1572248878818)(F:\feiqd\three\1907\me\笔记\react用图\状态码2.png)]
推荐使用第二种,在构造函数内定义,全局使用