dva——01——路由

1.dva安装

在这里插入图片描述在这里插入图片描述

2.路由

在这里插入图片描述在这里插入图片描述

route
关键代码
router.js

import React from "react";
import { Router, Route, Switch, Redirect } from "dva/router";
// import IndexPage from './routes/IndexPage';
import App from "./routes/App";
import Cinema from "./routes/Cinema";
import Center from "./routes/Center";
import Film from "./routes/Film";
function RouterConfig({ history }) {
  return (
    <Router history={history}>
      <Switch>
        {/* <Route path="/" exact component={IndexPage} /> */}
        {/* <Route path="/" component={App}></Route> */}
        {/* 用render写法,这样App组件里可以写路由 */}
        <Route
          path="/"
          render={() => (
            // APP外面不能包{},不然会被识别为表达式(jsx语法),如果写{} App前面要加个return,return <App></App>
            <App>
              {/* 这里如果不加Switch组件在匹配到film不会停又会因为重定向匹配到film而报错,而且假如在center页面,刷新的话又会回到film页面
             路由是模糊匹配的,加exact才是精准匹配,由于默认是模糊匹配,所以匹配到film也不会停,而 Switch保证只能匹配一个
              */}
               <Switch> 
                <Route path={"/film"} component={Film}>
                  Film
                </Route>
                <Route path={"/cinema"} component={Cinema}>
                  Cinema
                </Route>
                <Route path={"/center"} component={Center}>
                  Center
                </Route>
                <Redirect from={"/"} to={"/film"}></Redirect>
              </Switch> 
            </App>
          )}
        ></Route>
      </Switch>
    </Router>
  );
}

export default RouterConfig;

Tabbar.js

import React from "react";
import { NavLink, Switch } from "dva/router";
import "./Tabbar.css";
export default function Tabbar() {
  return (
    // 选项卡组件
    <div>
      <footer>
        <ul>
          {/* 重复点击选项卡同样的内容会有警告,所以要加上Switch标签 */}

          <li>
            <NavLink activeClassName="active" to={"/film"}>
              film
            </NavLink>
          </li>
          <li>
            <NavLink activeClassName="active" to={"/cinema"}>
              cinema
            </NavLink>
          </li>
          <li>
            <NavLink activeClassName="active" to="/center">
              center
            </NavLink>
          </li>
        </ul>
      </footer>
    </div>
  );
}

Tabbar.css

footer {
  position: fixed;
  bottom: 0;
  width: 100%;
  height: 50px;
  line-height: 50px;
  /* align-items: center; */
  text-align: center;
  background-color: white;
}
footer>ul{
   list-style: none;
   display: flex;
}
footer>ul>li{
  flex:1
}
.active{
  color: red;
}

3.编程式导航和withRouter用法

编程式导航适合从一个页面携带参数跳转到另一个页面
组件首字母一定是大写,这里我没注意出错了
props有history属性,是因为组件被Route包裹着,Route赋予的属性
用框架已经封装好的方法请求数据
在这里插入图片描述router.js

import React from "react";
import { Router, Route, Switch, Redirect } from "dva/router";
// import IndexPage from './routes/IndexPage';
import App from "./routes/App";
import Cinema from "./routes/Cinema";
import Center from "./routes/Center";
import Film from "./routes/Film";
import Detail from "./routes/Detail";
import Login from "./routes/Login";
function RouterConfig({ history }) {
  return (
    <Router history={history}>
      <Switch>
        <Route path={"/login"} component={Login} />
        {/* <Route path="/" exact component={IndexPage} /> */}
        {/* <Route path="/" component={App}></Route> */}
        {/* 用render写法,这样App组件里可以写路由 */}
        <Route
          path="/"
          render={() => (
            // APP外面不能包{},不然会被识别为表达式(jsx语法),如果写{} App前面要加个return,return <App></App>
            <App>
              {/* 这里如果不加Switch组件在匹配到film不会停又会因为重定向匹配到film而报错,而且假如在center页面,刷新的话又会回到film页面
             路由是模糊匹配的,加exact才是精准匹配,由于默认是模糊匹配,所以匹配到film也不会停,而 Switch保证只能匹配一个
              */}
              <Switch>
                <Route path={"/film"} component={Film} />
                <Route path={"/cinema"} component={Cinema} />
                <Route path={"/center"} render={()=>
                  localStorage.getItem("token")? <Center/>:<Redirect to={"./login"}></Redirect>
                } />
                {/* :myid动态路由占位符 */}
                <Route path={"/detail/:myid"} component={Detail} />
                <Redirect from={"/"} to={"/film"}></Redirect>
              </Switch>
            </App>
          )}
        ></Route>
      </Switch>
    </Router>
  );
}

