亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > JS > 正文

React精髓!一篇全概括小結(急速)

2024-05-06 16:51:18
字體:
來源:轉載
供稿:網友

學和使用react有一年多了,最近想在梳理一下react基礎知識,夯實基礎,激流勇進~
關于reacr-router,redux,redux-saga后續都會慢慢輸出,希望各位看官老爺持續關注~~要是能給個贊鼓勵一下就更贊了~

提醒一下:

看完之后抓緊時間趁熱打鐵,redux,react-redux,redux-saga

react基礎知識速覽

1、什么是JSX?

一個JSX語法的示例,如下所示

const element = <h1>Hello, world!</h1>;

這種語法形式,既不是HTML,也不是字符串,而是稱之為JSX,是React里用來描述UI和樣式的語法,JSX最終會被編譯為合法的JS語句調用(編譯器在遇到{時采用JS語法進行解析,遇到<就采用HTML規則進行解析)

2、嵌入表達式

JSX中,可以使用花括號{}嵌入任意的JavaScript合法表達式,如:2 + 2、user.firstName、formatName(user)都是合法的。示例如:

const user = { firstName: 'Zhang', lastName : 'Busong'};const elem = ( <h1>Hello, {formatName(user)}</h1>);/*這里的(),實際上是可選的,但是React推薦加入(),這樣子就會被視為一個表達式,而不會導致自動插入分號的問題*/ReactDOM.render( element, document.getElementById('app'))

3、JSX也是一種表達式

JSX本身也是一種表達式,所以它可以像其他表達式一樣,用于給一個變量賦值、作為函數實參、作為函數返回值,等等。如:

function getGreeting(user) { if (user) {  return <h1>Hello, {formatName(user)}</h1> } return <h1>Hello, Guest!</h1>;}

注意:

1、在JSX中,聲明屬性時不要使用引號,如果聲明屬性的時候使用引號,那么將被作為字符串解析,而不會被作為一個表達式解析,如:

<div firstName="{user.firstName}" lastName={user.lastName}></div>

解析后,可以得到:

<div firstName="{user.firstName}" lastName="Lau"></div>

因此,當我們需要使用一個字符串字面量的時候,可以使用引號,但是如果要作為表達式解析的時候,則不應當使用引號

2、在JSX中,有些屬性名稱需要進行特殊處理。如class應該用className代替,tabindex則用tabIndex代替。這是因為JSX本質上更接近于JavaScript,而class是JavaScript中的保留字。同時,應該使用camelCase來命名一個屬性,而不是使用HTML的屬性命名方式

3、JSX本身已經做了防注入處理,對于那些不是明確編寫的HTML代碼,是不會被解析為HTML DOM的,ReactDOM會將他們一律視為字符串,在渲染完成前就轉化為字符串,所以可以防止XSS攻擊

4、如果JSX標簽是閉合的,那么結尾需要用/>,另外,JSX標簽是可以互相嵌套的,這和HTML里是一樣的

4、JSX實質

JSX通過babel編譯,而babel實際上把JSX編譯給React.createElement()調用。如下JSX代碼:

const element = ( <h1 className="greeting">  Hello, world! </h1>);

是等同于以下的語句的:

const elem = React.createElement( 'h1', {className: 'greeting'}, 'Hello, world!');

React.createElement()方法會首先進行一些避免BUG的檢查,然后返回類似以下例子的對象:

const element = { type: 'h1', props: {  className: 'greeting',  children: 'Hello, world' }}

這樣的對象,則稱為React元素,代表所有呈現在屏幕上的東西。React正是通過讀取這些對象來構建DOM,并且保持數據和UI同步的

5、元素渲染

元素(elements)是構成React應用的最小單元,元素描述了想要在屏幕中看到的內容,如:

const element = <h1>Hello, world</h1>;

和DOM元素不同的是,React元素是純對象,創建的代價低。并且React會進行優化處理,只把有必要的變化更新到DOM上。此外,元素和組件的概念,是不一樣的,組件是由元素組成的。

6、將元素渲染進DOM

在React中,使用ReactDOM.render()方法來將React元素渲染進一個DOM中。如:

ReactDOM.render( element, document.getElementById('root'))

React元素是不可變的,所以一旦一個元素創建完成后,我們是無法改變其內容或者屬性的。一個元素就像是動畫里的一幀,它代表UI在某一時間點的樣子。如果非要使用元素來構成可變化的UI界面,就需要使用setInterval了,如:

function tick() { const element = (  <div>Now is {new Date().toLocaleTimeString()}</div> ); ReactDOM.render(  element,  document.getElementById('root') );}setInterval(tick, 1000);

在實際開發中,大多數React應用只會調用一次ReactDOM.render(),所以更好的方式是使用有狀態組件

7、組件和Props

組件(component)能夠將UI劃分為獨立的、可復用的部分,這樣我們就只需專注于構建每一個單獨的部件。
從概念上看,組件就像是函數:接受任意的輸入(稱為屬性,Props),返回React元素。React中有兩種定義組件的方式:函數定義和類定義

1、函數定義組件

這種方式是最簡單的定義組件的方式,就像寫一個JS函數一樣,如:

function Welcome (props) { return <h1>Hello, {props.name}</h1>;;}

2、類定義組件

還可以使用ES6里的類來定義一個組件,如下所示:

class Welcome extends React.Component { render () {  return <h1>Hello, {this.props.name}<h1>; }}

這種方式比起函數定義方式則更加靈活

3、組件渲染

先前,我們遇到的React元素只是呈現一個DOM標簽,如:

const element = <div />

然而,React元素也可以是用戶自定義的組件,如:

const element = <Welcome name="Tom" />

Welcome組件中聲明了一個屬性name="Tom",而這個屬性,將以props.name的方式傳遞給組件,如下方式:

function Welcome (props) { return <h1>Hello, {props.name}</h1>;}

此時,對于以下的代碼:

ReactDOM.render( <Welcome name="張不慫" />, document.getElementById('root'))

最終就會以<h1>Hello, 張不慫</h1>的方式呈現。在這個過程中,發生了如下的事情:

  • 對<Welcome name="張不慫" />元素調用了ReactDOM.render()豐富
  • React將{ name: '張不慫' }作為props實參來調用Welcome組件
  • Welcome完成渲染,返回<h1>Hello, 張不慫</h1>元素
  • ReactDOM計算最小更新代價,然后更新DOM

4、組合組件

組件是可以組合的。即組件內部可以引用其他組件,如:

function Welcome (props) { return <h1>Hello, {props.name}</h1>;}function App () { return (  <div>   <Welcome name="Tom" />   <Welcome name="Jack" />   <Welcome name="Mike" />  </div> )}ReactDOM.render( <App />, document.getElementById('root'))

注意: 在React中,組件必須返回單一的根元素,這也是為什么App組件中需要用<div>標簽包裹的原因。如以下的方式,是錯誤的(因為它有3個根元素):

function App () { return (  <Welcome name="Tom" />  <Welcome name="Jack" />  <Welcome name="Mike" /> )}

5、屬性是只讀的

考慮以下這種情況:

function sum (a, b) { return a + b;}

這種函數稱為純函數:它不改變自己的輸入值,且總是對相同的輸入返回相同的結果。

與之對立的,則是非純函數,如:

function withdraw (account, amount) { account.total -= amount;}

非純函數在函數內改變了輸入的參數。在React中,無論是通過function還是class聲明組件,我們都不應該修改它自身的屬性(props)。雖然React相當靈活,但是它也有一個嚴格的規定:所有的React組件都必須像純函數那樣來使用它們的props

8、State與生命周期

使用類定義組件有一些額外的好處,如擁有本地狀態這一特性。

以下是一個類定義組件

class Clock extends React.Component { render () {  return (   <div>    <h1>Hello, world!</h1>    <h2>Now is {this.props.date.toLocaleTimeString()}</h2>   </div>  ); }}

需要注意的有:

類名即為組件名(無論是函數定義組件還是類定義組件,組件名稱的首字母都必須大寫,并且繼承自React.Component)
使用 render() 方法,用來返回需要呈現的內容

1、在類中加入state

state是屬于一個組件自身的。我們可以在類的構造函數constructor中來初始化狀態,如:

constructor (props) { super(props) this.state = {  date: new Date() }}

如此一來,我們就可以在render()函數中使用this.state.xxx來引用一個狀態

2、生命周期

在應用里,往往都會有許許多多的組件。在組件銷毀后,回收和釋放它們所占據的資源非常重要。

在時鐘應用的例子里,我們需要在第一次渲染到DOM的時候設置一個定時器,并且需要在相應的DOM銷毀后,清除這個定時器。那么,這種情況下,React為我們提供了生命周期的鉤子函數,方便我們進行使用。在React中,生命周期分為:

1)Mount 已插入真實DOM
2)Update 正在重新渲染
3)Unmount 已移出真實DOM

