精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

《精通react/vue組件設計》之配合React Portals實現一個功能強大的抽屜組件

開發 前端
作為數據驅動的領導者react/vue等MVVM框架的出現,幫我們減少了工作中大量的冗余代碼, 一切皆組件的思想深得人心. 為了讓工程師們有更多的時間去考慮業務和產品迭代,我們不得不掌握高質量組件設計的思路和方法.

[[390593]]

前言

本文是筆者寫組件設計的第六篇文章,內容依次從易到難,今天會用到react的高級API React Portals,它也是很多復雜組件必用的方法之一. 通過組件的設計過程,大家會接觸到一個完成健壯的組件設計思路和方法,也能在實現組件的過程逐漸對react/vue的高級知識和技巧有更深的理解和掌握,并且在企業實際工作做游刃有余.

  • 之所以會寫組件設計相關的文章,是因為作為一名前端優秀的前端工程師,面對各種繁瑣而重復的工作,我們不應該按部就班的去"辛勤勞動",而是要根據已有前端的開發經驗,總結出一套自己的高效開發的方法.

作為數據驅動的領導者react/vue等MVVM框架的出現,幫我們減少了工作中大量的冗余代碼, 一切皆組件的思想深得人心. 為了讓工程師們有更多的時間去考慮業務和產品迭代,我們不得不掌握高質量組件設計的思路和方法.所以筆者將花時間去總結各種業務場景下的組件的設計思路和方法,并用原生框架的語法去實現各種常用組件的開發,希望能讓前端新手或者有一定工作經驗的朋友能有所收獲.

如果對于react/vue組件設計原理不熟悉的,可以參考我的之前寫的組件設計系列文章:

  • 《精通react/vue組件設計》之5分鐘實現一個Tag(標簽)組件和Empty(空狀態)組件
  • 《精通react/vue組件設計》之用純css打造類materialUI的按鈕點擊動畫并封裝成react組件
  • 《精通react/vue組件設計》之快速實現一個可定制的進度條組件
  • 《精通react/vue組件設計》之基于jsoneditor二次封裝一個可實時預覽的json編輯器組件(react版)

正文

在開始組件設計之前希望大家對css3和js有一定的基礎,并了解基本的react/vue語法.我們先看看實現后的組件效果:

圖片

1. 組件設計思路

按照之前筆者總結的組件設計原則,我們第一步是要確認需求. 一個抽屜(Drawer)組件會有如下需求點:

  • 能控制抽屜是否可見
  • 能手動配置抽屜的關閉按鈕
  • 能控制抽屜的打開方向
  • 關閉抽屜時是否銷毀里面的子元素(這個問題是工作中頻繁遇到的問題)
  • 指定 Drawer 掛載的 HTML 節點, 可以將抽屜掛載在任何元素上
  • 點擊蒙層可以控制是否允許關閉抽屜
  • 能控制遮罩層的展示
  • 能自定義抽屜彈出層樣式
  • 可以設置抽屜彈出層寬度
  • 能控制彈出層層級
  • 能控制抽屜彈出方向(上下左右)
  • 點擊關閉按鈕時能提供回調供開發者進行相關操作

需求收集好之后,作為一個有追求的程序員, 會得出如下線框圖:


對于react選手來說,如果沒用typescript,建議大家都用PropTypes, 它是react內置的類型檢測工具,我們可以直接在項目中導入. vue有自帶的屬性檢測方式,這里就不一一介紹了.

通過以上需求分析, 是不是覺得一個抽屜組件要實現這么多功能很復雜呢? 確實有點復雜,但是不要怕,有了上面精確的需求分析,我們只需要一步步按照功能點實現就好了.對于我們常用的table組件, modal組件等其實也需要考慮到很多使用場景和功能點, 比如antd的table組件暴露了幾十個屬性,如果不好好理清具體的需求, 實現這樣的組件是非常麻煩的.接下來我們就來看看具體實現.

2. 基于react實現一個Drawer組件

2.1. Drawer組件框架設計

