React-9:通過路由實現排序切換

queryString        (查詢字符串)

        通常我們把 URL `?` 後面的內容稱爲 queryString,在 React.js 中,我們可以通過 `this.props.location.search` 來獲取,它的值是字符串,

        格式爲:?k1=v1&k2=v2,爲了方便操作,我們把它轉成對象形式

URLSearchParams

        在原生 JJavaScript 中內置了一個 URLSearchParams 的類,我們通過它可以很方便的操作 queryString

js原生方法

或者可以用qs 庫,效果同原生

        https://www.npmjs.com/package/qs

安裝

        npm i -S qs

使用

import queryString from 'qs';

let qsTest = queryString.parse(search, {ignoreQueryPrefix: true});

let sort = qsTest.sort;

通過 JavaScript 編程的方式切換路由

        除了使用 \<Link\> 組件像 a 一樣點擊跳轉路由,我們還可以通過編程的方式(JavaScript) 來切換路由


應用場景(四)

        現在,我想給頁面頂部的導航加上高亮效果,用來標識當前頁面。這個時候,我們就可以使用 react-router-dom 提供的 NavLink 

        組件來實現

NavLink 組件

        NavLink 與 Link 類似,但是它提供了兩個特殊屬性用來處理頁面導航

activeStyle

        噹噹前 URL 與 NavLink 中的 to 匹配的時候,激活 activeStyle 中的樣式

activeClassName

        與 activeStyle 類似,但是激活的是 className

isActive

        默認情況下,匹配的是 URL 與 to 的設置,通過 isActive 可以自定義激活邏輯,isActive 是一個函數,返回布爾值

exact

        精確匹配

strict

        嚴格模式

應用場景(五)

        當用戶訪問不存在的路由,我們需要提供一個反饋頁面,也就是 404

index.js

NotFound.js

        默認情況下,React.js 會渲染所有與之匹配的路由組件,上面的案例中,當我們訪問任意路由(如:/about),也會匹配 NotFound

         路由組件渲染


Switch 組件

        該組件只會渲染首個被匹配的組件


應用場景(六)

現在,我們要給用戶增加一個購物車的功能

index.js

<NavLink to="/cart" activeStyle={{color:'red'}} exact>Cart</NavLink>

Cart.js

Cart.js

app.js


註冊登錄

index.js

Redirect 組件

        未登錄用戶是不能訪問購物車的,所以,我們需要在訪問購物車的時候加入用戶權限驗證(鑑權),如果沒有登錄則跳轉到登錄

index.js

to

        設置跳轉的 URL

登錄代碼

login({username, password}) {

  return new Promise( (resolve, reject) => {

    if (!username || !password) {

      reject('請輸入用戶名和密碼');

    }

    let user = this.state.users.find(user => user.username === username && user.password === password);

    if ( !user ) {

      reject('用戶不存在或者密碼錯誤');

    }

    this.setState({

      userInfo: {

        id: user.id,

        username: user.username

      }

    });

    resolve('登錄成功');

  } );

}

<Route path='/login' component={props => {

    return <Login {...props} onLogin={this.login.bind(this)} />;

}} />

// login.js

import React from 'react';

export default class Login extends React.Component {

    constructor(...props) {

        super(...props);

        this.login = this.login.bind(this);

        this.usernameRef = React.createRef();

        this.passwordRef = React.createRef();

    }

    login() {

        let {onLogin, history: {push}} = this.props;

        if (typeof onLogin === 'function') {

            onLogin({

                username: this.usernameRef.current.value,

                password: this.passwordRef.current.value

            }).then(msg=>{

                alert(msg);

                push('/');

            }).catch(e=>alert(e));

        } 

    }

    render() {

        return(

            <div>

                <p>

                    用戶名:<input type="text" ref={this.usernameRef} />

                </p>

                <p>

                    密碼:<input type="password" ref={this.passwordRef} />

                </p>

                <p>

                    <button onClick={this.login}>登錄</button>

                </p>

            </div>

        );

    }

}


應用場景(七)

        我突然發現賣東西比做碼農要賺錢(主要是能生髮),所以加大產品投入量,期待有一天,我的頭髮要寶哥多,然後推薦給

        莫莫。隨着產品的增多,那麼多的數據就不可能一次性全部展示出來,所以我們爲商品的展示添加一個分頁功能

Home.js

Home.js

 

// Pagination.js

import React from 'react';

import PropTypes from 'prop-types';

import {withRouter, Link} from 'react-router-dom';

class Pagination extends React.Component {

    static defaultProps = {

        pages: 1,

        page: 1

    }

    static propTypes = {

        pages: PropTypes.number,

        page: PropTypes.number

    }

    render() {

        let {pages, page, history: {push}} = this.props;

        // console.log(this.props);

        return (

            <div className="pagination">

                {

                    (new Array(pages)).fill('').map((v, i) => {

                        return (

                            <Link 

                                key={++i}

                                className={i === page ? 'active' : ''}

                                to={'/'+i}

                            >

                                {i}

                            </Link>

                        );

                    })

                }

                前往

                <input type="text" className="goto" onKeyDown={({target:{value}})=>{

                    if (value !== '') {

                        push('/' + value);

                    }

                }} />

                頁

            </div>

        );

    }

}

export default withRouter(Pagination);


withRouter 組件

        如果一個組件不是路由綁定組件,那麼該組件的 props 中是沒有路由相關對象的,雖然我們可以通過傳參的方式傳入,但是如果

        結構複雜,這樣做會特別的繁瑣。幸好,我們可以通過 withRouter 方法來注入路由對象

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章