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

40行代碼內實現一個React.js

開發 開發工具
本文會教你如何在40行代碼內,不依賴任何第三方的庫,用純JavaScript實現一個React.js。

[[186904]]

一、前言

本文會教你如何在 40 行代碼內,不依賴任何第三方的庫,用純 JavaScript 實現一個 React.js 。

本文的目的是:揭開對初學者看起來很很難理解的 React.js 的組件化形式的外衣。如果你剛開始學習 React.js 并且感覺很迷茫,那么看完這篇文章以后就能夠解除一些疑惑。

另外注意,本文所實現的代碼只用于說明教學展示,并不適用于生產環境。代碼托管這個 倉庫。心急如焚的同學可以先去看代碼,但本文會從最基礎的內容開始解釋。

二、一切從點贊說起

接下來所有的代碼都會從一個基本的點贊功能開始演化,你會逐漸看到,文章代碼慢慢地越來越像 React.js 的組件代碼。而在這個過程里面,大家需要只需要跟著文章的思路,就可以在代碼的演化當中體會到組件化形式。

假設現在我們需要實現一個點贊、取消點贊的功能。

如果你對前端稍微有一點了解,你就順手拈來:

HTML:

  1. <body> 
  2.     <div class='wrapper'> 
  3.       <button class='like-btn'> 
  4.         <span class='like-text'>點贊</span> 
  5.         <span>👍</span> 
  6.       </button> 
  7.     </div> 
  8.   </body> 

 

 

 

為了現實當中的實際情況,所以這里特意把這個 button 的 HTML 結構搞得稍微復雜一些。有了這個 HTML 結構,現在就給它加入一些 JavaScript 的行為:

JavaScript:

  1. const button = document.querySelector('.like-btn') 
  2.   const buttonbuttonText = button.querySelector('.like-text') 
  3.   let isLiked = false 
  4.   button.addEventListener('click', function () { 
  5.     isLiked = !isLiked 
  6.     if (isLiked) { 
  7.       buttonText.innerHTML = '取消' 
  8.     } else { 
  9.       buttonText.innerHTML = '點贊' 
  10.     } 
  11.   }, false) 

功能和實現都很簡單,按鈕已經可以提供點贊和取消點贊的功能。這時候你的同事跑過來了,說他很喜歡你的按鈕,他也想用你寫的這個點贊功能。你就會發現這種實現方式很致命:你的同事要把整個 button 和里面的結構復制過去,還有整段 JavaScript 代碼也要復制過去。這樣的實現方式沒有任何可復用性。

三、實現可復用性

所以現在我們來想辦法解決這個問題,讓這個點贊功能具有較好的可復用的效果,那么你的同事們就可以輕松自在地使用這個點贊功能。

1. 結構復用

現在我們來重新編寫這個點贊功能。這次我們先寫一個類,這個類有 render 方法,這個方法里面直接返回一個表示 HTML 結構的字符串:

  1. class LikeButton { 
  2.    render () { 
  3.      return ` 
  4.        <button class='like-btn'> 
  5.          <span class='like-text'></span> 
  6.          <span>👍</span> 
  7.        </button> 
  8.      ` 
  9.    } 
  10.  } 

然后可以用這個類來構建不同的點贊功能的實例,然后把它們插到頁面中。

  1. const wrapper = document.querySelector('.wrapper') 
  2.   const likeButton1 = new LikeButton() 
  3.   wrapper.innerHTML = likeButton1.render() 
  4.  
  5.   const likeButton2 = new LikeButton() 
  6.   wrapper.innerHTML += likeButton2.render() 

這里非常暴力地使用了 innerHTML ,把兩個按鈕粗魯地插入了 wrapper 當中。雖然你可能會對這種實現方式非常不滿意,但我們還是勉強了實現了結構的復用。我們后面再來優化它。

2. 生成 DOM 元素并且添加事件

你一定會發現,現在的按鈕是死的,你點擊它它根本不會有什么反應。因為根本沒有往上面添加事件。但是問題來了,LikeButton 類里面是雖然說有一個 button,但是這玩意根本就是在字符串里面的。你怎么能往一個字符串里面添加事件呢?DOM 事件的 API 只有 DOM 結構才能用。