首先我們先根據需求將組件框架寫好,這樣后面寫業務邏輯會更清晰:

  1. import PropTypes from 'prop-types' 
  2. import styles from './index.less' 
  3.  
  4. /** 
  5.  * Drawer 抽屜組件 
  6.  * @param {visible} bool 抽屜是否可見 
  7.  * @param {closable} bool 是否顯示右上角的關閉按鈕 
  8.  * @param {destroyOnClose} bool 關閉時銷毀里面的子元素 
  9.  * @param {getContainer} HTMLElement 指定 Drawer 掛載的 HTML 節點, false 為掛載在當前 dom 
  10.  * @param {maskClosable} bool 點擊蒙層是否允許關閉抽屜 
  11.  * @param {mask} bool 是否展示遮罩 
  12.  * @param {drawerStyle} object 用來設置抽屜彈出層樣式 
  13.  * @param {width} number|string 彈出層寬度 
  14.  * @param {zIndex} number 彈出層層級 
  15.  * @param {placement} string 抽屜方向 
  16.  * @param {onClose} string 點擊關閉時的回調 
  17.  */ 
  18. function Drawer(props) { 
  19.   const {  
  20.     closable = true,  
  21.     destroyOnClose,  
  22.     getContainer = document.body,  
  23.     maskClosable = true,  
  24.     mask = true,  
  25.     drawerStyle,  
  26.     width = '300px'
  27.     zIndex = 10, 
  28.     placement = 'right',  
  29.     onClose, 
  30.     children 
  31.   } = props 
  32.  
  33.   const childDom = ( 
  34.     <div className={styles.xDrawerWrap}> 
  35.       <div className={styles.xDrawerMask} ></div> 
  36.       <div  
  37.         className={styles.xDrawerContent}  
  38.         { 
  39.           children 
  40.         } 
  41.         { 
  42.           !!closable && <span className={styles.xCloseBtn}>X</span> 
  43.         } 
  44.       </div> 
  45.     </div> 
  46.   ) 
  47.   return childDom 
  48.  
  49. export default Drawer 

 有了這個框架,我們來一步步往里面實現內容吧.

2.2 實現visible, closable, onClose, mask, maskClosable, width, zIndex, drawerStyle

之所以要先實現這幾個功能,是因為他們實現都比較簡單,不會牽扯到其他復雜邏輯.只需要對外暴露屬性并使用屬性即可. 具體實現如下:

  1. function Drawer(props) { 
  2.   const {  
  3.     closable = true,  
  4.     destroyOnClose,  
  5.     getContainer = document.body,  
  6.     maskClosable = true,  
  7.     mask = true,  
  8.     drawerStyle,  
  9.     width = '300px'
  10.     zIndex = 10, 
  11.     placement = 'right',  
  12.     onClose, 
  13.     children 
  14.   } = props 
  15.  
  16.   let [visible, setVisible] = useState(props.visible) 
  17.  
  18.   const handleClose = () => { 
  19.     setVisible(false
  20.     onClose && onClose() 
  21.   } 
  22.  
  23.   useEffect(() => { 
  24.     setVisible(props.visible) 
  25.   }, [props.visible]) 
  26.  
  27.   const childDom = ( 
  28.     <div  
  29.       className={styles.xDrawerWrap}  
  30.       style={{ 
  31.         width: visible ? '100%' : '0'
  32.         zIndex 
  33.       }} 
  34.     > 
  35.       { !!mask && <div className={styles.xDrawerMask} onClick={maskClosable ? handleClose : null}></div> } 
  36.       <div  
  37.         className={styles.xDrawerContent}  
  38.         style={{ 
  39.           width, 
  40.           ...drawerStyle 
  41.         }}> 
  42.         { children } 
  43.         { 
  44.           !!closable && <span className={styles.xCloseBtn} onClick={handleClose}>X</span> 
  45.         } 
  46.       </div> 
  47.     </div> 
  48.   ) 
  49.   return childDom 

 上述實現過程值得注意的就是我們組件設計采用了react hooks技術, 在這里用到了useState, useEffect, 如果大家不懂的可以去官網學習, 非常簡單,如果有不懂的可以和筆者交流或者在評論區提問. 抽屜動畫我們通過控制抽屜內容的寬度來實現,配合overflow:hidden, 后面我會單獨附上css代碼供大家參考.

2.3 實現destroyOnClose

destroyOnClose主要是用來清除組件緩存,比較常用的場景就是輸入文本,比如當我是的抽屜的內容是一個表單創建頁面時,我們關閉抽屜希望表單中用戶輸入的內容清空,保證下次進入時用戶能重新創建, 但是實際情況是如果我們不銷毀抽屜里的子組件, 子組件內容不會清空,用戶下次打開時開始之前的輸入,這明顯不合理. 如下圖所示:

 

要想清除緩存,首先就要要內部組件重新渲染,所以我們可以通過一個state來控制,如果用戶明確指定了關閉時要銷毀組件,那么我們就更新這個state,從而這個子元素也就不會有緩存了.具體實現如下:

  1. function Drawer(props) { 
  2.   // ... 
  3.   let [isDesChild, setIsDesChild] = useState(false
  4.  
  5.   const handleClose = () => { 
  6.     // ... 
  7.     if(destroyOnClose) { 
  8.       setIsDesChild(true
  9.     } 
  10.   } 
  11.  
  12.   useEffect(() => { 
  13.     // ... 
  14.     setIsDesChild(false
  15.   }, [props.visible]) 
  16.  
  17.   const childDom = ( 
  18.     <div className={styles.xDrawerWrap}> 
  19.       <div className={styles.xDrawerContent}  
  20.         { 
  21.           isDesChild ? null : children 
  22.         } 
  23.       </div> 
  24.     </div> 
  25.   ) 
  26.   return childDom 

 上述代碼中我們省略了部分不相關代碼, 主要來關注isDesChild和setIsDesChild, 這個屬性用來根據用戶傳入的destroyOnClose屬性倆判斷是否該更新這個state, 如果destroyOnClose為true,說明要更新,那么此時當用戶點擊關閉按鈕的時候, 組件將重新渲染, 在用戶再次點開抽屜時, 我們根據props.visible的變化,來重新讓子組件渲染出來,這樣就實現了組件卸載的完整流程.

2.4 實現getContainer

getContainer主要用來控制抽屜組件的渲染位置,默認會渲染到body下, 為了提供更靈活的配置,我們需要讓抽屜可以渲染到任何元素下,這樣又怎么實現呢? 這塊實現我們可以采用React Portals來實現,具體api介紹如下:

  • Portal 提供了一種將子節點渲染到存在于父組件以外的 DOM 節點的優秀的方案。第一個參數(child)是任何可渲染的 React 子元素,例如一個元素,字符串或 fragment。第二個參數(container)是一個 DOM 元素。

具體使用如下:

  1. render() { 
  2.   // `domNode` 是一個可以在任何位置的有效 DOM 節點。 
  3.   return ReactDOM.createPortal( 
  4.     this.props.children, 
  5.     domNode 
  6.   ); 

所以基于這個api我們就能把抽屜渲染到任何元素下了, 具體實現如下:

  1. const childDom = ( 
  2.     <div  
  3.       className={styles.xDrawerWrap}  
  4.       style={{ 
  5.         position: getContainer === false ? 'absolute' : 'fixed'
  6.         width: visible ? '100%' : '0'
  7.         zIndex 
  8.       }} 
  9.     > 
  10.       { !!mask && <div className={styles.xDrawerMask} onClick={maskClosable ? handleClose : null}></div> } 
  11.       <div  
  12.         className={styles.xDrawerContent}  
  13.         style={{ 
  14.           width, 
  15.           [placement]: visible ? 0 : '-100%'
  16.           ...drawerStyle 
  17.         }}> 
  18.         { 
  19.           isDesChild ? null : children 
  20.         } 
  21.         { 
  22.           !!closable && <span className={styles.xCloseBtn} onClick={handleClose}>X</span> 
  23.         } 
  24.       </div> 
  25.     </div> 
  26.   ) 
  27.  
  28.   return getContainer === false ? childDom  
  29.             : ReactDOM.createPortal(childDom, getContainer) 

 因為這里getContainer要支持3種情況,一種是用戶不配置屬性,那么默認就掛載到body下,還有就是用戶傳的值為false, 那么就為最近的父元素, 他如果傳一個dom元素,那么將掛載到該元素下,所以以上代碼我們會分情況考慮,還有一點要注意,當抽屜打開時,我們要讓父元素溢出隱藏,不讓其滾動,所以我們在這里要設置一下:

  1. useEffect(() => { 
  2.     setVisible(() => { 
  3.       if(getContainer !== false && props.visible) { 
  4.         getContainer.style.overflow = 'hidden' 
  5.       } 
  6.       return props.visible 
  7.     }) 
  8.     setIsDesChild(false
  9.   }, [props.visible, getContainer]) 

當關閉時恢復邏輯父級的overflow, 避免影響外部樣式:

  1. const handleClose = () => { 
  2.     onClose && onClose() 
  3.     setVisible((prev) => { 
  4.       if(getContainer !== false && prev) { 
  5.         getContainer.style.overflow = 'auto' 
  6.       } 
  7.       return false 
  8.     }) 
  9.     if(destroyOnClose) { 
  10.       setIsDesChild(true
  11.     } 
  12.   } 

2.5 實現placement

placement主要用來控制抽屜的彈出方向, 可以從左彈出,也可以從右彈出, 實現過程也比較簡單,我們主要要更具屬性動態修改定位屬性即可,這里我們會用到es新版的新特性,對象的變量屬性. 核心代碼如下:

  1. <div  
  2.   className={styles.xDrawerContent}  
  3.   style={{ 
  4.     width, 
  5.     [placement]: visible ? 0 : '-100%'
  6.     ...drawerStyle 
  7.     }}> 
  8.  </div> 

這樣,無論是上下左右,都可以完美實現了.

2.6 健壯性支持, 我們采用react提供的propTypes工具:

  1. import PropTypes from 'prop-types' 
  2. // ... 
  3. Drawer.propTypes = { 
  4.   visible: PropTypes.bool, 
  5.   closable: PropTypes.bool,  
  6.   destroyOnClose: PropTypes.bool,  
  7.   getContainer: PropTypes.element,  
  8.   maskClosable: PropTypes.bool,  
  9.   mask: PropTypes.bool,  
  10.   drawerStyle: PropTypes.object,  
  11.   width: PropTypes.oneOfType([ 
  12.     PropTypes.string, 
  13.     PropTypes.number 
  14.   ]), 
  15.   zIndex: PropTypes.number, 
  16.   placement: PropTypes.string,  
  17.   onClose: PropTypes.func 

關于prop-types的使用官網上有很詳細的案例,這里說一點就是oneOfType的用法, 它用來支持一個組件可能是多種類型中的一個. 組件相關css代碼如下:

  1. .xDrawerWrap { 
  2.   top: 0; 
  3.   height: 100vh; 
  4.   overflow: hidden; 
  5.   .xDrawerMask { 
  6.     position: absolute
  7.     left: 0; 
  8.     right: 0; 
  9.     top: 0; 
  10.     bottom: 0; 
  11.     background-color: rgba(0, 0, 0, .5); 
  12.   } 
  13.   .xDrawerContent { 
  14.     position: absolute
  15.     top: 0; 
  16.     padding: 16px; 
  17.     height: 100%; 
  18.     transition: all .3s; 
  19.     background-color: #fff; 
  20.     box-shadow: 0 0 20px rgba(0,0,0, .2); 
  21.     .xCloseBtn { 
  22.       position: absolute
  23.       top: 10px; 
  24.       right: 10px; 
  25.       color: #ccc; 
  26.       cursor: pointer; 
  27.     } 
  28.   } 

通過以上步驟, 一個功能強大的的drawer組件就完成了,關于代碼中的css module和classnames的使用大家可以自己去官網學習,非常簡單.如果不懂的可以在評論區提問,筆者看到后會第一時間解答.

擴展

目前筆者已經將完成的組件庫發布到npm上了,大家可以通過npm安裝包的方式使用:

  1. npm i @alex_xu/xui 
  2.  
  3. // 使用 
  4. import { Button, Alert } from '@alex_xu/xui' 

在線文檔地址: xui——基于react的輕量級UI組件庫

npm包地址: @alex_xu/xui

最后

后續筆者已經實現

  • modal(模態窗),
  • alert(警告提示),
  • badge(徽標),
  • table(表格),
  • tooltip(工具提示條),
  • Skeleton(骨架屏),
  • Message(全局提示),
  • form(form表單),
  • switch(開關),
  • 日期/日歷,
  • 二維碼識別器組件

等組件, 來復盤筆者多年的組件化之旅.

 

責任編輯:姜華 來源: 趣談前端
相關推薦

2021-10-17 20:37:44

組件DrawerReact

2023-09-05 20:17:18

typescriptPropTypesreact

2023-04-28 09:30:40

vuereact

2022-03-10 09:00:37

提醒框ReactVue

2023-05-17 10:05:35

組件設計(Modal)組件

2021-06-21 15:49:39

React動效組件

2023-12-21 10:26:30

??Prettier

2022-05-13 08:48:50

React組件TypeScrip

2024-01-09 09:06:13

2019-07-22 10:42:11

React組件前端

2022-09-07 16:07:17

前端React

2024-03-20 09:31:00

圖片懶加載性能優化React

2020-10-21 08:38:47

React源碼

2019-07-20 23:30:48

開發技能代碼

2023-08-29 17:43:39

人工智能Fooocus

2017-05-17 15:50:34

開發前端react

2017-02-28 21:57:05

React組件

2021-03-18 08:00:55

組件Hooks React

2021-06-07 08:41:59

React異步組件

2022-05-11 07:50:15

React UI組件庫前端
點贊
收藏

51CTO技術棧公眾號

国产三级电影在线播放| 苍井空浴缸大战猛男120分钟| 一区二区冒白浆视频| 日韩乱码一区二区三区| 一区二区中文字| 日韩av有码在线| 国产又粗又长又大的视频| 中文在线字幕免费观看| 91美女精品福利| 国产在线观看一区二区三区| 欧美日韩人妻精品一区二区三区| 同性恋视频一区| 91精品国产综合久久久久| 老太脱裤让老头玩ⅹxxxx| 北岛玲一区二区三区| 懂色av一区二区在线播放| 国产精欧美一区二区三区| 欧美丰满熟妇bbbbbb| 影视先锋久久| 精品福利一二区| 免费一区二区三区在线观看| 国产黄大片在线观看| 亚洲天堂成人网| 秋霞久久久久久一区二区| 亚洲黄色在线观看视频| 蜜臀av一级做a爰片久久| 国内精品小视频| www日韩在线| 成人激情诱惑| 亚洲成色www8888| 91av视频免费观看| 日韩色淫视频| 欧美日在线观看| 69精品丰满人妻无码视频a片| 成年人在线看| 国产亚洲欧美色| 九九九九久久久久| 亚洲国产精品欧美久久| 精品无人码麻豆乱码1区2区| 国产黑人绿帽在线第一区| 制服.丝袜.亚洲.中文.综合懂色| www.youjizz.com在线| av老司机在线观看| 久久久国产一区二区三区四区小说 | 久久99精品久久久久久三级 | 久久99国产乱子伦精品免费| 欧日韩不卡在线视频| 国产精品99re| 综合日韩在线| 久久久久北条麻妃免费看| 免费看91的网站| 国产乱码精品一区二区三区四区| 日韩av影视综合网| 成人影视免费观看| 亚洲电影一级片| 日韩精品中文字幕有码专区| 五月天丁香社区| 99精品国产一区二区三区2021| 日韩视频一区在线观看| 免费看91视频| 久久夜色电影| 亚洲免费精彩视频| 手机在线看片日韩| 亚洲丁香日韩| 国产一区二区三区直播精品电影| 欧美剧在线免费观看网站| 伊人久久在线观看| 蜜乳av一区| 五月婷婷综合网| 久久久噜噜噜www成人网| 不卡av影片| 欧美三级视频在线| 99999精品| 国产精品jk白丝蜜臀av小说| 日韩国产精品亚洲а∨天堂免| 国产中文字幕一区二区| 免费观看久久av| 深夜精品寂寞黄网站在线观看| 国产大屁股喷水视频在线观看| 97人人精品| 欧美激情精品久久久久久黑人 | 亚洲综合中文字幕在线观看| www.av黄色| 97久久超碰国产精品| 日本一区二区免费看| 国产超级va在线视频| 亚洲福利一区二区| 欧美伦理片在线看| 精品视频一区二区三区| 日韩av在线免费| 亚洲图片第一页| 欧美深夜福利| 国产精品久久综合av爱欲tv| 国产欧美日韩综合精品一区二区三区| 国产白丝精品91爽爽久久| 久久精品第九区免费观看 | 99草草国产熟女视频在线| 亚洲狼人综合| 亚洲精品电影网| 亚洲天堂网av在线| 亚洲一区一卡| 亚洲tv在线观看| 国产女主播一区二区三区| 久久精品国产亚洲av高清色欲| 中文亚洲免费| 亚洲综合日韩在线| 精品推荐蜜桃传媒| 一区二区三区av电影| 男人的天堂日韩| 综合中文字幕| 日韩中文字幕在线| 亚洲欧美一区二区三区在线观看| 国产一区福利在线| 欧美下载看逼逼| 国语对白在线刺激| 欧美日本不卡视频| 公侵犯人妻一区二区三区| 亚洲天天综合| 国产精品久久久久一区二区| av女名字大全列表| 一区二区三区资源| 天天干天天操天天做| 亚洲精品白浆高清| 久久久久久国产精品| 亚洲系列在线观看| 国产校园另类小说区| 成人一区二区免费视频| 国产精品免费精品自在线观看| 亚洲色图av在线| 综合激情网五月| 成人18视频在线播放| 男人草女人视频| 色综合视频一区二区三区日韩| 亚洲女人天堂视频| 天堂网一区二区三区| 国产98色在线|日韩| 日日噜噜噜夜夜爽爽| 99riav视频一区二区| 亚洲色图13p| 色老头在线视频| 2021中文字幕一区亚洲| 黄页免费在线观看视频| 动漫av一区| 欧美劲爆第一页| www.蜜臀av.com| 亚洲精品免费电影| 亚洲高清视频免费| 亚洲欧美色图| 亚洲最大的免费| 欧美成人精品一区二区男人看| 91久久精品国产91性色tv| 中文字幕国产综合| 丝瓜av网站精品一区二区| 蜜桃91精品入口| 欧美大片免费高清观看| 国产一区二区激情| 国产精品国产精品国产| 中文字幕av一区 二区| 九九热在线免费| 亚洲经典一区| 国产精品免费在线播放| 国内精彩免费自拍视频在线观看网址 | 国产青草视频在线观看| 亚洲精品a区| 国内外成人免费激情在线视频网站| 国产成人手机在线| 精品久久久久久国产91| 欧美熟妇精品黑人巨大一二三区| 美女尤物久久精品| 亚洲午夜激情| 亚洲91网站| 欧美亚洲视频在线看网址| 男女污污视频在线观看| 欧美色视频在线观看| 亚洲一二三在线观看| 成人蜜臀av电影| 国产精品免费成人| 天天操夜夜操国产精品| 风间由美一区二区三区| www.成人爱| 色妞欧美日韩在线| 狠狠人妻久久久久久综合麻豆| 欧美日韩国产一区中文午夜| 国产精品揄拍100视频| 另类小说视频一区二区| 久久综合亚洲精品| 日韩极品少妇| 91亚洲人电影| 成人小电影网站| www日韩欧美| 日韩一级片免费观看| 在线观看精品一区| 久久久久久久久久久久久久免费看| xfplay精品久久| 一个色综合久久| av成人天堂| 正在播放一区二区三区| 牛牛影视久久网| 成人a级免费视频| 超碰超碰人人人人精品| 操91在线视频| 国产私人尤物无码不卡| 日韩精品一区二区三区swag | 伊人久久久久久久久久久久久久| www.99精品| 在线观看日本www| 久久久青草婷婷精品综合日韩 | 老司机一区二区三区| 亚洲最新免费视频| 欧美禁忌电影网| 国产精品日韩高清| 成人污版视频| 国产精品久久久久久影视| av中文资源在线资源免费观看| 色999日韩欧美国产| 三级av在线| 精品国产三级a在线观看| 在线播放亚洲精品| 色欧美片视频在线观看在线视频| 欧美日韩精品在线观看视频 | 成人在线一区二区三区| 日本不卡一区二区在线观看| 欧美一级网站| 国产不卡一区二区视频| 影音先锋日韩在线| 亚州欧美一区三区三区在线 | 免费久久久久久| 欧美日韩高清| 欧美一区2区三区4区公司二百| 国产精品久久久网站| 51成人做爰www免费看网站| 欧美日韩亚洲国产| 日韩av免费在线播放| 91高清视频在线观看| 欧美大成色www永久网站婷| 五月香视频在线观看| 一区二区三区四区在线观看视频| 天堂成人在线| 精品国产亚洲在线| 超碰免费在线97| 日韩视频不卡中文| 精品人妻无码一区二区| 91精品国产综合久久香蕉的特点| 中文字幕黄色av| 欧美日韩在线三区| 在线观看黄色网| 欧美日韩精品三区| 在线免费看av片| 51精品视频一区二区三区| 亚洲一区二区三区高清视频| 欧美色视频一区| 在线免费观看日韩视频| 91麻豆精品国产91久久久久| 91片黄在线观看喷潮| 正在播放一区二区| 国产www免费观看| 日韩欧美一区在线| 亚洲欧美另类综合| 亚洲精品成a人在线观看| 性感美女视频一二三| 亚洲欧美国产精品| 波多野结衣在线影院| 久久综合久中文字幕青草| 18视频在线观看| 国内揄拍国内精品| 欧美三区四区| 国产在线观看91精品一区| 精品一区二区三区亚洲| 成人资源av| 免费看av成人| 一区二区三区的久久的视频| 欧美在线高清| 日韩av黄色网址| 男女男精品视频网| 日本女人性视频| av电影天堂一区二区在线观看| 白丝女仆被免费网站| 中文字幕免费在线观看视频一区| 欧美一级片在线视频| 一区二区三区丝袜| 久久久成人免费视频| 欧美日韩国产高清一区二区| 亚洲精品喷潮一区二区三区| 亚洲欧美国产精品专区久久| 毛片网站在线免费观看| 久久久久久久久久久成人| av综合电影网站| 亚洲精品日韩av| 久久亚洲AV无码| 伊人青青综合网| 国产av熟女一区二区三区| 一本色道88久久加勒比精品| 国产高清视频网站| 国产69精品久久久久毛片| 在线不卡av电影| 一区二区在线看| 狠狠狠狠狠狠狠| 日韩一区二区三区四区五区六区 | 日韩一区中文| 国产无套精品一区二区| 凹凸成人精品亚洲精品密奴| 美女av免费观看| 日本不卡的三区四区五区| 2025中文字幕| 国产精品美女久久久久aⅴ国产馆 国产精品美女久久久久av爽李琼 国产精品美女久久久久高潮 | 亚洲欧美视频在线播放| 国产精品麻豆视频| 日韩成人免费观看| 91精品欧美一区二区三区综合在| 青青草观看免费视频在线| 不卡av日日日| 国产精品99精品一区二区三区∴| 国产一区二区久久久| 久久久久久久久久久久久久| 37pao成人国产永久免费视频| 国产乱码精品一区二区三区av | 国产成人精品综合久久久久99| 国产日韩欧美精品一区| 好吊操这里只有精品| 制服丝袜在线91| yiren22亚洲综合伊人22| 91精品国产色综合久久不卡98口| 高清一区二区| 在线观看一区二区三区三州| 日韩vs国产vs欧美| 精品国产无码在线观看| 婷婷开心激情综合| www.五月激情| 久久在线视频在线| 亚洲日韩中文字幕一区| 一本久道久久综合| 捆绑紧缚一区二区三区视频| 国产熟女一区二区| 色狠狠桃花综合| 免费在线稳定资源站| 欧美在线不卡区| 丝袜美腿综合| 日本在线xxx| 成人av在线观| 国产一级精品视频| 欧美电视剧在线看免费| 天堂av中文在线| 97神马电影| 中文无码久久精品| 99精品视频免费版的特色功能| 中文字幕一区二区三区四区| 在线观看日批视频| 精品久久久av| 欧美日韩国产一区二区在线观看| 免费观看国产视频在线| 国产精品自产自拍| 久久久久亚洲av片无码下载蜜桃| 日韩精品一区二区三区swag| 好久没做在线观看| 久久精品国产综合精品| 亚洲欧美久久| 日本美女xxx| 欧美精品少妇一区二区三区| 国产成人l区| 动漫一区二区在线| 国产精品久久久久久模特| 亚洲最大成人网站| 欧美在线三级电影| 久草免费在线观看| 春色成人在线视频| 国产精品美女久久久浪潮软件| 国产一二三四五区| 欧美日韩国产另类一区| 污污片在线免费视频| 精品国产一区二区三区麻豆小说 | 一区二区日韩免费看| 欧美成人午夜精品免费| 欧美性大战久久久久久久| 国内外激情在线| 国产一区在线免费| 日韩成人一级大片| 国产色无码精品视频国产| 亚洲第一综合天堂另类专| 日韩av中字| av动漫免费观看| 91在线视频观看| 亚洲怡红院av| 2019中文字幕在线| 久久综合成人| 一起草在线视频| 欧美日韩精品欧美日韩精品一 | 国产精品日韩精品欧美精品| av黄色在线免费观看| 日韩欧美在线观看一区二区三区| 女厕盗摄一区二区三区| 亚洲午夜精品久久久久久浪潮| 国产91高潮流白浆在线麻豆 | 国产人妻精品一区二区三区不卡| 亚洲国产精品99| 日本午夜免费一区二区| 91九色丨porny丨国产jk| 中文字幕一区二区三区在线观看| 人妻偷人精品一区二区三区| 国产精品高潮呻吟视频| 亚洲婷婷在线|