久久伊人一区二区三区四区-久久伊人影视-久久伊人影院-久久伊人中文字幕-亚洲成在人色婷婷-亚洲大成色www永久网

千鋒教育-做有情懷、有良心、有品質的職業教育機構

手機站
千鋒教育

千鋒學習站 | 隨時隨地免費學

千鋒教育

掃一掃進入千鋒手機站

領取全套視頻
千鋒教育

關注千鋒學習站小程序
隨時隨地免費學習課程

當前位置:首頁  >  技術干貨  > react自動化構建路由

react自動化構建路由

來源:千鋒教育
發布人:wjy
時間: 2022-06-01 17:00:00 1654074000

## 序

在使用`react-router-dom`在編寫項目的時候有種感覺就是,使用起來非常的方便,但是若是維護起來,那便是比較麻煩了,因為各大路由分散在各個組件中. 所以我們就會想到,使用`react-router-dom`中提供的`config`模式來編寫我們的路由,這樣寫的好處就是我們可以將邏輯集中在一處,配置路由比較方便

react自動化構建路由

## 項目地址

[https://gitee.com/d718781500/autoRouter](https://link.zhihu.com/?target=https%3A//gitee.com/d718781500/autoRouter)

## 1.路由集中式

我們先將下列數據定義在`/src/router/index.js`中

在react的路由官方文檔中就提供了配置集中式路由的案例,大致是這樣的仿照`vue`的路由,生成一個配置文件,預期是這樣的

```text
//需要一個路由的配置,它是一個數組
import Discover from "../pages/Discover"
import Djradio from "../pages/Discover/Djradio"
import Playlist from "../pages/Discover/Playlist"
import Toplist from "../pages/Discover/Toplist"
import Friends from "../pages/Friends"
import Mine from "../pages/Mine"
import Page404 from "../pages/Page404"
const routes = [
    {
        path: "/friends",
        component: Friends
    },
    {
        path: "/mine",
        component: Mine
    },

    {
        path: "/discover",
        component: Discover,
        children: [
            {
                path: "/discover/djradio",
                component: Djradio
            },
            {
                path: "/discover/playlist",
                component: Playlist

            },
            {
                path: "/discover/toplist",
                component: Toplist
            }
        ]
    },
    {//Page404這個配置一定要在所有路由配置之后
        path: "*",
        component: Page404
    }
]

export default routes
```

我們可以通過上述配置,來生成一個路由.當然上述的配置也只是做了簡單的處理,還有`redirect exact`等屬性沒有寫,我們還是從一個簡單的開始吧

## 2.文件目錄

上述的配置中使用了類似于vue的集中式路由配置模式,那么下面就展示下我當前這個demo的結構目錄吧

### 項目目錄結構

![img](https://pic2.zhimg.com/80/v2-ea7f59cc154a0ee366857901b1ed3dad_720w.jpg)

### src/pages目錄結構

```js
├─Discover
│  │  abc.js
│  │  index.js
│  │
│  ├─Djradio
│  │  │  index.js
│  │  │  lf.js
│  │  │
│  │  └─gv
│  │          index.js
│  │
│  ├─Playlist
│  │      index.js
│  │
│  └─Toplist
│          index.js

├─Entertaiment
│      index.js

├─Friends
│      index.js
│      xb.js

├─Mine
│      index.js

└─Page404
        index.js
```

有了這些結構之后,那么在`1`中提到的引入文件結合起來看就不懵逼啦,接下來我們可以封裝一個組件,給他取個名字叫做`CompileRouter`這個組件專門用于編譯路由

## 3.創建CompileRouter

這個組件我們把它創建在`src/utils`中,作用就是通過傳入的路由配置,然后計算出這個組件,那么問題來了,為什么要創建這個組件呢?

讓我們回顧一下react路由的編寫方式吧,react路由需要一個基礎組件`HashRouter`或者`BrowserRouter`這兩個相當于一個基石組件

然后還需要一個路由配方這個組件可以接受一個`path`映射一個`component`

我們來寫段偽代碼來說明一下

```text
//引入路由基本組件(要在項目中安裝 npm i react-router-dom)
import {HashRouter as Router,Route} from "react-router-dom"
class Demo extends React.Component {
    render(){
        //基石路由
        <Router>
            //路由配方組件 通過path匹配component
            <Route path="/" component={Home}/>
             <Route path="/mine" component={Mine}/>
        </Router>
    }
}
```

這是基本用法,所以我們CompileRouter這個組件的工作就是,生成如上代碼中的Route一樣,生成Route然后展示在組件上

在了解到Compile的基本作用之后,下面我們就開始編碼吧

我個`CompileRouter`設計是接受一個數據,這個數據必須是符合路由配置的一個數組,就像`1`里代碼中所示的數組一樣,接受的屬性為`routes`

```text
//這個文件通過routes配置來編譯出路由
import React from 'react'
import { Switch, Route } from "react-router-dom";
export default class CompileRouter extends React.Component {
    constructor() {
        super()
        this.state = {
            c: []
        }
    }
    renderRoute() {
        let { routes } = this.props;//獲取routes路由配置
        //1.通過routes生成Route組件
        //確保routes是一個數組
        // console.log(routes)
        //render 不會重復讓組件的componentDidMount和componentWillUnmount重復調用
        if (Array.isArray(routes) && routes.length > 0) {
            //確保傳入的routes是個數組
           // 循環迭代傳入的routes
            let finalRoutes = routes.map(route => {
                //每個route是這個樣子的 {path:"xxx",component:"xxx"}
                //如果route有子節點 {path:"xxx",component:"xxx",children:[{path:"xxx"}]}
                return <Route path={route.path} key={route.path} render={
                       // 這么寫的作用就是,如果路由還有嵌套路由,那么我們可以把route中的children中的配置數據傳遞給這個組件,讓組件再次調用CompileRouter的時候就能編譯出嵌套路由了
                    () => <route.component routes={route.children} />
                } />
            })

            this.setState({
                c: finalRoutes
            })
        } else {
            throw new Error('routes必須是一個數組,并且長度要大于0')
        }
    }
    componentDidMount() {
        //確保首次調用renderRoute計算出Route組件
        this.renderRoute()
    }
    render() {
        let { c } = this.state;
        return (
            <Switch>
                {c}
            </Switch>
        )
    }
}
```

上述代碼就是用于去處理`routes`數據并且聲稱這樣的組件,每一步的作用我都已經在上面用注釋標明了

## 4.使用CompileRouter

其實我們可以把封裝的這個組件當成是`vue-router`中的視圖組件`<router-view/>`就暫且先這么認為吧,接下來我們需要在頁面上渲染`1級路由了`

在`src/app.js`

```text
import React from 'react'
import { HashRouter as Router, Link } from 'react-router-dom'
//引入我們封裝的CompileRouter罪案
import CompileRouter from "./utils/compileRouter"
//引入在1中定義的路由配置數據
import routes from "./router"
console.log(routes)
class App extends React.Component {
    render() {
        return (
            <Router>
                <Link to="/friends">朋友</Link>
                |
                <Link to="/discover">發現</Link>
                |
                <Link to="/mine">我的</Link>
                {/*當成是vue-router的視圖組件 我們需要將路由配置數據傳入*/}
                <CompileRouter routes={routes} />
            </Router>
        )
    }
}

export default App
```

寫完后,那么頁面上其實就可以完美的展示1級路由了

## 5.嵌套路由處理

上面我們已經對1級路由進行了渲染,可以跳轉,但是二級路由怎么處理呢?其實也很簡單,我們只需要找到二級路由的父路由,繼續使用`CompileRouter`就可以了

我們從配置中可以看到,`Discover`這個路由是具有嵌套路由的,所以我們就以`Discover`路由為例子,首先我們看下結構圖

圖上的`index.js`就是`Discover`這個視圖組件了,也是嵌套路由的`父級路由`,所以我們只需要在這個`index.js`中繼續使用`CompileRouter`就可以了

```text
import React from 'react'
import { Link } from "react-router-dom"

import CompileRouter from "../../utils/compileRouter"
function Discover(props) {

    let { routes } = props //這個數據是從ComileRouter組件編譯的時候傳遞過來的children
    // console.log(routes)
    let links = routes.map(route => {
        return (
            <li key={route.path}>
                <Link to={route.path}>{route.path}</Link>
            </li>
        )
    })
    return (
        <fieldset>
            <legend>發現</legend>
            <h1>我發現,不能說多喝熱水</h1>
            <ul>
                {links}
            </ul>
            {/*核心代碼,再次使用即可 這里將通過children數據可以渲染出Route*/}
            <CompileRouter routes={routes} />
        </fieldset>
    )
}
Discover.meta = {
    title: "發現",
    icon: ""
}
export default Discover
```

所以我們以后記住,只要是有嵌套路由我們要做兩件事

1. 配置routes
2. 在嵌套路由的父級路由中再次使用`CompileRouter`,并且傳入`routes`即可

## 6. require.context

上面我們實現了一個路由集中式的配置,但是我們會發現一個問題

引入了很多的組件,實際上,在項目中引入的更多,如果一個一個引入,對我們來說是災難性的,所以我們可以使用`webpack`提供的一個很好用的api,`require.context`我們先說說它是怎么使用的吧

自動化導入`require.context`方法,使用這個方法可以減少繁瑣的組件引入,而且可以深度的遞歸目錄,做到import做不到的事情 下面我們來看一下這個方法是如何使用的

### 使用

你可以通過 `require.context()` 函數來創建自己的 context。

可以給這個函數傳入4個參數:

1. 一個要搜索的目錄,
2. 一個標記表示是否還要搜索其子目錄,
3. 一個匹配文件的正則表達式。
4. mode 模塊加載模式,常用值為 sync、lazy、lazy-once、eager
5. `sync` 直接打包到當前文件,同步加載并執行
   `lazy` 延遲加載會分離出單獨的 chunk 文件
   `lazy-once` 延遲加載會分離出單獨的 chunk 文件,加載過下次再加載直接讀取內存里的代碼。
   `eager` 不會分離出單獨的 chunk 文件,但是會返回 promise,只有調用了 promise 才會執行代碼,可以理解為先加載了代碼,但是我們可以控制延遲執行這部分代碼。

webpack 會在構建中解析代碼中的 `require.context()` 。

語法如下:

```js
require.context(
  directory,
  (useSubdirectories = true),
  (regExp = /^\.\/.*$/),
  (mode = 'sync')
);
```

示例:

```js
require.context('./test', false, /\.test\.js$/);
//(創建出)一個 context,其中文件來自 test 目錄,request 以 `.test.js` 結尾。
require.context('../', true, /\.stories\.js$/);
// (創建出)一個 context,其中所有文件都來自父文件夾及其所有子級文件夾,request 以 `.stories.js` 結尾。
```

### api

函數有三個屬性:`resolve`, `keys`, `id`。

- `resolve` 是一個函數,它返回 request 被解析后得到的模塊 id。
- `js let p = require.context("...",true,"xxx") p.resolve("一個路徑")`
- `keys` 也是一個函數,它返回一個數組,由所有可能被此 context module 處理的請求(譯者注:參考下面第二段代碼中的 key)組成。

`require.context`的返回值是一個函數,我們可以在函數中傳入文件的路徑,就可以得到模塊化的組件了

```text
let components = require.context('../pages', true, /\.js$/, 'sync')

let paths = components.keys()//獲得了所有引入文件的地址
// console.log(paths)
let routes = paths.map(path => {
    let component = components(path).default
    path = path.substr(1).replace(/\/\w+\.js$/,"")
    return {
        path,
        component
    }
})
console.log(routes)
```

### 總結

雖然上面有很多api和返回的值,我們只拿兩個來做說明

1. keys方法,這個可以獲取所有模塊的路徑,返回的是一個數組

```text
let context = require.context("../pages", true, /\.js$/);

let paths = context.keys()//獲取了所有文件的路徑
```

\2. 獲取路徑下所有的模塊

```text
let context = require.context("../pages", true, /\.js$/);

let paths = context.keys()//獲取了所有文件的路徑

let routes = paths.map(path => {
    //批量獲取引入的組件
    let component = context(path).default;
    console.log(component)
})
```

掌握這兩個就可以了,下面我們來繼續處理

## 7.扁平數據轉換為樹形結構的(convertTree算法)

這個算法的名字是我自己起的,首先我們要明白為甚么需要將數據轉換成tree

我們的預期的`routes`數據應該是下面這樣的

```js
//目的是什么?
//生成一個路由配置
 const routes = [
     {
         path: "",
         component:xxx
          children:[
                 {
                     path:"xxx"
                     component:xxx
                 }
            ]
     }
 ]
```

但其實我們使用`require.context`處理之后的數據是這樣的

可以看到這個數據是完全`扁平化`的,沒有任何的嵌套,所以我們第一步就是要實現將這種扁平化的數據轉換為符合我們預期的`樹形`結構,下面我們一步一步來

### 7.1使用require.context將數據處理成扁平化

首先要處理成上圖那樣的結構,代碼都有注釋,難度也不高

```js
//require.context()

// 1. 一個要搜索的目錄,
// 2. 一個標記表示是否還要搜索其子目錄,
// 3. 一個匹配文件的正則表達式。
let context = require.context("../pages", true, /\.js$/);

let paths = context.keys()//獲取了所有文件的路徑


let routes = paths.map(path => {
    //批量獲取引入的組件
    let component = context(path).default;
    //組件擴展屬性方便渲染菜單
    let meta = component['meta'] || {}
    //console.log(path)
    //這個正則的目的
    //因為地址是./Discover/Djradio/index.js這種類型的并不能直接使用,所以要進行處理
    //1.接去掉最前的"." 得到的結果是/Discover/Djradio/index.js
    //2.處理了還是不能直接用 因為我們的預期/Discover/Djradio,所以通過正則將index.js干掉了
    //3.有可能后面的路徑不是文件夾 得到的結果是/Discover/abc.js,后綴名并不能用到路由配置的path屬性中,所以.js后綴名又用正則替換掉
    path = path.substr(1).replace(/(\/index\.js|\.js)$/, "")
    // console.log(path)
    return {
        path,
        component,
        meta
    }
})
```

### 7.2 實現convertTree算法

上面處理好了數據后,我們封裝一個方法,專門用于處理扁平化數據變成樹形數據,算法`時間復雜度為O(n^2)`

```js
function convertTree(routes) {
    let treeArr = [];
    //1.處理數據 將每條數據的id和parent處理好 (俗稱 爸爸去哪兒了)
    routes.forEach(route => {
        let comparePaths = route.path.substr(1).split("/")
        // console.log(comparePaths)
        if (comparePaths.length === 1) {
            //說明是根節點,根節點不需要添加parent_id
            route.id = comparePaths.join("")
        } else {
            //說明具有父節點
            //先處理自己的id
            route.id = comparePaths.join("");
            //comparePaths除去最后一項就是parent_id
            comparePaths.pop()
            route.parent_id = comparePaths.join("")
        }
    })
    //2.所有的數據都已經找到了父節點的id,下面才是真正的找父節點了
    routes.forEach(route => {
        //判斷當前的route有沒有parent_id
        if (route.parent_id) {
            //有父節點
            //id===parent_id的那個route就是當前route的父節點
            let target = routes.find(v => v.id === route.parent_id);
            //判斷父節點有沒有children這個屬性
            if (!target.children) {
                target.children = []
            }
            target.children.push(route)
        } else {
            treeArr.push(route)
        }
    })

    return treeArr
}
```

通過上述處理之后就可以得到樹形結構啦

接下來我們只需要把數據導出去,在app上引入傳遞給`CompileRouter`組件就可以了

### 7.3 以后要注意的

以后只需要在pages中創建文件即可自動實現路由的處理以及編譯了,不過對于嵌套級別的路由咱們別忘了要在路由組件加上CompileRouter組件,總結為亮點

1. 創建路由頁面
2. 嵌套路由的父級路由組件中加入<CompileRouter routes={routes}/>

## 8.擴展靜態屬性

我們當前創建出來的效果是有了,但是如果我們用于渲染`菜單`的時候就會有問題,沒有內容可以用于渲染菜單,所以我們可以給組件上擴展`靜態屬性meta(也可以是別的)`,然后對我們的自動化編譯代碼做一些小小的改動就行了

### 組件

### 自動化處理邏輯完整代碼

```text
//require.context()

// 1. 一個要搜索的目錄,
// 2. 一個標記表示是否還要搜索其子目錄,
// 3. 一個匹配文件的正則表達式。
let context = require.context("../pages", true, /\.js$/);

let paths = context.keys()//獲取了所有文件的路徑


let routes = paths.map(path => {
    //批量獲取引入的組件
    let component = context(path).default;
    //組件擴展屬性方便渲染菜單
    let meta = component['meta'] || {}
    //console.log(path)
    //這個正則的目的
    //因為地址是./Discover/Djradio/index.js這種類型的并不能直接使用,所以要進行處理
    //1.接去掉最前的"." 得到的結果是/Discover/Djradio/index.js
    //2.處理了還是不能直接用 因為我們的預期/Discover/Djradio,所以通過正則將index.js干掉了
    //3.有可能后面的路徑不是文件夾 得到的結果是/Discover/abc.js,后綴名并不能用到路由配置的path屬性中,所以.js后綴名又用正則替換掉
    path = path.substr(1).replace(/(\/index\.js|\.js)$/, "")
    // console.log(path)
    return {
        path,
        component,
        meta
    }
})
//這種數據是扁平化的數據,并不符合我們的路由規則
//需要做算法 盡可能將時間復雜度降低o(n)最好
//封裝一個convertTree算法 時間復雜度o(n^2)
// console.log(routes)

//id
//parent_id

function convertTree(routes) {
    let treeArr = [];
    //1.處理數據 將每條數據的id和parent處理好 (俗稱 爸爸去哪兒了)
    routes.forEach(route => {
        let comparePaths = route.path.substr(1).split("/")
        // console.log(comparePaths)
        if (comparePaths.length === 1) {
            //說明是根節點,根節點不需要添加parent_id
            route.id = comparePaths.join("")
        } else {
            //說明具有父節點
            //先處理自己的id
            route.id = comparePaths.join("");
            //comparePaths除去最后一項就是parent_id
            comparePaths.pop()
            route.parent_id = comparePaths.join("")
        }
    })
    //2.所有的數據都已經找到了父節點的id,下面才是真正的找父節點了
    routes.forEach(route => {
        //判斷當前的route有沒有parent_id
        if (route.parent_id) {
            //有父節點
            //id===parent_id的那個route就是當前route的父節點
            let target = routes.find(v => v.id === route.parent_id);
            //判斷父節點有沒有children這個屬性
            if (!target.children) {
                target.children = []
            }
            target.children.push(route)
        } else {
            treeArr.push(route)
        }
    })

    return treeArr
}

export default convertTree(routes)


//獲取一個模塊
// console.log(p("./Discover/index.js").default)

//目的是什么?
//生成一個路由配置
// const routes = [
//     {
//         path: "",
//         component,
//          children:[
//                 {path component}
//             ]
//     }
// ]
```

## 寫在最后

其實上述的處理并不能作為`應用級別`用于項目中,主要在于`CompileRouter`處理的不夠細致,下一期我將專門寫一篇如何處理`CompileRouter`用于`鑒權`等應用在項目中.更多關于“html5培訓”的問題,歡迎咨詢千鋒教育在線名師。千鋒已有十余年的培訓經驗,課程大綱更科學更專業,有針對零基礎的就業班,有針對想提升技術的提升班,高品質課程助理你實現夢想。

tags:
聲明:本站稿件版權均屬千鋒教育所有,未經許可不得擅自轉載。
10年以上業內強師集結,手把手帶你蛻變精英
請您保持通訊暢通,專屬學習老師24小時內將與您1V1溝通
免費領取
今日已有369人領取成功
劉同學 138****2860 剛剛成功領取
王同學 131****2015 剛剛成功領取
張同學 133****4652 剛剛成功領取
李同學 135****8607 剛剛成功領取
楊同學 132****5667 剛剛成功領取
岳同學 134****6652 剛剛成功領取
梁同學 157****2950 剛剛成功領取
劉同學 189****1015 剛剛成功領取
張同學 155****4678 剛剛成功領取
鄒同學 139****2907 剛剛成功領取
董同學 138****2867 剛剛成功領取
周同學 136****3602 剛剛成功領取
相關推薦HOT
主站蜘蛛池模板: 欧美黑人疯狂性受XXXXX喷水| 无码国内精品久久综合88| 无码AV免费一区二区三区四区| 欧洲美熟女乱又伦AV曰曰| 国产寡妇XXXX猛交| 差差差很疼视频无掩丰富| 国产精品亚洲专区无码破解版 | 草木影视在线视频免费观看| 成人女人爽到高潮的Av在线| 色综合久久久无码中文字幕波多 | 成年无码AV片在线| 亚洲国产欧美在线人成最新| 嫩草院一区二区乱码| 极品婬荡少妇XXXX欧美图片| 亚洲AV无码久久| 男人添女人下部高潮全视频| 小婷又软又嫩又紧水又多 | 久久99精品免费一区二区| 精品国产AⅤ一区二区三区在线看| 国产成人AV无码精品天堂| 无码99久热只有精品视频在线观| 国产成人牲交在线观看视频| 国内精品久久久久影院蜜芽蜜芽T 国内精品久久久人妻中文字幕 | 久久久久亚洲精品男人的天堂| 国产又粗又猛又爽又黄的网站| 我半夜摸妺妺的奶摸到高潮| 无码G0G0大胆啪啪艺术| 少妇扒开毛茸茸的B自慰| 午夜无码伦费影视在线观看果冻| 一区二区三区中文字幕| 公车上玩弄白嫩少妇| 国产女人喷潮视频在线观看 | 国产精品SP调教打屁股| 高清性色生活片97| 小蜜被两老头吸奶头| 丝袜老师办公室里做好紧好爽| 亚洲国产精品无码第一区二区三区| 国产精品亚洲А∨无码播放麻豆 | 日韩一区无码视频| 欧美、另类亚洲日本一区二区| 无码日韩精品一区二区免费 | 少妇爆乳无码AV专区网站寝取| 哦┅┅快┅┅用力啊┅┅村妇| 寂寞视频一对一视频APP| 丰满人妻无码使劲张开双腿AV| 播放灌醉水嫩大学生国内精品| 日本极品人妻VIDEOSSEX| 国产精品成人99一区无码| 又黄又硬又湿又刺激视频免费 | 豆国产97在线 | 亚洲| 无遮挡又爽又刺激的视频| 免费的看片APP| 日本国产网曝视频在线观看| 亚洲精品无码专区在线播放| 丰满大爆乳波霸奶| 娇小6一8XXXXX| 国内精品久久久人妻中文字幕| 欧美亚洲日韩国产区三| 蜜臀98精品国产免费观看| 女刑警被两个黑人挺进| 国产成人亚洲精品无码AV大片| 国产精品WWW夜色视频| 干了老婆闺蜜两个小时| 亚洲AⅤ日韩AV无码COM| 久久久久亚洲AV综合仓井空| 国产精品久久久久久久久久直播| 粗大从后面狠狠贯穿H| 差差差很疼视频无掩丰富| 亚洲妇女无套内射精| 人妻系列综合第一页| 久久精品伊人一区二区三区| 亚洲中文字幕精品一区二区三区| 把腿扒开让我舔免费视频| 天天AV天天爽无码中文| 把腿扒开让我舔免费视频| 蜜芽AV在线新地址| 天天摸天天做天天爽水多| 高跟丝袜AV专区| 精品亚洲国产成人AV制服| 他的舌头探进蜜源毛毛虫说说 | 狠狠色丁香久久综合| 高清一区二区三区日本久| 人人爽人人模人人人爽人人爱| 一本大道东京热无码AV| 亚洲AV成人网站在线播放| 一个上面一个下面嘴巴| 无码精品人妻一区二区三区免费看| 高潮喷视频在线无码| 狠狠干2015最新版| 国产对白videos麻豆高潮| 国产日韩未满十八禁止观看| 男人扒开女人的腿做爽爽视频| 日本熟妇人妻XXXXX中文| 年级老师的滋味4| 国产精品无码素人福利| 又大又粗又爽A级毛片免费看| 又紧又大又爽精品一区二区| 琪琪秋霞午夜AV影院| 久久AⅤ人妻少妇嫩草影院| 国产高清在线精品一本大道| 成 人 综合 亚洲另类| 日本无吗无卡V免费清高清| 免费无码又爽又刺激激情视频| 久久婷婷五月综合色高清图片| 国产精品视频色拍拍| 色综合久久久无码中文字幕波多| 国产精品爽爽V在线观看无码| 亚洲AV永久中文无码精品综合 | 小鲜肉洗澡时自慰网站XNXX| 久久久WWW成人免费看片| 午夜A级理论片在线播放不卡| 美女把尿口扒开让男人桶爽| 日本高清在线视频WWW色| 亚洲人女屁股眼HD| 小蜜被两老头吸奶头| 色婷婷亚洲六月婷婷中文字幕| 超碰CAO已满18进入| 最新国产成人AB网站| 久久寂寞少妇成人内射| 国产激情久久久久久熟女老人| 久久久综合九色综合鬼色| 久久精品国产99精品最新| 国产裸拍裸体女网站链接在线观看 | 差差差软件大全APP推荐免费| 老熟妇高潮一区二区三区网| 国内精品久久影院综合日日| 公交车被CAO得合不拢腿视频| 成人羞羞视频免费网站| 小SAO货水好多真紧H视频| 日韩人妻不卡一区二区三区| 国产激情无码一区二区APP| 又黄又硬又湿又刺激视频免费| 淑芬二腿间又痒了| 女BBBB槡BBBB槡BBBB| 又大又粗的久久久精品少妇AV| 人妻被黑人与白人巨大中出| 成人亚洲欧美成ΑⅤ人在线观看| 色婷婷五月综合丁香中文字幕| 国产精品无码久久综合网| 少妇人妻一级AV片| 无码丰满人妻熟妇区| W永久939W78W78W乳液| 丰满少妇被猛烈进入无码| 久久久久久精品免费S| 少妇丰满爆乳被呻吟进入| 亚洲色大成网站WWW永久| 嗯…啊 摸 湿 奶头免费视频| 久久久WWW成人免费看片| 蜜臀98精品国产免费观看| 嫩草在线视频WWW免费看| 久久精品人人做人人综合试看 | 国产精品VIDEOSSEX久久发布| 亚洲已满18点击进入在线看片| 国产高清在线观看AV片麻豆| 成人欧美激情亚洲日韩蜜臀| 在线 | 一区二区三区| 成年片色大黄全免费网站久久| 动漫精品中文无码卡通动漫 | 色老头在线一区二区三区| 永久免费观看美女裸体的网站| 国产一本一道久久香蕉| 高潮毛片无遮挡高清免费视频 | 特大黑人巨交吊性XXXX| 久久99精品久久久久久野外| 纯爱无遮挡H肉动漫| 人妻丰满熟妇av无码区HD| 国产精品嫩草影院永久…| 草草永久地址发布页①| 久久99精品久久久久久HB无码| 成人女人A级毛片免费软件| 秋霞久久国产精品电影院| 国产成人一区二区三区APP| 人妻AV无码专区| 双腿高潮抽搐喷白浆视频| А√天堂 地址 在线| 极品尤物一区二区三区| 精品无码成人片一区二区| 人妻无码AⅤ中文字幕日韩| 曰本真人性做爰ⅩXX| 成人爽A毛片免费| 大荫蒂又大又长又硬又紧| 国产丰满老熟女重口对白| 狠狠婷婷色五月中文字幕| 精品亚洲国产成人AV制服| 国内偷自第一区二区三区| 久久综合给合久久狠狠狠97色| 人人爽人人操人人精品| 女人18毛片A级毛片| 秋霞国产午夜伦午夜无码灬| 老师黑色丝袜被躁翻了AV| 久久久久久精品免费免费自慰| 老熟妇仑乱一区二区视頻| 国产一区二区在线视频| 玩弄放荡人妻一区二区三| 青梅被从小摸到大H补课1视频| 奇米综合四色77777久久| 国产精品美女乱子伦高| 脱了老师内裤猛烈进入的软件| 免费一对一真人视频| 亚洲AV永久中文无码精品综合| 久久久久久九九精品久| 熟妇人妻中文字幕无码老熟妇| 国产精品成人永久在线四虎| 少妇丰满爆乳被呻吟进入| 国产成人综合久久精品推最新| 日本中文字幕乱码免费| 西方最大但人文艺术| 中国老妇XXXX性开放| 丰满少妇高潮惨叫在线观看| 狠狠躁天天躁中文字幕| 精品人妻一区二区三区四区九九| 人善交VIDEOS欧美3D| 强行糟蹋人妻HD中文字幕| 日韩不卡手机视频在线观看| 日韩AV无码久久精品免费 | 内射中出日韩无国产剧情| 中文字幕日产无线码一区| 日本高清视频色WWWWWW色| 乌克兰少妇XXXX做受野外| 亚洲丰满熟妇XXXX在线观看| 亚洲中久无码永久在线观看同| 成人亚洲欧美成ΑⅤ人在线观看| 高清拍拍拍无挡国产精品| 丰满大屁股BWWBWWBWW| 日日摸夜夜添夜夜添亚洲女人| 欧美人与ZOZOXXXX视频| 丰满爆乳一区二区三区| 乳荡的小痍子免费播放| 国产精品无码无卡在线观看久| W永久939W78W78W乳液| 女BBBB槡BBBB槡BBBB| 中文无码一区二区不卡ΑV| 日韩乱码人妻无码超清蜜桃| 教官在我腿间疯狂驰聘视频| 被多人玩弄的烂货苏妖精| 精品熟女AV少妇免费久久自慰| 无码午夜人妻一区二区不卡视频| 国产日韩未满十八禁止观看| 人妻波多野结衣爽到喷水| 亚洲中文字幕无码不卡电影 | 亚洲色成人一区二区三区小说| 欧美free叉叉叉叉极品少妇| 亚洲精品无码专区在线播放| 国产精品JIZZ在线观看| 狠狠色噜噜狠狠亚洲AV| 欧美性猛交XXXX乱大交视频| 性一交一乱一色一视频| 亚洲AV无码一区二区三区网址| 公粗挺进了我的密道在线观看| 美女张开腿黄网站免费| 精品一区二区三区在线播放视频| 旧里番6080在线观看| 久久久久久精品成人网站蜜臀| 欧美性猛交一区二区| 久久久久亚洲AV综合仓井空| 精品影片在线观看的网站| 国产激情久久久久久熟女老人| 国产精品无码专区AV在线播放| 高清拍拍拍无挡国产精品| XXXXX18日本人HDXX| 欧美自拍亚洲综合在线| 自慰无码一区二区三区| 欧洲熟妇色XXXXⅩ欧美老妇天| 激情爆乳一区二区三区| 亚洲A∨无码无在线观看| 内射人妻无码色AV无码| 又黄又硬又湿又刺激视频免费| 丝瓜秋葵草莓香蕉榴莲绿| 国精产品砖一区二区三区糖心| 无线乱码A区B区C区| 国产成人午夜在线视频A站| 无码少妇一区二区浪潮免费 | 狠狠婷婷色五月中文字幕| 性色AV一区二区三区无码| 丰满妇女强高潮18ⅩXXX在线| 男友把舌头都伸进我的嘴巴里了| 嗯…啊 摸 湿 奶头免费视频| 视频视频APP在线看| 色悠久久久久综合网伊| 亚洲精品成人AV在线| 又黄又无遮挡AAAAA毛片| 差差差很疼视频30分钟无掩盖| 国产男女猛烈无遮挡免费视频| 久久精品香蕉绿巨人登场| 久久久久久亚洲精品无码| 极品无码AV国模在线观看| 国产成人无码精品XXXX网站| 自拍亚洲综合在线精品| 乳荡的小痍子免费播放| 狠狠躁天天躁中文字幕| 锕锕锕锕锕锕锕好疼免费视频| YIN荡到骨子里的SAO货| 欧洲美女粗暴交视频| 国产果冻豆传媒麻婆精东影视| 草棚CAOPORON已满18进| 女人18毛片水真多免费看| 锕锕锕锕锕锕锕好痛免费网址| 无码人妻精一区二区三区老牛| 麻豆传播媒体APP官网在线观看 | 锕锕锕锕锕锕锕好疼免费视频| 色视频综合无码一区二区三区| 国产一区二区三区精品视频| 亚洲AV片毛片成人观看| 公交车强摁做开腿呻吟| 久久久久久久久精品无码中文字幕 | 老阿姨哔哩哔哩B站肉片茄子芒果 老师黑色丝袜被躁翻了AV | 久久成人A毛片免费观看网站| 成 人 黄 色 网 站 在线观| 久久久久久精品成人网站蜜臀| 亚洲美女国产精品久久久久久久久| 久久成人无码专区| 玩弄JAPAN白嫩少妇HD小说| 幼儿HIPHOP仙踪林的| 国产9 1在线 | 欧洲| 国产精品无码一区二区三区在| 强被迫伦姧在线观看无码| 日本适合十八岁以上的护肤品男 | 小婷又软又嫩又紧水又多| 国产在线视频一区二区三区| 国产午夜精品免费一区二区三区| 狠狠色噜噜狠狠亚洲AV| 国产精品视频色拍拍| 亚洲AV无码乱码国产精品老妇| 天堂√中文最新版在线中文| 日韩精品人妻中文字幕有码| 美女图片禁欲系高级感| 嗯啊开小嫩苞好深啊H视频| 伊人久久精品无码麻豆一区| 欧美人文艺术欣赏PPT背景| 国产成人精品午夜福利| 日韩乱码人妻无码超清蜜桃| 饭桌上故意张开腿让公在线观看| 天堂中文在线最新版| 国产成人无码A区在线观看视频| 幼儿稀缺区超清幼儿做的网站 | 午夜无码伦费影视在线观看| 久久99精品久久久久久HB无码| 差差差很疼视频30分钟无掩盖| 日本XXXX色视频在线观看免费,| 欧亚精品一区三区免费| 亚洲熟妇无码乱子AV电影| 韩国三级中文字幕HD| 人妻 白嫩 蹂躏 惨叫| 亚洲日本一本DVD高清| 岳女二人名器共侍一夫的出处| 久久精品无码一区二区日韩AV| 挽起裙子跨开双腿坐下去| 亚洲AV永久无码精品无码网站| らだ天堂√在线中文WWW| 成人看片黄APP免费看软件 | 久久久久久精品免费免费自慰| 西方37大但人文艺术A管77| 亚洲AV成人综合五月天在线观看| 亚洲日韩欧洲无码A∨夜夜| 草莓影视在线观看视频| 脱了老师内裤猛烈进入的软件| 日本XXXX裸体XXXX自慰| 国产午夜亚洲精品国产成人| 国产成人年无码AV片在线观看| А√天堂资源8在线官网地址| 西方44大但人文艺术是什么东西| 熟妇人妻无乱码中文字幕| 久久寂寞少妇成人内射| 涨乳催乳改造调教公主| 哦┅┅快┅┅用力啊┅┅在线观看| 国产欧美日韩专区发布| 日韩精品一区二区三区中文| 公车上玩弄白嫩少妇| 麻豆传播媒体APP大全免费版| 岛国AV动作片免费观看| 国产一区二区三区久久精品| 小S货又想挨C了叫大声点小| 国产成人牲交在线观看视频| 女的把腿张开男的往里面插| 无套内谢的新婚少妇国语播放| 黑人狂虐中国人妻陈艳| 久久寂寞少妇成人内射| 日本适合18岁以上的护肤品| 又大又粗的久久久精品少妇AV| 极品新婚夜少妇真紧| 国产成人无码18禁午夜福利网址| 精品久久久久久人妻无码中文字幕| 人人妻人人澡人人爽不卡视频| 人妻丰满熟妇av无码区HD| 嫩草在线视频WWW免费看| 久久精品人人做人人综合试看| 精品一区二区三区在线播放视频 | 纯爱无遮挡H肉动漫| 对白脏话肉麻粗话AⅤ| 草草永久地址发布页①| 小SB是不是想被C了| 免费女性裸体啪啪无遮挡网站 | 男阳茎进女阳道啪啪| 久久中文字幕无码专区| 丰满人妻被公侵犯完整版| 无码YY4800亚洲私人影院| 国产精品久久久亚洲| 日本欧美大码A在线观看| 高清播放器欧美大片| 青青青国产免A在线观看| 一面亲上边一面膜下边| 国产精品美女久久久| 内射射满骚B含着小说| 余年周婉小说全文免费阅读完整版 | 国产福利在线 | 传媒| 亚洲AV无码专区在线观看成人 | 精品久久久久久无码人妻蜜桃| 午夜三级A三级三点窝| 中文无码乱人伦中文视频播放| 国产精品扒开腿做爽爽爽 |