export default RouterConfig;

Detail.js

import React, { Component } from 'react'

export default class Detail extends Component {
  componentDidMount(){
    // 接收上个页面传来的id,利用此id取数据
    console.log(this.props.match.params.myid);
  }
  render() {
    return (

      <div>Detail</div>
    )
  }
}

Film.js

import React, { Component } from "react";
// 导入dva封装好的文件
import request from "../utils/request";
export default class Film extends Component {
  state={
    list:[]
  }
  componentDidMount() {
    request(
      "https://m.maizuo.com/gateway?cityId=330100&pageNum=1&pageSize=10&type=1&k=9105921",
      {
        headers: {
          "X-Client-Info":
            '{"a":"3000","ch":"1002","v":"5.2.0","e":"16460383564094280654127105","bc":"330100"}',
          "X-Host": "mall.film-ticket.film.list",
        },
      }
    ).then(res=>
      // console.log(res.data.data.films)
      this.setState({list:res.data.data.films})
      );
  }
  render() {
    
      return this.state.list.map((item) => (
        <li key={item.filmId} onClick={()=>{
          // console.log(this.props);
          // props上有history属性,组件被Route所包裹着,是Route赋予的属性
          this.props.history.push(`/detail/${item.filmId}`)
        }}>
          <img src={item.poster} style={{ width: "100px" }} />
          <p>{item.name}</p>
        </li>
      ));
    
  }
}

4.路由拦截

进入center页面必须有token信息,若没有跳转到登录login页面
router.js

import React from "react";
import { Router, Route, Switch, Redirect } from "dva/router";
// import IndexPage from './routes/IndexPage';
import App from "./routes/App";
import Cinema from "./routes/Cinema";
import Center from "./routes/Center";
import Film from "./routes/Film";
import Detail from "./routes/Detail";
import Login from "./routes/Login";
function RouterConfig({ history }) {
  return (
    <Router history={history}>
      <Switch>
        <Route path={"/login"} component={Login} />
        {/* <Route path="/" exact component={IndexPage} /> */}
        {/* <Route path="/" component={App}></Route> */}
        {/* 用render写法,这样App组件里可以写路由 */}
        <Route
          path="/"
          render={() => (
            // APP外面不能包{},不然会被识别为表达式(jsx语法),如果写{} App前面要加个return,return <App></App>
            <App>
              {/* 这里如果不加Switch组件在匹配到film不会停又会因为重定向匹配到film而报错,而且假如在center页面,刷新的话又会回到film页面
             路由是模糊匹配的,加exact才是精准匹配,由于默认是模糊匹配,所以匹配到film也不会停,而 Switch保证只能匹配一个
              */}
              <Switch>
                <Route path={"/film"} component={Film} />
                <Route path={"/cinema"} component={Cinema} />
                <Route path={"/center"} render={()=>
                  localStorage.getItem("token")? <Center/>:<Redirect to={"./login"}></Redirect>
                } />
                {/* :myid动态路由占位符 */}
                <Route path={"/detail/:myid"} component={Detail} />
                <Redirect from={"/"} to={"/film"}></Redirect>
              </Switch>
            </App>
          )}
        ></Route>
      </Switch>
    </Router>
  );
}

export default RouterConfig;

Login.js

import React, { Component } from 'react'

export default class Login extends Component {
  render() {
    return (
      <div>Login</div>
    )
  }
}

Center.js

import React, { Component } from "react";
import { withRouter } from "dva/router";

export default class Center extends Component {
  render() {
    return (
      <div>
        Center
        {/* <Child props={this.props} /> */}
        {/* 不传props的情况下可以使用withRouter */}
        <WithChild />
      </div>
    );
  }
}
class Child extends Component {
  render() {
    return (
      <div>
        <button
          onClick={() => {
            // console.log(this.props)
            localStorage.removeItem("token");
            this.props.history.push("/login");
          }}
        >
          退出登录
        </button>
      </div>
    );
  }
}
// 组件首字母要大写,注意
const WithChild = withRouter(Child);

点击退出登录后,token被移除,会跳转到login页面
在控制台我们再设置token数据,并刷新,点击center又可以跳转到center了
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值