而相應的,生命周期鉤子函數有:

  • componentWillMount
  • componentDidMount
  • componentWillUpdate(newProps, nextState)
  • componentDidUpdate(prevProps, prevState)
  • componentWillUnmount()

此外,還有兩種特殊狀態的處理函數:

  • componentWillReceiveProps(nextProps) 已加載的組件收到新的參數時調動
  • shouldComponentUpdate(nextProps, nextState) 組件判斷是否重新渲染時調用

因此,基于生命周期鉤子函數,我們可以實現一個時鐘應用如下:

class Clock extends React.Component { constructor (props) {  super(props);  this.state = {   date: new Date()  } } tick () {  this.setState({   date: new Date()  }); } componentDidMount () {  this.timerId = setInterval(() => {   this.tick()  }, 1000); } componentWillUnmount () {  clearInterval(this.timerId); } render () {  return (   <div>Now is {this.state.date.toLocaleTimeString()}</div>  ); }}

需要注意的是:

1)render()里用不到的state,不應該聲明在state里
2)不能直接使用this.state.xxx = xxx的方式來改變一個state的值,應該使用this.setState()。如:

setName () { this.setState({  name: '張不慫' })}

this.setState()會自動覆蓋this.state里相應的屬性,并觸發render()重新渲染。

3)狀態更新可能是異步的

