React 学习笔记 04 React-Route路由

2019-04-13  本文已影响0人  Upcccz

fetch

js原生方法,用来替换XMLHttpRequest的,是基于Promise的,不兼容ie6,但是有一个插件whatwg-fetch来兼容ie(兼容到ie6,是封装XMLHttpRequest,让其有和fetch一样的API)

// fetch(url,config)
// 第一个参数 请求路径
// 第二个参数 请求配置选项:请求方法(默认是GET),请求参数,跨域模式,是否带cookie,请求头,超时时间

fetch('./data.json')
.then(res=>{ // 不同的是 只要服务器有响应就会触发 不管是成功还是失败
    console.log('响应对象',res) // 不仅仅是响应的数据 还包含了响应头 响应体

    // fetch 封装了4个类 Resquest , Response , Header, Body

    // Resquest 请求实例 fetch('./data.json')

    // Response 响应实例

    // Body =>  响应体类,提供了text() , json() ,blob(), arrayBuffer() ,formData()
    // 用来将数据格式化成不同的类型然后返回一个Promise对象

    var promise = res.text(); // 以字符串的形式获取响应结果
    promise.then(data=>{
        console.log('响应结果解析成功',data)
    }).catch(err=>{
        console.log('响应结果解析失败',err)
    })

})
.catch(err=>{ //  类似服务器网络中断这种情况才会触发catch 就是服务器没有任何响应的时候 触发catch
    console.log(err)
})


// 简化写法

fetch('./data.json')
.then(res=>res.json()) // 这里就是返回的就是上面的那个promise
.then(data=>{
    console.log('响应结果解析成功',data)
}).catch(err=>{
    console.log('响应结果解析失败',err)
})

// 配置选项

fetch('./data.json',{
    mothod: 'post',
    body: 'a=1&b=2'
    headers : {
        'Content-Type': 'application/x-www-form-urlencoded' // 表单类型键值对的请求
        // 文件上传 'multipart/form-data'
    },
    mode:"no-cors", // 设置不支持cors跨域  默认是支持 一般不会设置这个选项
    credentials: 'include' // 默认不发送 'same-origin' 同源才发送 'include'都发送cookie
})

react-route

基本使用
// 安装 4.x版本的 react-route-dom 是包含了核心库 react-route的
npm i react-route-dom  -S


// import { Router }  from 'react-route-dom'

// 这个Router是相当于是VueRouter的,负责包括所有的路由记录
// 但是本身是抽象的 不能直接使用 因为它不知道该使用哪种模式

// 它拥有四个子类:{BroswerRouter} {HashRouter} {StaticRouter} {MemoryRouter}

// BroswerRouter  对应 history模式
// HashRouter 对应  hash 模式

import { BrowserRouter as Router, Route } from 'react-router-dom'


class App extends React.Component {
    render(){
        return (
            <Router>
                <div>
                    {/* exact 精准拼配 Router必须有一个根元素*/}
                    <Route exact path="/" component={Home}/>
                    <Route path="/news" render={()=>(<h1>我是一个news组件</h1>)}/>
                </div>
            </Router>
        )
    }
}

ReactDOM.render(<App/>,document.getElementById('app'))

关于重定向

import { HashRouter as Router,Route,Redirect } from 'react-router-dom'

<Router>
    <div>
        <Route path="/goods" component={Goods}/>
        <Redirect to="/home" from="/" /> {/* /重定向到首页 */}
    </div>
</Router>


<Route exact path="/" render={() => (
  loggedIn ? (<Redirect to="/dashboard"/>) : (<PublicHomePage/>)
)}/>


<Redirect
  to={{
    pathname: "/login",
    search: "?utm=your+face",
    state: { referrer: currentLocation }
  }}
/>

<Redirect push to="/somewhere/else" />
// push 是一个bool值,使用push 而不是replace
关于Link 和 NavLink
import { HashRouter as Router,Route,Link, NavLink} from 'react-router-dom'
 
