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

從零開發一款輕量級滑動驗證碼插件(深度復盤)

開發 前端
今天繼續和大家分享一款非常有趣且實用的前端實戰項目——從零基于 react + canvas 實現一個滑動驗證碼,并將其發布到 npm 上供他人使用。

[[425863]]

之前一直在分享 低代碼 和 可視化 的文章,其中涉及到很多有意思的知識點和設計思想,今天繼續和大家分享一款非常有趣且實用的前端實戰項目——從零基于 react + canvas 實現一個滑動驗證碼,并將其發布到 npm 上供他人使用。當然如果大家更喜歡 vue 的開發方式,也不用擔心,文中的設計思想和思路都是通用的,如果大家想學習如何封裝 vue 組件并發布到 npm 上,也可以參考我之前的文章: 從零到一教你基于vue開發一個組件庫。

從這個實戰項目中我們可以學到如下知識點:

  • 前端組件設計的基本思路和技巧
  • canvas 基本知識和使用
  • react hooks 基本知識和使用
  • 滑動驗證碼基本設計原理
  • 如何封裝一款可擴展的滑動驗證碼組件
  • 如何使用 dumi 搭建組件文檔
  • 如何發布自己第一個npm組件包

如果你對以上任意知識點感興趣,相信這篇文章都會給你帶來啟發。

效果演示

圖片

滑動驗證組件基本使用和技術實現

上圖是實現的滑動驗證組件的一個效果演示,當然還有很多配置項可以選擇,以便支持更多 定制化 的場景。接下來我先介紹一下如何安裝和使用這款驗證碼插件,讓大家有一個直觀的體驗,然后我會詳細介紹一下滑動驗證碼的實現思路,如果大家有一定的技術基礎,也可以直接跳到技術實現部分。

基本使用

因為 react-slider-vertify 這款組件我已經發布到 npm 上了,所以大家可以按照如下方式安裝和使用:

1.安裝

  1. # 或者 yarn add @alex_xu/react-slider-vertify 
  2. npm i @alex_xu/react-slider-vertify -S 

2.使用

  1. import React from 'react'
  2. import { Vertify } from '@alex_xu/react-slider-vertify'
  3.  
  4. export default () => { 
  5.     return <Vertify  
  6.             width={320} 
  7.             height={160} 
  8.             onSuccess={() => alert('success')}  
  9.             onFail={() => alert('fail')}  
  10.             onRefresh={() => alert('refresh')}  
  11.         /> 
  12. }; 

通過以上兩步我們就可以輕松使用這款滑動驗證碼組件了,是不是很簡單?

當然我也暴露了很多可配置的屬性,讓大家對組件有更好的控制。參考如下:

技術實現

在做這個項目之前我也研究了一些滑動驗證碼的知識以及已有的技術方案,收獲很多。接下來我會以我的組件設計思路來和大家介紹如何用 react 來實現和封裝滑動驗證碼組件,如果大家有更好的想法和建議, 也可以在評論區隨時和我反饋。

1.組件設計的思路和技巧

每個人都有自己設計組件的方式和風格,但最終目的都是更 優雅 的設計組件。這里我大致列舉一下 優雅 組件的設計指標:

  • 可讀性(代碼格式統一清晰,注釋完整,代碼結構層次分明,編程范式使用得當)
  • 可用性(代碼功能完整,在不同場景都能很好兼容,業務邏輯覆蓋率)
  • 復用性(代碼可以很好的被其他業務模塊復用)
  • 可維護性(代碼易于維護和擴展,并有一定的向下/向上兼容性)
  • 高性能

以上是我自己設計組件的考量指標,大家可以參考一下。

另外設計組件之前我們還需要明確需求,就拿滑動驗證碼組件舉例,我們需要先知道它的使用場景(用于登錄注冊、活動、論壇、短信等高風險業務場景的人機驗證服務)和需求(交互邏輯,以什么樣的方式驗證,需要暴露哪些屬性)。

