文章目录
前端之React学习(三)
React 脚手架
create-react-app 是 Facebook 官方退出的 react 脚手架
安装(有 node)
- npm i -g create-reate-app //全局安装
- create-reate-app --v //查看版本
创建项目
- cd 需要创建的文件夹中
- create-react-app 项目名字
启动项目
npm start
文件解释
- public 静态资源文件夹
- src 写代码的地方
创建组件
- 组件名.js 或者 组件名.jsx
- rcc //快捷键
import React, { Component } from "react";
class Home extends Component {
render() {
return <div>我是一个组件</div>;
}
}
export default Home;
引用组件
- import 组件名 from “文件路径”
- <组件名/>
import Home from "./components/Home";
function App() {
return (
<div className="App">
<Home />
</div>
);
}
export default App;
多行标签
- 用一个父标签 div 包裹
import React, { Component } from "react";
class Home extends Component {
render() {
return (
<div>
<div>我是一个组件</div>
<div>我是一个组件1</div>
</div>
);
}
}
export default Home;
- 用一个空标签包裹
import React, { Component } from "react";
class Home extends Component {
render() {
return (
<>
<div>我是一个组件</div>
<div>我是一个组件1</div>
</>
);
}
}
export default Home;
- 引用 Fragment 标签
import React, { Component ,Fragment} from "react";
class Home extends Component {
render() {
return (
<Fragment>
<div>我是一个组件</div>
<div>我是一个组件1</div>
</Fragment>
);
}
}
export default Home;
图片引用
- 法一
- 图片放在 public 中
- 法二
- 图片放在 src 下
- import 名字 from “图片路径”
- 法三
- 图片放在 src 下
- <img src={require(“路径”)} />
组件的 props 和 state
- 父组件
import React, { Component, Fragment } from "react";
import News from "./News";
class Home extends Component {
render() {
return (
<Fragment>
<div>我是一个父组件</div>
<div>你好</div>
<News text="props数据" />
</Fragment>
);
}
}
export default Home;
- 子组件
import React, { Component } from "react";
class News extends Component {
constructor(props) {
super(props);
this.state = {
num: 123,
};
}
fun() {
this.setState({
num: 165465,
});
}
render() {
return (
<div>
我是子组件-----{this.props.text}------{this.state.num}
<button onClick={this.fun.bind(this)}>点我修改,state数据</button>
</div>
);
}
}
export default News;
组件的传值
正向传值——父传子(props)
逆向传值——子传父
- 子组件中声明数据
- 绑定传递父函数
- 接收父函数,并编写父函数,函数形参即为接收的子组件的数据
- 子组件
import React, { Component } from "react";
class News extends Component {
constructor(props) {
super(props);
this.state = {
zitext: "我是子组件中的数据",
};
}
render() {
return (
<div>
我是子组件
<div>
<button onClick={this.props.fufun.bind(this, this.state.zitext)}>
点我进行子传父
</button>
</div>
</div>
);
}
}
export default News;
+ 父组件
import React, { Component, Fragment } from “react”;
import News from “./News”;
class Home extends Component {
constructor(props) {
super(props);
this.state = {
text: “我是默认值”,
};
}
datafun = (text) => {
this.setState({
text, //ES6 中,text 和 text:text 相同
});
console.log(text);
};
render() {
return (
export default Home;
第三种——同级传值(pubsub.js)
- Com1 的数据传给 Com2
- 下载
npm i --save pubsub-js - 设置同级组件 Com1,Com2
- 在 Com1 中,引用
import Pubsub from "pubsub-js"
定义绑击事件函数名,定义此函数
Pubsub.publish.("事件名","传递的数据")
- 在 Com2 中
引用
import Pubsub from "pubsub-js"
在 constructor 中调用
Pubsub.subscribe("事件名",(msg,接收数据)=>{})
- 例子 News 传值给 Phone
- News
import React, { Component } from "react";
import Pubsub from "pubsub-js";
class News extends Component {
constructor(props) {
super(props);
this.state = {
num: 123,
zitext: "我是子组件中的数据",
};
}
pubsub() {
Pubsub.publish("evt", this.state.num);
}
render() {
return (
<div>
我是子组件News
<div>
<button onClick={this.props.fufun.bind(this, this.state.zitext)}>
点我进行子传父
</button>
</div>
<button onClick={this.pubsub.bind(this)}>点我同级传值</button>
</div>
);
}
}
export default News;
- Phone
import React, { Component } from "react";
import Pubsub from "pubsub-js";
class Phone extends Component {
constructor(props) {
super(props);
Pubsub.subscribe("evt", (msg, data) => {
console.log(data);
});
}
render() {
return <div>我是子组件Phone</div>;
}
}
export default Phone;
axios(数据请求)& json-server(数据模拟)
下载
- axios(数据请求)
npm i --save axios
- json-server(数据模拟)
npm i json-server -g
数据模拟的启动
- cd mock 文件夹下
- json-server (json 数据的文件名字) --port 4000
数据请求
- 组件中引用 axios
import axios from 'axios'
- 组件中请求数据
componentDidMount(){
this.ajaxfun()
}
ajaxfun=()=>{
axios.get("http://localhost:4000/arr").then((ok)=>{
console.log(ok)
})
}
- 调用组件
import 组件名 from "组件路径"
<组件名/>
- 例子
- mock 下的 data.json 文件
{
"arr":[
{"id":1,"name":"小米1"},
{"id":2,"name":"小米2"},
{"id":3,"name":"小米3"},
{"id":4,"name":"小米4"}
]
}
- 组件
import React, { Component } from "react";
import axios from "axios";
class Home extends Component {
// 自动调用函数
componentDidMount() {
this.ajaxfun();
}
//函数axios请求数据
ajaxfun = () => {
axios.get("http://localhost:4000/arr").then((ok) => {
console.log(ok);
this.setState({
arr: ok.data,
});
});
};
//接收数据
constructor(props) {
super(props);
this.state = {
arr: [],
};
}
render() {
return (
<div>
{/*渲染数据 */}
{this.state.arr.map((v, i) => {
return <p key={i}>{v.name}</p>;
})}
</div>
);
}
}
export default Home;
react 处理跨域问题
正向代理——开发环境
解释:
一个位于客户端和目标服务器之间的代理服务器
为了湖区目标服务器的内容,客户端向代理服务器发送一个请求
代理服务器帮助我们去目标服务器获取数据并且返回给我们
反向代理——上线环境
解释
可以通过代理服务器来接收网络上的请求连接,
然后这个请求转发给内部的网络服务器上,并且把这个服务器上得到的数据返回给请求的客户端
这个时候代理服务器对外的表现就是一个反向代理
(后端人员配置服务器)
例子–模拟请求真实的网络接口
- 中国天气网中的数据
- 找到文件
项目\node_modules\react-scripts\config\webpackDevServer.config.js - 修改
proxy:{
"api":{
target:"http://www.weather.com.cn/data/cityinfo",//只用改target地址
changeOrigin:true,
"pathRewrite":{
"^api":"/"
}
}
},
路由
解释:
根据 url 的不同来切换对应的组件
实现 spa(单页面应用)在页面切换的时候不会刷新,更加接近原生的效果
基本知识
- react-router 只提供了一些核心的 api
- react-router-dom 更加全面
- 路由模式
- hash HashRouter
hash 模式,带 # 号,刷新时页面不会丢失 - browser BrowserRouter
历史记录模式,没有 # 号,他是通过历史记录 api 来进行路由切换,刷新会丢失,本地模式不会
- hash HashRouter
下载
npm i --save react-router-dom
index.js 引用
import {BrowserRouter} from "react-router-dom
index.js 中 BrowserRouter 标签包裹
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>,
document.getElementById("root")
);
配置路由
- 根组件中引用路由
import { Route } from "react-router-dom";
- 根组件中引用多个组件
import Home from "./components/Home";
import Phone from "./components/Phone";
import User from "./components/User";
- 根组件渲染组件
<Route path="/home" component={Home} />
<Route path="/phone" component={Phone} />
<Route path="/user" component={User} />
hash 模式注意:
- 直接在引用时修改
import {HashRouter} from "react-router-dom
- 包裹时修改
- 其余不变
- 路径有#
路由导航
Link,NavLink
- 引用
- 标签
to=“去哪里”
注意:
Navlink—可以动态给选中的标签添加 active 的类名
exact 属性
精准匹配
switch 唯一渲染
- 引用
- 标签
Redirect 重定向
- 引用
- 标签
<Redirect from="/" to="/home" exact component={Home} />
二级路由
- home
import React, { Component } from "react";
import axios from "axios";
import { Route, NavLink } from "react-router-dom";
import homea from "./home/homea";
import homeb from "./home/homeb";
class Home extends Component {
conmponetDidMount() {
axios.get("/api/101320101.html").then((ok) => {
console.log(ok);
});
}
render() {
return (
<div>
<div>Home组件</div>
{/*二级页面 */}
<div>
<NavLink to="/home/homea">to homea</NavLink>
<NavLink to="/home/homeb">to homeb</NavLink>
</div>
<div>
<Route path="/home/homea" component={homea} />
<Route path="/home/homeb" component={homeb} />
</div>
</div>
);
}
}
export default Home;
- homea
import React, { Component } from "react";
class homea extends Component {
render() {
return <div>homea</div>;
}
}
export default homea;
- homeb
import React, { Component } from "react";
class homeb extends Component {
render() {
return <div>homeb</div>;
}
}
export default homeb;