React:
一.主要终端操作
1. 下脚手架:create-react-app 项目名
2. 起服务:npm start
3. 下包:
npm i axios mockjs node-sass redux redux-logger redux-thunk react-redux react-router-dom -D
(ajax) (数据模拟)(scss)( redux )( 路由 )
二.清空脚手架
1. src文件夹删除App.test.js index.css logo.svg serviceWorker.js setupTests.js 文件
2. index.js文件删除以下代码
(1)import './index.css';----3
(2)import * as serviceWorker from './serviceWorker';-----5
(3)serviceWorker.unregister()-----12
3.App.css清空,准备写入新的样式代码
4.App.js文件删除
import logo from './logo.svg';
&&
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
三.配路由
1. src文件夹下建立views文件夹,用来配置路由文件
文件格式例
如:
2. 文件格式为.js文件,内容生成快捷方式 rcc (路由文件名首字母大写)
import React, { Component } from 'react'
export default class “文件名” extends Component {
render() {
return (
<div>
</div>
)
}
}
3. 在src文件夹中建route文件夹,放置router-config.js RouterViews.js 两个文件
4. router-config.js 文件中写路由文件的关系
import Home from "../views/home/Home"; ==>引路由文件
import Detail from "../views/Detail";
import Eat from "../views/home/eat/Eat"
import Pay from "../views/home/pay/Pay";
const routes =[ ===>配置路由
{
path:"/home",
component:Home,
children:[
{
path:"/home/eat",
component:Eat
},{
path:"/home/pay",
component:Pay
},{
path:"/home",
redirect:"/home/pay" ===>重定向
}
]
}{
path:"/detail/:id", ===>跳详情需要传入id
component:Detail,
},{
path:"/",
redirect:"/home" ===>重定向
}
]
export default routes ====>抛出
5. RouterViews.js 文件中具体配置路由操作(固定)
import React, { Component } from 'react'
import { Route,Switch,Redirect } from "react-router-dom"
export default class RouterViews extends Component {
render() {
let routes = this.props.routes.filter(v=>v.component)
let redirect = this.props.routes.filter(v=>v.redirect)
return (
<Switch>
{
routes.map((item,index)=>{
return <Route key={index} path={item.path} render={
props=>{
if(item.children){
<item.component routes={item.children} {...props}/>
}
return <item.component {...props} />
}
}></Route>
})
}
{
redirect.map((item,index)=>{
return <Redirect key={index} from={item.path} to={item.redirect} />
})
}
</Switch>
)
}
}
6. App.js 文件
import RouteViews from "./route/RouterViews"
import routes from "./route/router-config"
import { BrowserRouter } from "react-router-dom"
function App() {
return (
<BrowserRouter>
<div className="App">
<RouteViews routes={routes} ></RouteViews> //视图
</div>
</BrowserRouter>
);
}
7. 需要配置路由的页面
import RouteViews from "../../route/RouterViews"
import { NavLink } from "react-router-dom"
(1)导航栏
<NavLink to="/home/pay">路由1</NavLink> //==>to后边写的是路由路径
<NavLink to="/home/eat">路由2</NavLink> //添加点击效果 .active{}
(2)视图
<RouteViews routes={this.props.routes}></RouteViews>
注:简单路由配置
1.App.js
import { BrowserRouter, Switch, Redirect, Route } from 'react-router-dom';
import Home from '../view/home'
<BrowserRouter>
<div className="app">
<Switch>//视图
<Route path="/home" component={Home}></Route>
<Redirect to="/home"></Redirect>
</Switch>
</div>
</BrowserRouter>
2.导航栏
import { NavLink } from 'react-router-dom';
<NavLink path="/home">主页</NavLink>
四.简单样式(scss)
1. 三段式
.index{
width:100%;
height:100%;
display:flex;
flex-direction:column;
header{
width:100%;
height:50px;
}
main{
flex:1;
width:100%;
overflow:true
}
footer{
width:100%;
height:50px;
}
}
2. 吸顶
position:sticky;
left:0;
top:0; ==>需要吸顶的部分距离顶部位置的负值
3. 横滚
overflow-x: scroll; ==>横向加滚动条
五.数据的模拟与引入
1.src文件夹创建mock文件夹index.js文件
import Mock from 'mockjs'
const data = Mock.mock({
"list|10":[ //10条数据
{
"id|+1":0, //id从0开始每个+1
"name":"@ctitle(8)", //8个随机汉字
"img":"@image(80x80,@color())", //80px*80px的随机色块
"title":"@ctitle(20)", //20个随机汉字
"zan|100-200":110, // 100-200的随机数
} //cname:随机中文名
] //具体看官网
})
Mock.mock('/list',function(){
return data.list
})
2.App.js文件中引用
import "./mock/index"
3.在文件中用axios获取数据
(1)import axios from "axios" //调用插件
(2)state = {
list:[],
}
(3)componentDidMount() {
axios.get("/list").then(res => {
let list = this.props.list
this.setState({
list
})
})
}
4. 使用 this.state.list
六.事件及操作
1. 所有的标签用虚拟dom写在render(){ return(......)}内,并且最外层有一个大盒子包裹,里边所有带js操作的标签都要用{}包裹。
2. 渲染:
this.state.list.map((item,index)=>{
return (<div key={index}>
<p>{item.title}</p>
<img src={item.img} />
</div>)
)}
3. 点击事件
<button className="active" onClick={()=>{
this.to(id)
}}>
to=(id)=>{
}
七.组件
新建components文件夹内创建组件
引用:import Car from './components/car'
使用:<Car />
八.跳详情
1.<dt onClick={() => {
this.jump(item.id)
}}>
2. jump = (id) => {
this.props.history.push("/detail/" + id)
}
3.在detail.js文件中
state={
list:[] //数据
}
componentDidMount(){
axios.get("/list").then(res=>{
let id = this.props.match.params.id;//传过来的id
let list = res.data.filter(v=>v.id==id)[0]
this.setState({
list
})
})
}
九.redux
1. 下包 redux,react-redux, redux-logger, redux-thunk
2. App.js文件中
import { Provider } from "react-redux"
import store from "./store/index"
function App() {
return (
<BrowserRouter>
<Provider store={store}> //redux主要添加这行代码
<div className="App">
<RouteViews routes={routes} ></RouteViews>
</div>
</Provider>
</BrowserRouter>
);
}
3. 在src文件夹中创建store文件夹及index.js文件
import { createStore, applyMiddleware } from "redux";
import logger from "redux-logger";
import thunk from "redux-thunk";
let initState = {
List:[]
//主要写在redux中保存的数据
}
function reducer(state = initState, action) {
state = JSON.parse(JSON.stringify(state))
switch (action.type) {
case 'GET_DATA': //大写的方法名
state.list = action.list //传过来的数据处理后保存到state里
return state
default:
return state;
}
}
const store = createStore(reducer, applyMiddleware(thunk, logger))
export default store
4. 需要redux操作的文件
(1)import { connect } from 'react-redux'
(2)删除自动生成的export default
(3)
let state = state => {
return {
list: state.list, //获取redux的list数据
}
}
let dispatch = dispatch => {
return {
getData(list) {
dispatch({ type: "GET_DATA", list }) //传list用GET_DATA方法
}
}
}
export default connect(state, dispatch)(“文件名”)
(4)存: this.props.getData(data) //用getData方法传data数据给redux
(5)取: this.props.list //取redux内的数据
十.点击返回
this.props.history.go(-1)