以上就是我梳理的一個大致的組件開發需求,在開發具體組件之前,如果遇到復雜的業務邏輯,我們還可以將每一個實現步驟列舉出來,然后一一實現,這樣有助于整理我們的思路和更高效的開發。

2.滑動驗證碼基本實現原理

在介紹完組件設計思路和需求分析之后,我們來看看滑動驗證碼的實現原理。

我們都知道設計驗證碼的主要目的是為了防止機器非法暴力地入侵我們的應用,其中核心要解決的問題就是判斷應用是誰在操作(人 or 機器),所以通常的解決方案就是隨機識別。

上圖我們可以看到只有用戶手動將滑塊拖拽到對應的鏤空區域,才算驗證成功,鏤空區域的位置是隨機的(隨機性測試這里暫時以前端的方式來實現,更安全的做法是通過后端來返回位置和圖片)。

基于以上分析我們就可以得出一個基本的滑動驗證碼設計原理圖:

接下來我們就一起封裝這款可擴展的滑動驗證碼組件。

3.封裝一款可擴展的滑動驗證碼組件

按照我開發組件一貫的風格,我會先基于需求來編寫組件的基本框架:

  1. import React, { useRef, useState, useEffect, ReactNode } from 'react'
  2.  
  3. interface IVertifyProp { 
  4.     /** 
  5.      * @description   canvas寬度   
  6.      * @default       320 
  7.      */ 
  8.     width:number,  
  9.     /** 
  10.      * @description   canvas高度   
  11.      * @default       160 
  12.      */ 
  13.     height:number,  
  14.     /** 
  15.      * @description   滑塊邊長   
  16.      * @default       42 
  17.      */ 
  18.      l:number, 
  19.      /** 
  20.      * @description   滑塊半徑  
  21.      * @default       9 
  22.      */ 
  23.       r:number, 
  24.      /** 
  25.      * @description   是否可見 
  26.      * @default       true 
  27.      */ 
  28.       visible:boolean, 
  29.      /** 
  30.      * @description   滑塊文本 
  31.      * @default       向右滑動填充拼圖 
  32.      */ 
  33.       text:string | ReactNode, 
  34.       /** 
  35.      * @description   刷新按鈕icon, 為icon的url地址 
  36.      * @default       - 
  37.      */ 
  38.        refreshIcon:string, 
  39.      /** 
  40.      * @description   用于獲取隨機圖片的url地址 
  41.      * @default       https://picsum.photos/${id}/${width}/${height}, 具體參考https://picsum.photos/, 只需要實現類似接口即可 
  42.      */ 
  43.        imgUrl:string, 
  44.     /** 
  45.      * @description   驗證成功回調   
  46.      * @default       ():void => {} 
  47.      */ 
  48.     onSuccess:VoidFunction,  
  49.     /** 
  50.      * @description   驗證失敗回調   
  51.      * @default       ():void => {} 
  52.      */ 
  53.     onFail:VoidFunction,  
  54.     /** 
  55.      * @description   刷新時回調   
  56.      * @default       ():void => {} 
  57.      */ 
  58.     onRefresh:VoidFunction 
  59.  
  60. export default ({  
  61.     width = 320, 
  62.     height = 160, 
  63.     l = 42, 
  64.     r = 9, 
  65.     imgUrl, 
  66.     text, 
  67.     refreshIcon = 'http://yourimgsite/icon.png'
  68.     visible = true
  69.     onSuccess, 
  70.     onFail, 
  71.     onRefresh 
  72.  }: IVertifyProp) => { 
  73.      return <div className="vertifyWrap"
  74.         <div className="canvasArea"
  75.             <canvas width={width} height={height}></canvas> 
  76.             <canvas className="block" width={width} height={height}></canvas> 
  77.         </div> 
  78.         <div className={sliderClass}> 
  79.             <div className="sliderMask"
  80.                 <div className="slider"
  81.                     <div className="sliderIcon">&rarr;</div> 
  82.                 </div> 
  83.             </div> 
  84.             <div className="sliderText">{ textTip }</div> 
  85.         </div> 
  86.         <div className="refreshIcon" onClick={handleRefresh}></div> 
  87.         <div className="loadingContainer"
  88.             <div className="loadingIcon"></div> 
  89.             <span>加載中...</span> 
  90.         </div> 
  91.     </div> 
  92.  } 

以上就是我們組件的基本框架結構。從代碼中可以發現組件屬性一目了然,這都是提前做好需求整理帶來的好處,它可以讓我們在編寫組件時思路更清晰。在編寫好基本的 css 樣式之后我們看到的界面是這樣的:

接下來我們需要實現以下幾個核心功能:

  • 鏤空效果的 canvas 圖片實現
  • 鏤空圖案 canvas 實現
  • 滑塊移動和驗證邏輯實現

上面的描述可能比較抽象,我畫張圖示意一下:

因為組件實現完全采用的 react hooks ,如果大家對 hooks 不熟悉也可以參考我之前的文章:

10分鐘教你手寫8個常用的自定義hooks

一.實現鏤空效果的 canvas 圖片

在開始 coding 之前我們需要對 canvas 有個基本的了解,建議不熟悉的朋友可以參考高效 canvas 學習文檔: Canvas of MDN。

由上圖可知首先要解決的問題就是如何用 canvas 畫不規則的圖形,這里我簡單的畫個草圖:

我們只需要使用 canvas 提供的 路徑api 畫出上圖的路徑,并將路徑填充為任意半透明的顏色即可。建議大家不熟悉的可以先了解如下 api :

  • beginPath() 開始路徑繪制
  • moveTo() 移動筆觸到指定點
  • arc() 繪制弧形
  • lineTo() 畫線
  • stroke() 描邊
  • fill() 填充
  • clip() 裁切路徑

實現方法如下:

  1. const drawPath  = (ctx:any, x:number, y:number, operation: 'fill' | 'clip') => { 
  2.     ctx.beginPath() 
  3.     ctx.moveTo(x, y) 
  4.     ctx.arc(x + l / 2, y - r + 2, r, 0.72 * PI, 2.26 * PI) 
  5.     ctx.lineTo(x + l, y) 
  6.     ctx.arc(x + l + r - 2, y + l / 2, r, 1.21 * PI, 2.78 * PI) 
  7.     ctx.lineTo(x + l, y + l) 
  8.     ctx.lineTo(x, y + l) 
  9.     // anticlockwise為一個布爾值。為true時,是逆時針方向,否則順時針方向 
  10.     ctx.arc(x + r - 2, y + l / 2, r + 0.4, 2.76 * PI, 1.24 * PI, true
  11.     ctx.lineTo(x, y) 
  12.     ctx.lineWidth = 2 
  13.     ctx.fillStyle = 'rgba(255, 255, 255, 0.8)' 
  14.     ctx.strokeStyle = 'rgba(255, 255, 255, 0.8)' 
  15.     ctx.stroke() 
  16.     ctx.globalCompositeOperation = 'destination-over' 
  17.     // 判斷是填充還是裁切, 裁切主要用于生成圖案滑塊 
  18.     operation === 'fill'? ctx.fill() : ctx.clip() 

這塊實現方案也是參考了 yield 大佬的原生 js 實現,這里需要補充的一點是 canvas 的 globalCompositeOperation 屬性,它的主要目的是設置如何將一個源(新的)圖像繪制到目標(已有)的圖像上。

  • 源圖像 = 我們打算放置到畫布上的繪圖
  • 目標圖像 = 我們已經放置在畫布上的繪圖

w3c上有個形象的例子:

這里之所以設置該屬性是為了讓鏤空的形狀不受背景底圖的影響并覆蓋在背景底圖的上方。如下:

接下來我們只需要將圖片繪制到畫布上即可:

  1. const canvasCtx = canvasRef.current.getContext('2d'
  2. // 繪制鏤空形狀 
  3. drawPath(canvasCtx, 50, 50, 'fill'
  4.  
  5. // 畫入圖片 
  6. canvasCtx.drawImage(img, 0, 0, width, height) 

當然至于如何生成隨機圖片和隨機位置,實現方式也很簡單,前端實現的話采用 Math.random 即可。

二.實現鏤空圖案 canvas

上面實現了鏤空形狀,那么鏤空圖案也類似,我們只需要使用 clip() 方法將圖片裁切到形狀遮罩里,并將鏤空圖案置于畫布左邊即可。代碼如下:

  1. const blockCtx = blockRef.current.getContext('2d'
  2. drawPath(blockCtx, 50, 50, 'clip'
  3. blockCtx.drawImage(img, 0, 0, width, height) 
  4.  
  5. // 提取圖案滑塊并放到最左邊 
  6. const y1 = 50 - r * 2 - 1 
  7. const ImageData = blockCtx.getImageData(xRef.current - 3, y1, L, L) 
  8. // 調整滑塊畫布寬度 
  9. blockRef.current.width = L 
  10. blockCtx.putImageData(ImageData, 0, y1) 

上面的代碼我們用到了 getImageData 和 putImageData,這兩個 api 主要用來獲取 canvas 畫布場景像素數據和對場景進行像素數據的寫入。實現后 的效果如下:

三.實現滑塊移動和驗證邏輯

實現滑塊移動的方案也比較簡單,我們只需要利用鼠標的 event 事件即可:

  • onMouseDown
  • onMouseMove
  • onMouseUp

以上是一個簡單的示意圖,具體實現代碼如下:

  1. const handleDragMove = (e) => { 
  2.     if (!isMouseDownRef.currentreturn false 
  3.     e.preventDefault() 
  4.     // 為了支持移動端, 可以使用e.touches[0] 
  5.     const eventX = e.clientX || e.touches[0].clientX 
  6.     const eventY = e.clientY || e.touches[0].clientY 
  7.     const moveX = eventX - originXRef.current 
  8.     const moveY = eventY - originYRef.current 
  9.     if (moveX < 0 || moveX + 36 >= width) return false 
  10.     setSliderLeft(moveX) 
  11.     const blockLeft = (width - l - 2r) / (width - l) * moveX 
  12.     blockRef.current.style.left = blockLeft + 'px' 

當然我們還需要對拖拽停止后的事件做監聽,來判斷是否驗證成功,并埋入成功和失敗的回調。代碼如下:

  1. const handleDragEnd = (e) => { 
  2.     if (!isMouseDownRef.currentreturn false 
  3.     isMouseDownRef.current = false 
  4.     const eventX = e.clientX || e.changedTouches[0].clientX 
  5.     if (eventX === originXRef.currentreturn false 
  6.     setSliderClass('sliderContainer'
  7.     const { flag, result } = verify() 
  8.     if (flag) { 
  9.       if (result) { 
  10.         setSliderClass('sliderContainer sliderContainer_success'
  11.         // 成功后的自定義回調函數 
  12.         typeof onSuccess === 'function' && onSuccess() 
  13.       } else { 
  14.         // 驗證失敗, 刷新重置 
  15.         setSliderClass('sliderContainer sliderContainer_fail'
  16.         setTextTip('請再試一次')  
  17.         reset() 
  18.       } 
  19.     } else { 
  20.       setSliderClass('sliderContainer sliderContainer_fail'
  21.       // 失敗后的自定義回調函數 
  22.       typeof onFail === 'function' && onFail() 
  23.       setTimeout(reset.bind(this), 1000) 
  24.     } 

實現后的效果如下:

[[425875]]

當然還有一些細節需要優化處理,這里在 github 上有完整的代碼,大家可以參考學習一下,如果大家想對該組件參與貢獻,也可以隨時提 issue。

四.如何使用 dumi 搭建組件文檔

為了讓組件能被其他人更好的理解和使用,我們可以搭建組件文檔。作為一名熱愛開源的前端 coder,編寫組件文檔也是個很好的開發習慣。接下來我們也為 react-slider-vertify 編寫一下組件文檔,這里我使用 dumi 來搭建組件文檔,當然大家也可以用其他方案(比如storybook)。我們先看一下搭建后的效果:

dumi 搭建組件文檔非常簡單,接下來和大家介紹一下安裝使用方式。

1.安裝

  1. $ npx @umijs/create-dumi-lib        # 初始化一個文檔模式的組件庫開發腳手架 
  2. or 
  3. $ yarn create @umijs/dumi-lib 
  4.  
  5. $ npx @umijs/create-dumi-lib --site # 初始化一個站點模式的組件庫開發腳手架 
  6. or 
  7. $ yarn create @umijs/dumi-lib --site 

2.本地運行

  1. npm run dev 
  2. or 
  3. yarn dev 

3.編寫文檔

dumi 約定式的定義了文檔編寫的位置和方式,其官網上也有具體的飯介紹,這里簡單給大家上一個 dumi 搭建的組件目錄結構圖:

 

 

我們可以在 docs 下編寫組件庫文檔首頁和引導頁的說明,在單個組件的文件夾下使用 index.md 來編寫組件自身的使用文檔,當然整個過程非常簡單,我這里舉一個文檔的例子:

通過這種方式 dumi 就可以幫我們自動渲染一個組件使用文檔。如果大家想學習更多組件文檔搭建的內容,也可以在 dumi 官網學習。

五.發布自己第一個npm組件包

最后一個問題就是組件發布。之前很多朋友問我如何將自己的組件發布到 npm 上讓更多人使用,這塊的知識網上有很多資料可以學習,那今天就以滑動驗證碼 @alex_xu/react-slider-vertify 的例子,來和大家做一個簡單的介紹。

1.擁有一個 npm 賬號并登錄

如果大家之前沒有 npm 賬號,可以在 npm 官網 注冊一個,然后用我們熟悉的 IDE 終端登錄一次:

  1. npm login 

跟著提示輸入完用戶名密碼之后我們就能通過命令行發布組件包了:

  1. npm publish --access public 

之所以指令后面會加 public 參數,是為了避免權限問題導致組件包無法發布成功。我們為了省事也可以把發布命令配置到 package.json 中,在組件打包完成后自動發布:

  1.     "scripts": { 
  2.         "start""dumi dev"
  3.         "release""npm run build && npm publish --access public"
  4.   } 

這樣我們就能將組件輕松發布到 npm 上供他人使用啦! 我之前也開源了很多組件庫,如果大家對組件打包細節和構建流程有疑問,也可以參考我之前開源項目的方案。發布到 npm 后的效果:

本文轉載自微信公眾號「趣談前端」

 

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

2023-12-08 08:02:40

開箱React?組件

2018-01-17 15:05:22

框架設計爬蟲Scrapy

2022-07-14 11:31:04

SQLToolsVScode數據庫

2021-09-26 05:00:11

Vscode插件

2021-08-26 05:15:22

圖片編輯器 H5-DooringMitu-Doorin

2022-08-31 08:32:22

數據可視化項目nocode

2021-09-11 21:03:09

可視化搭建框架

2023-12-12 13:50:00

代碼業務狀態

2013-11-28 15:02:34

Ubuntu技巧Geary

2021-09-14 08:38:57

組件開源前端

2022-04-18 19:02:53

chrome擴展瀏覽器

2019-11-26 08:43:44

平臺桌面軟件

2024-01-11 08:19:17

開源界驗證碼滑動類

2022-01-24 11:02:27

PySimpleGUPython計算器

2015-03-17 09:28:04

2016-11-14 15:40:01

Android

2023-06-27 16:42:18

Tinygrad深度學習工具

2022-05-27 10:00:06

C++游戲引擎

2013-06-19 10:19:59

點贊
收藏

51CTO技術棧公眾號

黄在线免费看| 一本一道人人妻人人妻αv | 国产精品丝袜高跟| 人妻人人澡人人添人人爽| 日本在线成人| 欧美日韩国产激情| 黄色片久久久久| 日本一区高清| 久久精品噜噜噜成人av农村| 精品国内亚洲在观看18黄| 国产精品欧美一区二区| 五月综合色婷婷| 久久影视三级福利片| 欧美在线视频日韩| 国产日韩亚洲欧美在线| 国产高清在线| 成人免费三级在线| 国产精品视频xxxx| 国产成人在线免费观看视频| 999国产精品永久免费视频app| 精品成人私密视频| jizz欧美性11| 超碰国产一区| 亚洲成人tv网| 麻豆中文字幕在线观看| 欧美精品少妇| 成人动漫精品一区二区| 久久影视电视剧免费网站| 精品影片一区二区入口| 亚洲青青一区| 日本电影亚洲天堂一区| 久久久久综合一区二区三区| 国产美女无遮挡永久免费| 久久精品国产www456c0m| 亚洲成色777777女色窝| 黄色一级片免费播放| 日韩美女在线看免费观看| 亚洲国产综合在线| 色乱码一区二区三区熟女| 国产一级在线观看| 99久久婷婷国产综合精品电影| 91视频国产高清| 中日韩在线观看视频| 午夜亚洲精品| 午夜精品一区二区三区在线视频| 日韩大尺度视频| 久久亚洲国产精品尤物| 色婷婷亚洲婷婷| 国产青青在线视频| 不卡av免费观看| 一区二区三区av电影| 一级黄色免费在线观看| 9191在线| 国产精品国产三级国产| 亚洲精品二区| 99riav在线| 国产日韩v精品一区二区| 欧美日韩综合网| 蜜桃视频在线免费| 国产视频一区在线播放| 日韩精品伦理第一区| 国产乱子伦三级在线播放| 久久精品在线观看| 午夜精品短视频| 丁香婷婷在线| 中文字幕一区二区三区蜜月| 一区高清视频| aa在线视频| 亚洲综合一区在线| 欧美亚洲日本一区二区三区| 97人人爽人人澡人人精品| 午夜精品福利一区二区三区av| 99热自拍偷拍| 日本在线啊啊| 在线免费观看成人短视频| 性欧美极品xxxx欧美一区二区| 天天综合网站| 在线成人高清不卡| 91福利视频免费观看| 亚洲一区二区三区中文字幕在线观看| 精品国产制服丝袜高跟| 精品无码人妻少妇久久久久久| 激情亚洲另类图片区小说区| 亚洲欧美日韩视频一区| 国产福利在线导航| 一区二区影院| 91精品国产91久久久久久不卡| 国产精品黄色大片| 日本伊人精品一区二区三区观看方式| 91精品久久久久久| 亚洲av无码国产综合专区| 99精品久久免费看蜜臀剧情介绍| 欧美激情专区| 精品自拍一区| 精品久久久久久久久久久久久久 | 快射视频在线观看| 一区二区不卡在线播放| 激情综合在线观看| 日韩午夜电影免费看| 欧美精品一区二区三区四区| 久久久无码人妻精品一区| 日韩一级毛片| 国内精品伊人久久| 中文字幕 自拍偷拍| 国产高清精品网站| 鲁片一区二区三区| 成人无遮挡免费网站视频在线观看| 亚洲一区二区三区四区五区中文 | 午夜裸体女人视频网站在线观看| 欧美亚洲综合在线| 麻豆短视频在线观看| 视频精品在线观看| 色中色综合影院手机版在线观看| 免费在线不卡视频| 精品影视av免费| 蜜桃久久影院| 午夜羞羞小视频在线观看| 91黄视频在线| 伊人网综合视频| 久久久久久久久丰满| 清纯唯美亚洲综合| 亚洲毛片欧洲毛片国产一品色| 久久精品视频网| 日本人妻伦在线中文字幕| 日本另类视频| 日韩高清a**址| 黑人巨大精品一区二区在线| 日韩黄色免费电影| 久久婷婷人人澡人人喊人人爽| a级影片在线观看| 欧美性受xxxx黑人xyx性爽| 免费观看污网站| 91成人看片| 国产精品中文字幕在线| 男人天堂资源在线| 同产精品九九九| 老司机午夜免费福利| 国产精品毛片久久| 国产欧美日韩专区发布| 精品无吗乱吗av国产爱色| 亚洲成人av福利| 欧美日韩一区二区区别是什么 | 26uuu成人网一区二区三区| 久久天天东北熟女毛茸茸| 国产黄色一区| 在线a欧美视频| 蜜臀99久久精品久久久久小说| 99免费精品在线| 国产一区二区四区| 伊人久久大香线蕉av超碰| 久久精品国产一区二区三区| 伊人色综合久久久| 日本一区二区久久| 亚洲黄色小视频在线观看| 久久99国产精品视频| 欧美亚洲视频在线看网址| 天天摸天天碰天天爽天天弄| 亚洲一二三区视频在线观看| 亚洲熟女乱综合一区二区| 欧美韩日精品| 成人欧美一区二区三区视频| 暖暖在线中文免费日本| 欧美成人福利视频| 国产亚洲精品久久久久久打不开| 国产v日产∨综合v精品视频| 国产肉体ⅹxxx137大胆| 97精品久久| 91国产精品91| 美丽的姑娘在线观看免费动漫| 欧美性xxxx极品hd欧美风情| 中文字幕人妻一区二区| 日本视频在线一区| 一区二区精品国产| 精品一区二区三区在线观看视频| 久久亚洲精品网站| 狠狠躁日日躁夜夜躁av| 精品久久久久久久久久久久久| 国产三级视频网站| 蜜臀久久99精品久久久画质超高清| 一本色道久久综合亚洲二区三区 | 肉肉视频在线观看| 亚洲成成品网站| 精品久久久久久久久久久久久久久久久久| 香蕉成人久久| 日韩av高清在线播放| yy6080久久伦理一区二区| 久久人人爽人人爽爽久久| www.日韩高清| 欧美性xxxx| 999精品在线视频| 成人综合激情网| 不要播放器的av网站| 99热精品久久| 国产日韩久久| 91国内外精品自在线播放| 欧美精品在线免费观看| 天堂中文在线视频| 亚洲精品videosex极品| 国产成人精品无码片区在线| 日韩二区三区四区| 视色,视色影院,视色影库,视色网| 美女视频免费精品| 国产精品久久久久久亚洲影视| 在线你懂的视频| 亚洲色图第三页| 精品国产av一区二区三区| 色网站国产精品| 国产一级在线观看视频| 中文一区二区在线观看| 亚洲国产精品无码久久久久高潮| 久久99深爱久久99精品| 好吊妞无缓冲视频观看| 91超碰成人| 神马欧美一区二区| 久久a爱视频| 96pao国产成视频永久免费| 中文字幕乱码在线播放| 欧美日韩成人精品| 尤物网址在线观看| 亚洲精品中文字幕有码专区| 国产激情无套内精对白视频| 欧美亚洲图片小说| 日本熟妇毛耸耸xxxxxx| 综合av第一页| 欧美a在线播放| 久久综合久色欧美综合狠狠| 久久久无码人妻精品无码| 蜜臀久久久久久久| 老司机午夜av| 亚洲自拍另类| 隔壁人妻偷人bd中字| 91综合在线| 天天综合色天天综合色hd| 日韩美女毛片| 国产自产精品| 风间由美一区二区av101| 91欧美精品午夜性色福利在线| 日韩视频网站在线观看| 欧美影院久久久| 男人久久天堂| 91精品国产高清| 男女免费观看在线爽爽爽视频| 不卡av电影在线观看| 91成人高清| 日韩性xxxx爱| 日本在线www| 日韩在线观看网址| jzzjzzjzz亚洲成熟少妇| 亚洲日本欧美日韩高观看| 日本中文字幕电影在线观看| 日韩成人在线免费观看| 无码国精品一区二区免费蜜桃| 欧美不卡在线视频| 亚洲第一页视频| 精品免费国产一区二区三区四区| 99草在线视频| 欧美一区二区视频在线观看| 国产三区在线播放| 91精品国产91久久久久久一区二区| 国产精品久久免费| 欧美一区日韩一区| 精品欧美一区二区精品少妇| 日韩欧美aaaaaa| 蜜臀久久99精品久久久| 精品国产污污免费网站入口 | 伊人久久大香线蕉成人综合网| 成人av国产| 中文精品一区二区三区| 中文在线日韩| 欧美国产视频一区| 伊人成人在线| 漂亮人妻被中出中文字幕| 日本欧美一区二区三区乱码| 伊人成人222| 国产成人午夜精品影院观看视频| 韩国三级在线看| 91视频观看免费| 精品国产aaa| 亚洲精品免费看| 日韩三级视频在线播放| 色噜噜久久综合| 国产一区二区自拍视频| 精品少妇一区二区三区在线视频| 日韩专区第一页| 亚洲欧美日韩网| 欧美天天影院| 亚洲精品美女网站| 黄色电影免费在线看| 中文字幕国产亚洲2019| 国产原创视频在线观看| 欧美精品videos另类日本| 欧美大胆性生话| 成人中心免费视频| 久久99国产精品久久99大师| 日本一区二区三区免费观看| 99re6这里只有精品| 欧美成人精品免费| 日韩在线一区二区三区| 亚洲精品一区二区18漫画| 91免费观看国产| 97在线观看免费高| 欧美日韩亚洲视频一区| 国产精品羞羞答答在线| 亚洲国模精品私拍| 午夜在线观看视频| 性金发美女69hd大尺寸| 久久久久毛片| 精品日本一区二区| 小小影院久久| 欧美少妇性生活视频| 国产成人精品综合在线观看| 精品成人无码一区二区三区| 亚洲综合清纯丝袜自拍| 中国精品一区二区| 日韩av在线电影网| 亚洲奶水xxxx哺乳期| 国产精品极品美女在线观看免费| 国产成人tv| 丰满女人性猛交| 日韩黄色一级片| 一级特黄a大片免费| 亚洲女与黑人做爰| 这里只有久久精品视频| 亚洲国产一区自拍| 97超碰资源站在线观看| 国产精品观看在线亚洲人成网 | 免费在线一区二区| 黄色成人在线网址| 日本高清免费在线视频| 国产女人水真多18毛片18精品视频 | 一区精品在线观看| 亚洲视频999| 在线观看福利电影| 国产久一道中文一区| 午夜精品网站| 久久人人爽人人片| 亚洲视频一区二区在线| 正在播放木下凛凛xv99| 亚洲欧美制服综合另类| 色是在线视频| 国产综合18久久久久久| 最新成人av网站| 国产精品果冻传媒| 亚洲午夜在线视频| 成人av手机在线| 九色精品美女在线| 日韩三级久久| 色哟哟免费网站| 国产伦精品一区二区三区视频青涩| av片在线免费看| 91精品免费在线| 国产美女福利在线| 亚洲xxx大片| 欧美69视频| 免费不卡的av| 午夜精品久久久久久久| 天堂在线视频观看| 欧美亚洲国产视频| 久久93精品国产91久久综合| 欧美少妇性生活视频| 亚洲国产成人私人影院tom| 中文字幕在线观看视频一区| 一区二区三区国产视频| 欧美网站免费| 美女黄色片网站| 国产suv精品一区二区883| 久久精品视频9| 日韩精品中文字幕有码专区| 成人av三级| 一本色道久久99精品综合| 国产一区二区精品久久99| 精品亚洲永久免费| 亚洲国产成人在线播放| 热三久草你在线| 水蜜桃亚洲一二三四在线| 理论片日本一区| 欧美黄色一区二区三区| 天天爽夜夜爽夜夜爽精品视频| 人妻91麻豆一区二区三区| 欧洲精品在线视频| 日韩精品永久网址| av在线网站免费观看| 亚洲国产欧美在线| 欧洲亚洲在线| 成人网址在线观看| 国产精品黄色| 亚洲黄色小说视频| 3d成人h动漫网站入口| 激情网站在线| 区一区二区三区中文字幕| 久久66热偷产精品| 日本一级淫片免费放| 在线成人免费网站| 爱爱精品视频| 男女爽爽爽视频| 亚洲国产综合91精品麻豆| 国产精品免费观看| 成人欧美一区二区| 蜜桃视频一区二区| 日韩欧美激情视频|