React可以將多個setState()調用合并成一個調用來提升性能。且由于this.props和this.state可能是異步更新的,所以不應該依靠它們的值來計算下一個狀態。這種情況下,可以給setState傳入一個函數,如:

this.setState((prevState, props) => ({ counter: prevState.counter + props.increment}));

9、事件處理

React元素的事件與DOM元素類似,不過也有一些區別,如:

1)React事件使用camelCase命名(onClick),而不是全小寫的形式(onclick)
2)使用JSX,傳入的是事件的句柄,而不是一個字符串

如以下的HTML:

<button onclick="increment()">ADD</button>

使用React的方式描述如:

<button onClick={increment}>ADD</button>

還有一個不同在于,在原生DOM中,我們可以通過返回false來阻止默認行為,但是這在React中是行不通的,在React中需要明確使用preventDefault()來阻止默認行為。如:

function ActionLink () { function handleClick (e) {  e.preventDefault();  alert('Hello, world!'); } return (  <a href="#" rel="external nofollow" onClick={handleClick}>Click Me</a> );}

這里,事件回調函數里的event是經過React特殊處理過的(遵循W3C標準),所以我們可以放心地使用它,而不用擔心跨瀏覽器的兼容性問題。

注意: 在使用事件回調函數的時候,我們需要特別注意this的指向問題,因為在React里,除了構造函數和生命周期鉤子函數里會自動綁定this為當前組件外,其他的都不會自動綁定this的指向為當前組件,因此需要我們自己注意好this的綁定問題,
通常而言,在一個類方式聲明的組件里使用事件回調,我們需要在組件的constructor里綁定回調方法的this指向,如:

class Counter extends React.Component { constructor (props) {  super(props);  this.state = {   counter: 0  }  // 在這里綁定指向  this.increment = this.increment.bind(this); } increment () {  this.setState({   counter: this.state.counter + 1  }); } render () {  return (   <div>    The counter now is: {this.state.counter}    <button onClick={this.increment}>+1</button>   </div>  ); }}

當然,我們還有另外一種方法來使用箭頭函數綁定指向,就是使用實驗性的屬性初始化語法,如:

class Counter extends React.Component { increment: () => {  this.setState({   counter: this.state.counter + 1  }); } // ...}

3)像事件處理程序傳遞參數

我們可以為事件處理程序傳遞額外的參數,方式有以下兩種:

<button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button><button onClick={this.deleteRow.bind(this, id)}>Delete Row</button>

需要注意的是,使用箭頭函數的情況下,參數e要顯式傳遞,而使用bind的情況下,則無需顯式傳遞(參數e會作為最后一個參數傳遞給事件處理程序)

10、條件渲染

在React里,我們可以創建不同的組件來封裝我們需要的功能。我們也可以根據組件的狀態,只渲染組件中的一部分內容,而條件渲染就是為此而準備的。在React中,我們可以像在JavaScript中寫條件語句一樣地寫條件渲染語句,如:

function Greet(props) { const isLogined = props.isLogined; if (isLogined) {  return <div>Hello !</div>; } return <div>Please sign in</div>;}ReactDOM.render( <Greet isLogined={true} />, document.getElementById('root'));

這將渲染出:

<div>Hello !</div>

1、使用變量來存儲元素

我們也可以使用變量來存儲元素,如:

function LogBtn(props) { var button; const isLogined = props.isLogined; if (isLogined) {  button = <button>退出</button> } else {  button = <button>登陸</button> } return <div>You can {button}</div>;}ReactDOM.render( <LogBtn isLogined={false} />, document.getElementById('root'));

2、使用&&運算符進行渲染

由于JavaScript語法對待&&運算符的性質,我們也可以使用&&運算符來完成條件渲染,如:

function LogBtn(props) { var button; const isLogined = props.isLogined; return (  <div>Hello  {!isLogined && (   <button>請登陸</button>  )}  </div> )}

當props.isLogined為false的時候,就會渲染出:

<div>Hello <button>請登錄</button></div>

3、使用三目運算符進行渲染

我們可能已經發現了,其實JSX可以像一個表達式那樣子靈活使用,所以,我們自然也可以使用三目運算符進行渲染,如:

function LogBtn (props) { const isLogined = props.isLogined; return (  <div>You can    <button>{isLogined ? '退出' : '登陸'}</button>  </div> )}

4、阻止整個組件的渲染

有時候,我們希望是整個組件都不渲染,而不僅僅是局部不渲染,那么這種情況下,我們就可以在render()函數里返回一個null,來實現我們想要的效果,如:

function LogBtn (props) { const isLogined = props.isLogined; const isShow = props.isShow; if (isShow) {  return (   <div>You can     <button>{isLogined ? '退出' : '登陸'}</button>   </div>  ) } return null;}

注意: 組件里返回null不會影響組件生命周期的觸發,如componentWillUpdate和componentDidUpdate仍然會被調用

11、列表渲染與keys

在JavaScript中,我們可以使用map()函數來對一個數組列表進行操作,如:

const numbers = [1, 2, 3, 4, 5];const doubled = numbers.map(number => number*2);console.log(doubled); // 得到[2, 4, 6, 8, 10]

同樣的,在React里,我們也可以使用map()來進行列表渲染,如:

const numbers = [1, 2, 3, 4, 5];const listItems = numbers.map(number => { return (  <li>{number}</li> )});ReactDOM.render( <ul>{listItems}</ul>, document.getElementById('root'))

這將得到:

<ul><li>1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li></ul>

當然,我們還可以進行更好的封裝,如:

function NumberList (props) { const numbers = props.numbers; const listItems = numbers.map(number => {  return (   <li>{number}</li>  ) }); return <ul>{listItems}</ul>}

當我們運行以上的代碼的時候,會發現控制臺提示:Each child in an array or iterator should have a unique "key" prop,因此,我們需要為列表項的每一個項分配一個key,來解決這個問題,通常而言,我們可以使用以下幾種方式來提供key:

使用數據項自身的ID,如<li key={item.itemId}>
使用索引下標(index),如:

const listItems = numbers.map((number, index) => { <li key={index}>{number}</li>});

但是React不推薦在需要重新排序的列表里使用索引下標,因為會導致變得很慢。
注意: 只有在一個項的同胞里區分彼此的時候,才需要使用到key,key不需要全局唯一,只需要在一個數組內部區分彼此時唯一便可。key的作用是給React一個提示,而不會傳遞給組件。如果我們在組件內需要同樣的一個值,可以換個名字傳遞,如:

const content = posts.map(post => ( <Post key={post.id} id={post.id} style="margin: 0px; padding: 0px; outline: none; line-height: 25.2px; font-size: 14px; width: 660px; overflow: hidden; clear: both; font-family: tahoma, arial, "Microsoft YaHei";">	
class NameForm extends React.Component { constructor (props) {  super(props);  this.state = {   value: ''  }  this.handleChange = this.handleChange.bind(this);  this.handleSubmit = this.handleSubmit.bind(this); } handleChange (event) {  this.setState({   value: event.target.value  }); } handleSubmit (event) {  alert('Your name is '+this.state.value);  event.preventDefault(); }  render () {  return (   <form onSubmit={this.handleSubmit}>   Name: <input type="text" value={this.state.value} onChange={this.handleChange} />   <input type="submit" value="Submit" />   </form>  ) }}

和HTML中不同的是,React中的textarea并不需要寫成<textarea></textarea>的形式,而是寫成<textarea value="" ... />的形式便可。而對于HTML中的select標簽,通常做法是:

<select> <option value="A">A</option> <option value="B" selected>B</option> <option value="C">C</option></select>

但是React中,不需要在需要選中的option處加入selected,而只需要傳入一個value,就會自動根據value來選中相應的選項,如:

<select value="C"> <option value="A">A</option> <option value="B">B</option> <option value="C">C</option></select>

那么如上述例子,C所在的這個option就會被選中

2、多個輸入的解決辦法

通常一個表單都有多個輸入,如果我們為每一個輸入添加處理事件,那么將會非常繁瑣。好的一個解決辦法是,使用name,然后根據event.target.name來選擇做什么。如:

class Form extends React.Component { constructor (props) {  super(props);  this.state = {   name: '',   gender: '男',   attend: false,   profile: ''  };  this.handleInputChange = this.handleInputChange.bind(this);  this.handleSubmit = this.handleSubmit.bind(this); } handleInputChange (event) {  const target = event.target;  const value = target.type==='checkbox' ? target.checked : target.value;  const name = target.name;  this.setState({   [name]: value  }); } handleSubmit (event) {  this.setState({   profile: `姓名:${this.state.name},${this.state.gender},${this.state.attend ? '參加' : '不參加'}活動`  });  event.preventDefault(); }  render () {  return (   <form>   <p>姓名:<input name="name" value={this.state.name} onChange={this.handleInputChange} /></p>   <p>性別:    <select name="gender" value={this.state.gender} onChange={this.handleInputChange}>     <option value="男">男</option>     <option value="女">女</option>    </select>   </p>   <p>是否參加:<input name="attend" type="checkbox" onChange={this.handleInputChange} checked={this.state.attend} /></p>   <input type="submit" value="Submit" onClick={this.handleSubmit} />   <p>您的報名信息:{this.state.profile}</p>   </form>  ) }}

3、非受控組件

大多數情況下,使用受控組件實現表單是首選,在受控組件中,表單數據是交由React組件處理的。如果想要讓表單數據由DOM處理(即數據不保存在React的狀態里,而是保存在DOM中),那么可以使用非受控組件,使用非受控組件,可以無需為每個狀態更新編寫事件處理程序,使用ref即可實現,如:

class NameForm extends React.Component { constrcutor(props) {  super(props) } handleSubmit(event) {  console.log('A name was submitted: ', this.input.value)  event.preventDefault() } render() {  return (   <form onSubmit={this.handleSubmit}>    <label>    Name: <input type="text" ref={input => this.input = input} />    </label>    <input type="submit" value="submit" />   </form>  ) }}

對于非受控組件,如果要指定默認值,那么可以使用defaultValue,如:

<input type="text" defaultValue="Hello" ref={input => this.input = input} />

相應的,type="checkbox"和type="radio",則使用defaultChecked

13、狀態提升

當需要幾個組件共用狀態數據的時候,可以使用狀態提升技術。核心思想在于:把數據抽離到最近的共同父組件,父組件管理狀態(state),然后通過屬性(props)傳遞給子組件。如實現一個貨幣轉換的組件,可以如下:

1、首先定義轉換函數

function USD2RMB (amount) { return amount * 6.7925;}function RMB2USD (amount) { return amount * 0.1472;}function convert (amount, typeFn) { return typeFn(amount);}

2、定義組件

我們希望在RMB的輸入表單上上輸入的時候,USD的輸入表單上的數值也同步更新,這種情況下,如果RMB組件自己管理自己的狀態,是很難以實現的,因此,我們需要讓這個狀態提升自父組件進行管理。如下:

class CurrencyInput extends React.Component { constructor (props) {  super(props)  this.handleChange = this.handleChange.bind(this) } handleChange (event) {  this.props.onInputChange(event.target.value) } render () {  const value = this.props.value  const type = this.props.type  return (   <p>{type}: <input type="text" value={value} onChange={this.handleChange} /></p>  ); }}

最后定義一個共同的父組件,如下:

class CurrencyConvert extends Component { constructor (props) {  super(props);  this.state = {   type: 'RMB',   amount: 0  }  this.handleRMBChange = this.handleRMBChange.bind(this);  this.handleUSDChange = this.handleUSDChange.bind(this); } handleRMBChange (amount) {  this.setState({   type: 'RMB',   amount  }); } handleUSDChange (amount) {  this.setState({   type: 'USD',   amount  }); } render () {  const type = this.state.type;  const amount = this.state.amount;  const RMB = type==='RMB' ? amount : convert(amount, USB2RMB);  const USD = type==='USD' ? amount : convert(amount, RMB2USB);  return (   <div>    <p>Please Input:</p>    <CurrencyInput type="RMB" value={RMB} onInputChange={this.handleRMBChange} />    <CurrencyInput type="USD" value={USD} onInputChange={this.handleUSDChange} />   </div>  ); }}

14、組合vs繼承

React推崇更多的是使用組合,而非使用繼承。對于一些使用場景,React給出的建議如下:

1、包含關系

當父組件不知道子組件可能的內容是什么的時候,可以使用props.children,如:

function Article (props) { return (  <section>   <aside>側邊欄</aside>   <article>{props.children}</article>  </section> );}function App () { return (  <Article>這是一篇文章</Article> );}

這將渲染得到:

<section> <aside>側邊欄</aside> <article>這是一篇文章</article></section>

我們還可以自定義名稱,因為JSX實際上會被轉化為合法的JS表達式,所以,還可以有:

function Article (props) { return (  <section>   <aside>{props.aside}</aside>   <article>{props.children}</article>  </section> );}function App () { return (  <Article aside={   <h1>這是一個側欄</h1>  }>這是一篇文章</Article> );}

這將渲染得到:

<section> <aside><h1>這是一個側欄</h1></aside> <article>這是一篇文章</article></section>

2、何時使用繼承?

在Facebook的網站上,使用了數以千計的組件,但是實踐證明還沒有發現需要使用繼承才能解決的情況。

屬性和組合為我們提供了清晰的、安全的方式來自定義組件的樣式和行為,組件可以接受任意元素,包括:基本數據類型、React元素、函數。

如果要在組件之間復用UI無關的功能,那么應該將其提取到單獨的JavaScript模塊中,這樣子可以在不對組件進行擴展的前提下導入并使用函數、對象、類

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VeVb武林網。


注:相關教程知識閱讀請移步到JavaScript/Ajax教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美日韩在线另类| 最近2019免费中文字幕视频三| 日韩av免费在线播放| 亚洲精品乱码久久久久久按摩观| 亚洲jizzjizz日本少妇| 亚洲精品在线91| 狠狠色香婷婷久久亚洲精品| 色哟哟网站入口亚洲精品| 日韩欧美中文字幕在线观看| 国产噜噜噜噜噜久久久久久久久| 91精品在线观| 精品丝袜一区二区三区| 亚洲第一天堂无码专区| 国产中文字幕亚洲| 欧美成人免费小视频| 国产一区二区三区免费视频| 日本久久久久亚洲中字幕| 精品人伦一区二区三区蜜桃免费| 成人久久一区二区三区| 精品无人区乱码1区2区3区在线| 欧美性感美女h网站在线观看免费| 亚洲免费小视频| 亚洲美女精品成人在线视频| 亚洲国产精品成人va在线观看| 91精品国产99久久久久久| 成人国产精品久久久| 8x海外华人永久免费日韩内陆视频| 久久久久久久97| 国产成人综合亚洲| 成人xvideos免费视频| 精品久久久久久中文字幕大豆网| 日韩一区二区三区xxxx| 亚洲视频在线免费观看| 欧美激情欧美激情在线五月| 日韩极品精品视频免费观看| 日韩av在线免费看| 久久久久久91香蕉国产| 日韩精品在线观看一区| 国产欧美中文字幕| 欧美成人精品激情在线观看| 日韩免费在线观看视频| 欧美电影在线播放| 日韩av大片在线| 91精品国产自产91精品| 久久久久久久国产| 欧美日韩免费一区| 91精品国产综合久久香蕉922| 2019日本中文字幕| 欧美精品激情在线观看| 4438全国亚洲精品在线观看视频| 中文字幕一区二区精品| 亚洲香蕉在线观看| 欧亚精品中文字幕| 性色av一区二区三区| 国产香蕉精品视频一区二区三区| 欧美大码xxxx| 成人欧美一区二区三区黑人| 亚洲va欧美va在线观看| 98精品国产高清在线xxxx天堂| 成人福利视频网| 亚洲成人免费在线视频| 精品久久久久久久久久久| 成人国产在线激情| 国产精品爱啪在线线免费观看| 成人网页在线免费观看| 国产欧亚日韩视频| 国产91精品黑色丝袜高跟鞋| 日韩一区视频在线| 久久精品国产精品| 国内揄拍国内精品| 亚洲最大激情中文字幕| 红桃av永久久久| 九九热这里只有精品6| 久久久久久香蕉网| 青青在线视频一区二区三区| 成人黄色在线免费| 98精品国产自产在线观看| 91国内揄拍国内精品对白| 富二代精品短视频| 国产精品 欧美在线| 亚洲成人国产精品| 96pao国产成视频永久免费| 国产精品草莓在线免费观看| 国产伦精品免费视频| 97**国产露脸精品国产| 日韩一中文字幕| 国产美女直播视频一区| 欧美一级大片在线免费观看| 欧美精品国产精品日韩精品| 国产精品免费小视频| 亚洲国产欧美一区二区三区久久| 精品国产一区二区在线| 久久久久亚洲精品成人网小说| 高清日韩电视剧大全免费播放在线观看| 懂色aⅴ精品一区二区三区蜜月| 久久99精品国产99久久6尤物| 日韩欧美在线视频| 久久成年人视频| 欧美亚洲伦理www| 欧美与欧洲交xxxx免费观看| 久久国产视频网站| 国产精品久久久久久久久久东京| 日韩三级影视基地| 中文字幕亚洲欧美一区二区三区| 欧美激情精品久久久久久黑人| 欧美一区二粉嫩精品国产一线天| 国产精品午夜一区二区欲梦| 亚洲精品www| 久久好看免费视频| 韩国福利视频一区| 亚洲a∨日韩av高清在线观看| 日韩精品免费综合视频在线播放| 伊人久久久久久久久久久| 毛片精品免费在线观看| 亚洲一区二区三区777| 亚洲国产91色在线| 亚洲精品日韩av| 亚洲精品免费一区二区三区| 97香蕉超级碰碰久久免费软件| 国语自产精品视频在免费| 欧美性极品xxxx娇小| 最近2019免费中文字幕视频三| 一本大道香蕉久在线播放29| 日韩成人在线网站| 久久亚洲精品一区二区| 国产亚洲xxx| 久久国产精品久久久久久久久久| 97视频在线观看成人| 欧美一性一乱一交一视频| 日韩专区在线播放| 日韩国产高清污视频在线观看| 欧美三级免费观看| 久久国产视频网站| 亚洲影院高清在线| 亚洲成人精品av| 国产精品国内视频| 亚洲欧美日韩高清| 欧美电影免费观看电视剧大全| 精品偷拍一区二区三区在线看| 久久久精品一区| 精品视频久久久久久久| 日韩av片免费在线观看| 95av在线视频| 精品久久久久久| 国产激情视频一区| 亚洲3p在线观看| 成人网在线免费看| 国内揄拍国内精品少妇国语| 欧美超级免费视 在线| 亚洲女同精品视频| 久久精品久久久久久国产 免费| 国产精品电影在线观看| 欧美成人国产va精品日本一级| 国产精品无av码在线观看| 欧美成人精品在线观看| 亚洲激情视频网站| 成人情趣片在线观看免费| 亚洲偷欧美偷国内偷| 久青草国产97香蕉在线视频| 欧美日韩亚洲天堂| 亚洲精品美女在线观看| 亚洲在线一区二区| 久久久噜久噜久久综合| 亚洲欧美在线免费|