我們需要 DOM 結構,準確地來說:我們需要這個點贊功能的 HTML 字符串代表的 DOM 結構。假設我們現在有一個函數 createDOMFromString ,你往這個函數傳入 HTML 字符串,但是它會把相應的 DOM 元素返回給你。這個問題就可以額解決了。

  1. // ::String => ::Document 
  2. const createDOMFromString = (domString) => { 
  3.   // TODO  

先不用管這個函數應該怎么實現,先知道它是干嘛的。拿來用就好,這時候用它來改寫一下 LikeButton 類:

  1. class LikeButton { 
  2.     render () { 
  3.       this.el = createDOMFromString(` 
  4.         <button class='like-btn'> 
  5.           <span class='like-text'>點贊</span> 
  6.           <span>👍</span> 
  7.         </button> 
  8.       `) 
  9.       this.el.addEventListener('click', () => console.log('click'), false) 
  10.       return this.el 
  11.     } 
  12.   } 

現在 render() 返回的不是一個 html 字符串了,而是一個由這個 html 字符串所生成的 DOM。在返回 DOM 元素之前會先給這個 DOM 元素上添加事件再返回。

因為現在 render 返回的是 DOM 元素,所以不能用 innerHTML 暴力地插入 wrapper。而是要用 DOM API 插進去。

  1. const wrapper = document.querySelector('.wrapper') 
  2.  
  3. const likeButton1 = new LikeButton() 
  4. wrapper.appendChild(likeButton1.render()) 
  5.  
  6. const likeButton2 = new LikeButton() 
  7. wrapper.appendChild(likeButton2.render()) 

現在你點擊這兩個按鈕,每個按鈕都會在控制臺打印 click,說明事件綁定成功了。但是按鈕上的文本還是沒有發生改變,只要稍微改動一下 LikeButton 的代碼就可以完成完整的功能:

  1. class LikeButton { 
  2.     constructor () { 
  3.       this.state = { isLiked: false } 
  4.     } 
  5.  
  6.     changeLikeText () { 
  7.       const likeText = this.el.querySelector('.like-text') 
  8.       this.state.isLiked = !this.state.isLiked 
  9.       if (this.state.isLiked) { 
  10.         likeText.innerHTML = '取消' 
  11.       } else { 
  12.         likeText.innerHTML = '點贊' 
  13.       } 
  14.     } 
  15.  
  16.     render () { 
  17.       this.el = createDOMFromString(` 
  18.         <button class='like-btn'> 
  19.           <span class='like-text'>點贊</span> 
  20.           <span>👍</span> 
  21.         </button> 
  22.       `) 
  23.       this.el.addEventListener('click', this.changeLikeText.bind(this), false) 
  24.       return this.el 
  25.     } 
  26.   } 

這里的代碼稍微長了一些,但是還是很好理解。只不過是在給 LikeButton 類添加了構造函數,這個構造函數會給每一個 LikeButton 的實例添加一個對象 state,state 里面保存了每個按鈕自己是否點贊的狀態。還改寫了原來的事件綁定函數:原來只打印 click,現在點擊的按鈕的時候會調用 changeLikeText 方法,這個方法會根據 this.state 的狀態改變點贊按鈕的文本。

如果你現在還能跟得上文章的思路,那么你留意下,現在的代碼已經和 React.js 的組件代碼有點類似了。但其實我們根本沒有講 React.js 的任何內容,我們一心一意只想怎么做好“組件化”。

現在這個組件的可復用性已經很不錯了,你的同事們只要實例化一下然后插入到 DOM 里面去就好了。

四、為什么不暴力一點?

仔細留意一下 changeLikeText 函數,這個函數包含了 DOM 操作,現在看起來比較簡單,那是因為現在只有 isLiked 一個狀態。但想一下,因為你的數據狀態改變了你就需要去更新頁面的內容,所以如果你的組件包含了很多狀態,那么你的組件基本全部都是 DOM 操作。一個組件包含很多狀態的情況非常常見,所以這里還有優化的空間:如何盡量減少這種手動 DOM 操作?

1. 狀態改變 -> 構建新的 DOM 元素

這里要提出的一種解決方案:一旦狀態發生改變,就重新調用 render 方法,構建一個新的 DOM 元素。這樣做的好處是什么呢?好處就是你可以在 render 方法里面使用***的 this.state 來構造不同 HTML 結構的字符串,并且通過這個字符串構造不同的 DOM 元素。頁面就更新了!聽起來有點繞,看看代碼怎么寫:

  1. class LikeButton { 
  2.     constructor () { 
  3.       this.state = { isLiked: false } 
  4.     } 
  5.  
  6.     setState (state) { 
  7.       this.state = state 
  8.       thisthis.el = this.render() 
  9.     } 
  10.  
  11.     changeLikeText () { 
  12.       this.setState({ 
  13.         isLiked: !this.state.isLiked 
  14.       }) 
  15.     } 
  16.  
  17.     render () { 
  18.       this.el = createDOMFromString(` 
  19.         <button class='like-btn'> 
  20.           <span class='like-text'>${this.state.isLiked ? '取消' : '點贊'}</span> 
  21.           <span>👍</span> 
  22.         </button> 
  23.       `) 
  24.       this.el.addEventListener('click', this.changeLikeText.bind(this), false) 
  25.       return this.el 
  26.     } 
  27.   } 

其實只是改了幾個小地方:

  • render 函數里面的 HTML 字符串會根據 this.state 不同而不同(這里是用了 ES6 的字符串特性,做這種事情很方便)。
  • 新增一個 setState 函數,這個函數接受一個對象作為參數;它會設置實例的 state,然后重新調用一下 render 方法。
  • 當用戶點擊按鈕的時候, changeLikeText 會構建新的 state 對象,這個新的 state ,傳入 setState 函數當中。

這樣的結果就是,用戶每次點擊,changeLikeText 都會調用改變組件狀態然后調用 setState;setState 會調用 render 方法重新構建新的 DOM 元素;render 方法會根據 state 的不同構建不同的 DOM 元素。

也就是說,你只要調用 setState,組件就會重新渲染。我們順利地消除了沒必要的 DOM 操作。

2. 重新插入新的 DOM 元素

上面的改進不會有什么效果,因為你仔細看一下就會發現,其實重新渲染的 DOM 元素并沒有插入到頁面當中。所以這個組件之外,你需要知道這個組件發生了改變,并且把新的 DOM 元素更新到頁面當中。

重新修改一下 setState 方法:

  1. ... 
  2.     setState (state) { 
  3.       const oldEl = this.el 
  4.       this.state = state 
  5.       thisthis.el = this.render() 
  6.       if (this.onStateChange) this.onStateChange(oldEl, this.el) 
  7.     } 
  8. ... 

使用這個組件的時候:

  1. const likeButton = new LikeButton() 
  2. wrapper.appendChild(likeButton.render()) // ***次插入 DOM 元素 
  3. component.onStateChange = (oldEl, newEl) => { 
  4.   wrapper.insertBefore(newEl, oldEl) // 插入新的元素 
  5.   wrapper.removeChild(oldEl) // 刪除舊的元素 

這里每次 setState 都會調用 onStateChange 方法,而這個方法是實例化以后時候被設置的,所以你可以自定義 onStateChange 的行為。這里做的事是,每當 setState 的時候,就會把插入新的 DOM 元素,然后刪除舊的元素,頁面就更新了。這里已經做到了進一步的優化了:現在不需要再手動更新頁面了。

非一般的暴力。不過沒有關系,這種暴力行為可以被 Virtual-DOM 的 diff 策略規避掉,但這不是本文章所討論的范圍。

這個版本的點贊功能很不錯,我可以繼續往上面加功能,而且還不需要手動操作DOM。但是有一個不好的地方,如果我要重新另外做一個新組件,譬如說評論組件,那么里面的這些 setState 方法要重新寫一遍,其實這些東西都可以抽出來。

五、抽象出 Component 類

為了讓代碼更靈活,可以寫更多的組件,我把這種模式抽象出來,放到一個 Component 類當中:

  1. class Component { 
  2.     constructor (props = {}) { 
  3.       this.props = props 
  4.     } 
  5.  
  6.     setState (state) { 
  7.       const oldEl = this.el 
  8.       this.state = state 
  9.       thisthis.el = this.renderDOM() 
  10.       if (this.onStateChange) this.onStateChange(oldEl, this.el) 
  11.     } 
  12.  
  13.     renderDOM () { 
  14.       this.el = createDOMFromString(this.render()) 
  15.       if (this.onClick) { 
  16.         this.el.addEventListener('click', this.onClick.bind(this), false) 
  17.       } 
  18.       return this.el 
  19.     } 
  20.   } 

還有一個額外的 mount 的方法,其實就是把組件的 DOM 元素插入頁面,并且在 setState 的時候更新頁面:

  1. const mount = (wrapper, component) => { 
  2.     wrapper.appendChild(component.renderDOM()) 
  3.     component.onStateChange = (oldEl, newEl) => { 
  4.       wrapper.insertBefore(newEl, oldEl) 
  5.       wrapper.removeChild(oldEl) 
  6.     } 
  7.   } 

這樣的話我們重新寫點贊組件就會變成:

  1. class LikeButton extends Component { 
  2.     constructor (props) { 
  3.       super(props) 
  4.       this.state = { isLiked: false } 
  5.     } 
  6.  
  7.     onClick () { 
  8.       this.setState({ 
  9.         isLiked: !this.state.isLiked 
  10.       }) 
  11.     } 
  12.  
  13.     render () { 
  14.       return ` 
  15.         <button class='like-btn'> 
  16.           <span class='like-text'>${this.props.word || ''} ${this.state.isLiked ? '取消' : '點贊'}</span> 
  17.           <span>👍</span> 
  18.         </button> 
  19.       ` 
  20.     } 
  21.   } 
  22.  
  23.   mount(wrapper, new LikeButton({ word: 'hello' })) 

有沒有發現你寫的代碼已經和 React.js 的組件寫法很相似了?而且還是可以正常運作的代碼,而且我們從頭到尾都是用純的 JavaScript,沒有依賴任何第三方庫。(注意這里加入了上面沒有提到過點 props,可以給組件傳入配置屬性,跟 React.js 一樣)。

只要有了上面那個 Component 類和 mount 方法加起來不足40行代碼就可以做到組件化。如果我們需要寫另外一個組件,只需要像上面那樣,簡單地繼承一下 Component 類就好了:

  1. class RedBlueButton extends Component { 
  2.     constructor (props) { 
  3.       super(props) 
  4.       this.state = { 
  5.         color: 'red' 
  6.       } 
  7.     } 
  8.  
  9.     onClick () { 
  10.       this.setState({ 
  11.         color: 'blue' 
  12.       }) 
  13.     } 
  14.  
  15.     render () { 
  16.       return ` 
  17.         <div style='color: ${this.state.color};'>${this.state.color}</div> 
  18.       ` 
  19.     } 
  20.   } 

簡單好用,完整的代碼可以在這里找到: React.js in 40

噢,忘了,還有一個神秘的 createDOMFromString,其實它更簡單:

  1. const createDOMFromString = (domString) => { 
  2.     const div = document.createElement('div') 
  3.     div.innerHTML = domString 
  4.     return div 
  5.   } 

六、總結

你到底能從文章中獲取到什么?

好吧,我承認我標題黨了,這個 40 行不到的代碼其實是一個殘廢而且智障版的 React.js,沒有 JSX ,沒有組件嵌套等等。它只是 React.js 組件化表現形式的一種實現而已。

React 的 setState 、props 等等都只不過是一種形式,而很多初學者會被它這種形式作迷惑。本篇文章其實就是揭露了這種組件化形式的實現原理。如果你正在學習或者學習 React.js 過程很迷茫,那么看完這篇文章以后就能夠解除一些疑惑。

點擊《40 行代碼內實現一個 React.js》閱讀原文。

【本文是51CTO專欄作者“胡子大哈”的原創文章,轉載請聯系作者本人獲取授權】

戳這里,看該作者更多好文

責任編輯:趙寧寧 來源: 51CTO專欄
相關推薦

2022-04-15 08:07:21

ReactDiff算法

2020-11-30 06:18:21

React

2025-01-13 00:00:00

2024-03-20 09:31:00

圖片懶加載性能優化React

2020-04-27 14:54:45

React開發

2022-06-08 08:03:51

React.jsReactJS 庫

2025-01-17 09:29:42

2017-02-09 15:19:14

2022-01-26 16:30:47

代碼虛擬機Linux

2022-06-29 09:02:31

go腳本解釋器

2018-06-21 16:03:25

Vue.jsReact.js框架

2015-12-31 10:14:54

React.js開發Web應用

2019-11-15 15:50:41

JS代碼React前端

2022-06-28 08:17:10

JSON性能反射

2022-02-08 12:30:30

React事件系統React事件系統

2021-12-16 06:21:16

React組件前端

2016-11-14 15:51:42

JavaScriptAngular.jsReact.js

2023-02-07 13:42:44

代碼實現并發

2022-06-06 09:28:36

ReactHook

2023-07-03 07:51:47

點贊
收藏

51CTO技術棧公眾號

久久无码人妻精品一区二区三区 | 2018国产在线| 欧洲精品久久一区二区| 久久蜜桃精品| 久久精品小视频| 欧美极品jizzhd欧美仙踪林| 日韩欧美精品电影| 一区二区三区在线影院| 欧美精品亚洲| h狠狠躁死你h高h| 亚洲免费中文| 不卡av电影在线观看| 国产二级一片内射视频播放| 久久女人天堂| 欧美日韩国产限制| 18视频在线观看娇喘| 污污的视频网站在线观看| 久久99久久精品| 777午夜精品福利在线观看| 午夜激情福利电影| 最新亚洲精品| 亚洲成人久久久久| 中文字幕视频三区| gogo亚洲高清大胆美女人体| 亚洲五码中文字幕| 亚洲砖区区免费| 外国精品视频在线观看| 蜜桃传媒麻豆第一区在线观看| 久久久久久香蕉网| www.av免费| 欧洲杯足球赛直播| 日韩电影中文字幕| 绯色av蜜臀vs少妇| 精品99re| 在线不卡a资源高清| 国产日韩一区二区在线| 精精国产xxxx视频在线中文版 | 青娱乐av在线| 欧美wwwww| 亚洲最新中文字幕| 成人黄色免费网址| 日韩av字幕| 亚洲丁香婷深爱综合| 久久久久亚洲av片无码v| 亚洲欧洲日韩精品在线| 欧美三级日韩在线| 一区二区三区国产免费| 美女福利一区二区| 欧美性猛交xxxx乱大交3| 欧美,日韩,国产在线| 啪啪免费视频一区| 一区二区三区欧美日| 精品91一区二区三区| 免费网站成人| 自拍偷拍欧美精品| 国产对白在线播放| 二区在线播放| 一区二区视频免费在线观看| 日韩精品福利片午夜免费观看| fc2ppv国产精品久久| 亚洲日本丝袜连裤袜办公室| 综合网五月天| 少妇av在线| 午夜精品一区二区三区三上悠亚 | 日本免费www| 日韩国产一区| 日韩最新中文字幕电影免费看| 我想看黄色大片| 国产精品久久久乱弄| 久久伊人精品视频| 免费人成视频在线| 亚洲精华国产欧美| 日本欧美黄网站| 中国精品一区二区| 国产一区二区三区黄视频 | 97视频免费在线看| 亚洲精品男人的天堂| 日韩成人dvd| 成人乱人伦精品视频在线观看| 精品二区在线观看| 成人18视频日本| 热re99久久精品国产99热 | 亚州欧美日韩中文视频| 精品免费囯产一区二区三区| 天堂成人国产精品一区| 国产主播精品在线| 黑人精品一区二区三区| 91麻豆国产在线观看| 亚洲欧美日产图| 日本天码aⅴ片在线电影网站| 偷拍一区二区三区| www.精品在线| 成人av综合网| 日韩精品中文字幕在线| 亚洲一二三四五六区| 精品福利电影| 国产日本欧美一区二区三区| 丰满肥臀噗嗤啊x99av| 久久久精品天堂| 强开小嫩苞一区二区三区网站| 国产在线精彩视频| 7777精品伊人久久久大香线蕉完整版 | 亚洲欧美日韩另类精品一区二区三区 | 精品久久亚洲| 亚洲欧美日韩中文在线| 欧美日韩午夜视频| 久久激情视频| 99国产高清| 在线免费观看黄| 精品免费在线视频| 91人妻一区二区三区| 国产亚洲一卡2卡3卡4卡新区| 欧美日韩福利在线观看| 亚洲精品国产精品国自产网站按摩| 国产凹凸在线观看一区二区| 日韩欧美一区二区在线观看 | 青青九九免费视频在线| 亚洲精品视频一区二区| 亚洲77777| 香蕉国产成人午夜av影院| 欧美成人午夜免费视在线看片| 国产精品熟女视频| gogogo免费视频观看亚洲一| www.-级毛片线天内射视视| 日韩高清中文字幕一区二区| 亚洲第一页中文字幕| 91成人福利视频| 久久国产尿小便嘘嘘| 欧美一区二区三区四区夜夜大片| 波多野结依一区| 日韩欧美一区二区视频| 激情高潮到大叫狂喷水| 日韩高清中文字幕一区| 欧美二区在线| 在线观看v片| 亚洲精品美女在线观看播放| 久久久国产精品黄毛片| 黄页视频在线91| 久久久一二三四| 四虎视频在线精品免费网址| 最新的欧美黄色| 中文字幕欧美人妻精品一区蜜臀| 久久久蜜桃精品| 男人操女人免费软件| 在线看成人短视频| 国产成人精品久久亚洲高清不卡| 香蕉国产在线视频| 欧美日韩人人澡狠狠躁视频| 99久久免费看精品国产一区| 亚洲黄色av| 国产日韩欧美综合精品 | 四季av一区二区三区免费观看| 国产成人精品网站| 韩国中文免费在线视频| 欧美中文字幕亚洲一区二区va在线 | 成年人小视频网站| 国产成人黄色| 国产精品网址在线| 香蕉视频网站在线观看| 91精品国产综合久久香蕉的特点| 91精品一区二区三区蜜桃| 国产精品综合久久| 男人天堂新网址| 黄色美女久久久| 欧美最猛性xxxx| 福利视频在线播放| 欧美人牲a欧美精品| 综合五月激情网| 成人网页在线观看| 欧美 国产 日本| 波多野结衣在线播放一区| 国产美女精品免费电影| 制服丝袜在线播放| 亚洲精品久久久久久久久久久 | 欧美日韩视频在线第一区| 黑人狂躁日本娇小| 国产成人免费视频| 91精品91久久久中77777老牛| 国产a久久精品一区二区三区 | 中文字幕二区三区| 亚洲三级在线免费观看| 在线xxxxx| 久久综合九色| 日韩不卡视频一区二区| 国产精品白丝一区二区三区| 国产成人精品综合| 2024最新电影在线免费观看| 亚洲精品电影在线| 亚洲视频一区二区三区四区| 亚洲线精品一区二区三区八戒| 精品人妻一区二区三区日产乱码卜| 日韩国产在线观看一区| 老司机午夜免费福利视频| 香蕉久久夜色精品国产使用方法| 国产日韩av在线播放| 不卡视频观看| www.精品av.com| 亚洲日本国产精品| 欧美丰满高潮xxxx喷水动漫| www.日本精品| 亚洲精品乱码久久久久久日本蜜臀| 疯狂揉花蒂控制高潮h| 久久精品二区亚洲w码| 337p粉嫩大胆噜噜噜鲁| 91精品国产91久久综合| 欧美12av| 成人av综合网| 91青草视频久久| av电影一区| 久久人人97超碰精品888| 免费黄色在线| 亚洲新声在线观看| 三级小视频在线观看| 91精品婷婷国产综合久久| 国产主播第一页| 午夜影视日本亚洲欧洲精品| 欧美另类videoxo高潮| 国产亚洲综合色| 国产麻豆xxxvideo实拍| 国产一区二区视频在线| 午夜免费福利在线| 亚洲综合激情| 分分操这里只有精品| 欧美~级网站不卡| 亚洲区一区二区三区| 香蕉久久99| 精品国产乱码久久久久久久软件| 国产 日韩 欧美| 国产欧美日韩中文字幕在线| 亚洲成a人片| 欧美专区在线观看| 激情视频网站在线播放色| 久久99热精品| 怡红院在线播放| 日韩三级成人av网| 欧美日韩欧美| 色婷婷**av毛片一区| 草草影院在线观看| 一区二区三区视频在线| 黄色av网址在线免费观看| 精品亚洲男同gayvideo网站| 神马久久久久久久久久| 亚洲成人网在线| 蜜桃视频久久一区免费观看入口| 日韩欧美一区在线| 亚洲av综合色区无码一二三区 | av在线天堂网| 国产精品羞羞答答xxdd| 宇都宫紫苑在线播放| 国产精品一区三区| 日韩大尺度视频| 成人成人成人在线视频| 中文字幕在线播放一区| 99亚偷拍自图区亚洲| 欧美激情 亚洲| 91丨porny丨蝌蚪视频| 一本色道久久综合亚洲精品图片 | 永久免费看mv网站入口| 亚洲欧美aⅴ...| 欧美日韩大片在线观看| 亚洲国产精品精华液网站| 青青国产在线观看| 色婷婷av一区二区三区软件| 亚洲午夜无码久久久久| 欧美日韩www| www.天堂在线| 亚洲精品www| 国产午夜视频在线观看| 这里只有精品丝袜| 成人看av片| 国内精品在线一区| 奇米777日韩| 91在线视频精品| 日韩极品在线| 亚洲欧洲国产精品久久| 国产精品福利在线观看播放| 久久综合久久久久| 性欧美精品高清| 红桃视频 国产| www.视频一区| 日本污视频网站| 亚洲影院理伦片| 无码无套少妇毛多18pxxxx| 欧美日韩日日摸| 欧美 日韩 国产 在线| 亚洲欧美日韩中文在线| 宅男在线观看免费高清网站| 日本成人免费在线| 国产精品国产三级在线观看| 精品无人区一区二区三区竹菊| 欧洲福利电影| 精品无码国产一区二区三区av| 日韩精品一二三四| av在线天堂网| 国产精品看片你懂得| 免费毛片一区二区三区| 欧美亚洲国产怡红院影院| 性一交一乱一精一晶| 亚洲午夜女主播在线直播| 欧美激情成人动漫| 国产精品普通话| 欧美黄色录像| 国产日韩欧美大片| 日韩国产高清在线| 性久久久久久久久久久| 亚洲乱码精品一二三四区日韩在线| 日韩色图在线观看| 欧美草草影院在线视频| 9色在线视频网站| 91精品国产高清自在线 | 久久精品五月婷婷| 欧美在线资源| 中文字幕视频在线免费观看| 99久久99久久综合| 免费中文字幕在线| 欧美日韩国产123区| 欧美在线一卡| 国内外成人免费激情在线视频| 97久久精品一区二区三区的观看方式| 蜜桃视频在线观看91| 欧美日韩国产色综合一二三四| 亚洲天堂网一区| 久久综合九色综合97_久久久| 国产福利久久久| 56国语精品自产拍在线观看| 99se视频在线观看| 国产成人精品一区二区| 中国av一区| 两根大肉大捧一进一出好爽视频| 国产ts人妖一区二区| 欧美日韩免费做爰视频| 在线不卡中文字幕| 欧美日韩在线看片| 成人黄色av播放免费| 三区四区不卡| 成人性生交免费看| 中文成人av在线| 欧美另类高清videos的特点| 亚洲桃花岛网站| 女生影院久久| 日韩欧美精品久久| 日韩精品五月天| 先锋影音av在线| 精品视频一区三区九区| av在线三区| 成人高清视频观看www| 999久久久91| 亚洲一二三不卡| 亚洲精品国产一区二区精华液| 国产精品系列视频| 欧美久久精品一级黑人c片| 国产精品xnxxcom| 东北少妇不带套对白| 99久久99久久综合| 久久亚洲精品石原莉奈| 亚洲天堂免费观看| 国产成人精选| 欧美亚洲视频一区| 国产电影一区二区三区| 精品无码av在线| 日韩精品免费在线| 欧美日韩不卡| 中文字幕一区二区三区四区五区六区| 久久99精品久久久| 草视频在线观看| 亚洲国产精品99| 成人看片网页| 在线看无码的免费网站| 粉嫩av一区二区三区在线播放| 日本视频免费在线| 亚洲一级一级97网| 亚洲天堂网站| 成人免费视频91| 国产欧美日韩卡一| 国产视频在线免费观看| 97碰在线观看| 国产韩日影视精品| 麻豆短视频在线观看| 色播五月激情综合网| 国产在线观看a| 国产伦精品一区二区三区在线| 亚洲欧美日韩专区| 亚洲视频重口味| 亚洲精品电影网站| 婷婷精品久久久久久久久久不卡| 性一交一乱一伧国产女士spa| 久久这里只有精品视频网| 一级特黄aaa| 2019中文字幕在线免费观看| 91视频精品| 久久久久久久无码| 欧美精品v日韩精品v韩国精品v| 九九色在线视频| 视频一区三区| av在线不卡观看免费观看| 中文在线最新版天堂| 国内精品伊人久久| 无码一区二区三区视频| 久久久久久久久久久国产精品| 69久久夜色精品国产69蝌蚪网|