<Router>
    <div>
        {/* Link标签本质还是a便签 */}
        <Link to="/home">首页</Link>
        <Link to="/goods">商品</Link>
        <hr/>

        {/* 与route-link 差不多 会给激活的NavLink 添加一个active类 */}
        <NavLink to="/home">首页</NavLink>
        <hr/>

         {/* 可以使用activeClassName自定义这个类名 一把使用第三方样式的时候使用 */}
        <NavLink to="/home" activeClassName='myActive'>首页</NavLink>
        <hr/>

         {/* 也要加exact精准匹配 不然active类会在跳转到/home的时候 在两个NavLink标签上都加上 */}
        <NavLink to="/" exact >Index</NavLink>
        <NavLink to="/home">首页</NavLink>
        <hr/>

        <Route path="/goods" component={Goods}/>
        {/* /重定向到首页 */}
        <Redirect to="/home" from="/" /> 
    </div>
</Router>
关于Switch组件

Switch组件让路由在匹配到第一个组件时就结束匹配

import { HashRouter as Router,Route,Switch} from 'react-router-dom'

<Router>
    <div>
        {/*Switch一定要加 不然有多少个路由 每次跳转的时候就会匹配多少次 影响性能*/}
        <Switch>
            {/*在Switch中 如果默认路径不加 exact 不管跳转哪里都会跳转到Index 因为'/xxx'都会匹配到'/' */}

            {/* exact是bool值 可以设置为false。exact={false} 实现的是 url.pathname === Route的path属性 */}

            <Route exact path="/" component={Index}/>
            <Route path="/home" component={Home}/>
            <Route path="/goods" component={Goods}/>
        </Switch>
    </div>
</Router>

嵌套路由
class App extends React.Component {
    render(){
        return (
            <Router>
                <Route path="/home" component={Home}/>
                <Route path="/goods" component={Goods}/>
            </Router>
        )
    }
}

class Goods extends React.Component {
    render(){
        return (
            <Router>
                {/* 必须要连接/goods 不然无法匹配 因为每次匹配都是从最外层开始 */}
                {/* /goods 一定不能设置 exact 不然/goods/phone根本就匹配不到路由/goods 那Goods组件都不会渲染 更不会有子路由组件渲染的机会*/}
                <Route path="/goods/phone" component={Phone}/>
                <Route path="/goods/food" component={Food}/>
            </Router>
        )
    }
}
动态路由
class App extends React.Component {
    render(){
        return (
            <Router>
                <Route path="/home" component={Home}/>
                <Route path="/:myPath" component={Product}/>
            </Router>
        )
    }
}

class Product extends React.Component {
    render(){
        return (
            <Router>
                {/* 必须要连接/goods 不然无法匹配 因为每次匹配都是从最外层开始 */}
                {/* /goods 一定不能设置 exact 不然/goods/phone根本就匹配不到路由/goods 那Goods组件都不会渲染 更不会有子路由组件渲染的机会*/}
                <Route path="/phone" component={Phone}/>
                <Route path="/food" component={Food}/>
            </Router>
        )
    }

    componentDidMount(){ // 一般在这个钩子中请求数据 渲染视图
        console.log(this.props)
        // 动态路由的props上有三个属性 history location match

        // history 历史对象== this.ptops.history.push() /  this.ptops.history.replace() / goBack / go
        // 编程式跳转

        // location 当前地址信息对象 = 当前路由的hash pathname search(?a=1&b=2) state 

        // match 匹配对象 拥有isExact params(myPath:phone)  path(/:myPath) url(/phone) 
        // 相当于this.$route.params.myPath
    }
}

为什么要在componentDidMount中获取数据:更新期4个钩子不能调用setState 所有创建周期的render不行,然后componentWillMount会被执行两次

动态路由需要在componentWillReceiveProps获取数据,因为动态路由使用同一个组件,组件的componentDidMount只会执行一次

上一篇下一篇

猜你喜欢

热点阅读