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

Vue.js源碼(1):Hello World的背后

開發(fā) 前端
下面的代碼會(huì)在頁(yè)面上輸出Hello World,但是在這個(gè)new Vue()到頁(yè)面渲染之間,到底發(fā)生了什么。這篇文章希望通過最簡(jiǎn)單的例子,去了解Vue源碼過程。

[[171807]]

下面的代碼會(huì)在頁(yè)面上輸出Hello World,但是在這個(gè)new Vue()到頁(yè)面渲染之間,到底發(fā)生了什么。這篇文章希望通過最簡(jiǎn)單的例子,去了解Vue源碼過程。這里分析的源碼版本是Vue.version = '1.0.20' 

  1. <div id="mountNode">{{message}}</div>  
  1. var vm = new Vue({ 
  2.     el: '#mountNode'
  3.     data: function () { 
  4.         return { 
  5.             message: 'Hello World' 
  6.         }; 
  7.     } 
  8. }); 

 這篇文章將要解決幾個(gè)問題:

  1. new Vue()的過程中,內(nèi)部到底有哪些步驟
  2. 如何收集依賴
  3. 如何計(jì)算表達(dá)式
  4. 如何表達(dá)式的值如何反應(yīng)在DOM上的

簡(jiǎn)單來說過程是這樣的:

  1. observe: 把{message: 'Hello World'}變成是reactive的
  2. compile: compileTextNode "{{message}}",解析出指令(directive = v-text)和表達(dá)式(expression = message),創(chuàng)建fragment(new TextNode)準(zhǔn)備替換
  3. link:實(shí)例化directive,將創(chuàng)建的fragment和directive鏈接起來,將fragment替換在DOM上
  4. bind: 通過directive對(duì)應(yīng)的watcher獲取依賴(message)的值("Hello World"),v-text去update值到fragment上

詳細(xì)過程,接著往下看。

構(gòu)造函數(shù)

文件路徑:src/instance/vue.js 

  1. function Vue (options) { 
  2.   this._init(options) 
  3.  

初始化

這里只拿對(duì)例子理解最關(guān)鍵的步驟分析。文件路徑:src/instance/internal/init.js 

  1. Vue.prototype._init = function (options) { 
  2.     ... 
  3.     // merge options. 
  4.     options = this.$options = mergeOptions( 
  5.       this.constructor.options, 
  6.       options, 
  7.       this 
  8.     ) 
  9.     ... 
  10.     // initialize data observation and scope inheritance. 
  11.     this._initState() 
  12.     ... 
  13.     // if `el` option is passed, start compilation. 
  14.     if (options.el) { 
  15.       this.$mount(options.el) 
  16.     } 

 merge options

mergeOptions()定義在src/util/options.js文件中,這里主要定義options中各種屬性的合并(merge),例如:props, methods, computed, watch等。另外,這里還定義了每種屬性merge的默認(rèn)算法(strategy),這些strategy都可以配置的,參考Custom Option Merge Strategy

在本文的例子中,主要是data選項(xiàng)的merge,在merge之后,放到$options.data中,基本相當(dāng)于下面這樣: 

  1. vm.$options.data = function mergedInstanceDataFn () { 
  2.       var parentVal = undefined 
  3.        
  4.       // 這里就是在我們定義的options中的data 
  5.       var childVal = function () { 
  6.           return { 
  7.               message: 'Hello World' 
  8.           } 
  9.       } 
  10.        
  11.       // data function綁定vm實(shí)例后執(zhí)行,執(zhí)行結(jié)果: {message: 'Hello World'
  12.       var instanceData = childVal.call(vm) 
  13.        
  14.       // 對(duì)象之間的merge,類似$.extend,結(jié)果肯定就是:{message: 'Hello World'
  15.       return mergeData(instanceData, parentVal) 
  16.  

init data

_initData()發(fā)生在_initState()中,主要做了兩件事:

  1. 代理data中的屬性
  2. observe data

文件路徑:src/instance/internal/state.js 

  1. Vue.prototype._initState = function () { 
  2.     this._initProps() 
  3.     this._initMeta() 
  4.     this._initMethods() 
  5.     this._initData() // 這里 
  6.     this._initComputed() 
  7.   }  

屬性代理(proxy)

把data的結(jié)果賦值給內(nèi)部屬性:文件路徑:src/instance/internal/state.js 

  1. var dataFn = this.$options.data // 上面我們得到的mergedInstanceDataFn函數(shù) 
  2. var data = this._data = dataFn ? dataFn() : {}  

代理(proxy)data中的屬性到_data,使得vm.message === vm._data.message:

文件路徑:src/instance/internal/state.js 

  1. /** 
  2.   * Proxy a property, so that 
  3.   * vm.prop === vm._data.prop 
  4.   */ 
  5. Vue.prototype._proxy = function (key) { 
  6.     if (!isReserved(key)) { 
  7.       var self = this 
  8.       Object.defineProperty(self, key, { 
  9.         configurable: true
  10.         enumerable: true
  11.         get: function proxyGetter () { 
  12.           return self._data[key
  13.         }, 
  14.         setfunction proxySetter (val) { 
  15.           self._data[key] = val 
  16.         } 
  17.       }) 
  18.     } 
  19.   } 

 observe

這里是我們的***個(gè)重點(diǎn),observe過程。在_initData()***,調(diào)用了observe(data, this)對(duì)數(shù)據(jù)進(jìn)行observe。在hello world例子里,observe()函數(shù)主要是針對(duì){message: 'Hello World'}創(chuàng)建了Observer對(duì)象。

文件路徑:src/observer/index.js 

  1. var ob = new Observer(value) // value = data = {message:'Hello World'

在observe()函數(shù)中還做了些能否observe的條件判斷,這些條件有:

  1. 沒有被observe過(observe過的對(duì)象都會(huì)被添加__ob__屬性)
  2. 只能是plain object(toString.call(ob) === "[object Object]")或者數(shù)組
  3. 不能是Vue實(shí)例(obj._isVue !== true)
  4. object是extensible的(Object.isExtensible(obj) === true)

Observer

官網(wǎng)的Reactivity in Depth上有這么句話:

When you pass a plain JavaScript object to a Vue instance as its data option, Vue.js will walk through all of its properties and convert them to getter/setters

The getter/setters are invisible to the user, but under the hood they enable Vue.js to perform dependency-tracking and change-notification when properties are accessed or modified

Observer就是干這個(gè)事情的,使data變成“發(fā)布者”,watcher是訂閱者,訂閱data的變化。

 在例子中,創(chuàng)建observer的過程是:

  1. new Observer({message: 'Hello World'}) 
  2. 實(shí)例化一個(gè)Dep對(duì)象,用來收集依賴
  3. walk(Observer.prototype.walk())數(shù)據(jù)的每一個(gè)屬性,這里只有message
  4. 將屬性變成reactive的(Observer.protoype.convert())

convert()里調(diào)用了defineReactive(),給data的message屬性添加reactiveGetter和reactiveSetter

文件路徑:src/observer/index.js 

  1. export function defineReactive (obj, key, value) { 
  2.     ... 
  3.     Object.defineProperty(obj, key, { 
  4.     enumerable: true
  5.     configurable: true
  6.     get: function reactiveGetter () { 
  7.       ... 
  8.       if (Dep.target) { 
  9.         dep.depend() // 這里是收集依賴 
  10.         ... 
  11.       } 
  12.       return value 
  13.     }, 
  14.     setfunction reactiveSetter (newVal) { 
  15.       ... 
  16.       if (setter) { 
  17.         setter.call(obj, newVal) 
  18.       } else { 
  19.         val = newVal 
  20.       } 
  21.       ... 
  22.       dep.notify() // 這里是notify觀察這個(gè)數(shù)據(jù)的依賴(watcher) 
  23.     } 
  24.   }) 

 關(guān)于依賴收集和notify,主要是Dep類

文件路徑:src/observer/dep.js 

  1. export default function Dep () { 
  2.   this.id = uid++ 
  3.   this.subs = [] 

 這里的subs是保存著訂閱者(即watcher)的數(shù)組,當(dāng)被觀察數(shù)據(jù)發(fā)生變化時(shí),即被調(diào)用setter,那么dep.notify()就循環(huán)這里的訂閱者,分別調(diào)用他們的update方法。

但是在getter收集依賴的代碼里,并沒有看到watcher被添加到subs中,什么時(shí)候添加進(jìn)去的呢?這個(gè)問題在講到Watcher的時(shí)候再回答。

mount node

按照生命周期圖上,observe data和一些init之后,就是$mount了,最主要的就是_compile。

文件路徑:src/instance/api/lifecycle.js 

  1. Vue.prototype.$mount = function (el) { 
  2.     ... 
  3.     this._compile(el) 
  4.     ... 
  5.   }  

_compile里分兩步:compile和link

compile

compile過程是分析給定元素(el)或者模版(template),提取指令(directive)和創(chuàng)建對(duì)應(yīng)離線的DOM元素(document fragment)。

文件路徑:src/instance/internal/lifecycle.js 

  1. Vue.prototype._compile = function (el) { 
  2.     ... 
  3.     var rootLinker = compileRoot(el, options, contextOptions) 
  4.     ... 
  5.     var rootUnlinkFn = rootLinker(this, el, this._scope) 
  6.     ... 
  7.     var contentUnlinkFn = compile(el, options)(this, el) 
  8.     ... 

 例子中compile #mountNode元素,大致過程如下:

  1. compileRoot:由于root node(<div id="mountNode"></div>)本身沒有任何指令,所以這里compile不出什么東西
  2. compileChildNode:mountNode的子node,即內(nèi)容為"{{message}}"的TextNode
  3. compileTextNode:

3.1 parseText:其實(shí)就是tokenization(標(biāo)記化:從字符串中提取符號(hào),語句等有意義的元素),得到的結(jié)果是tokens

3.2 processTextToken:從tokens中分析出指令類型,表達(dá)式和過濾器,并創(chuàng)建新的空的TextNode

3.3 創(chuàng)建fragment,將新的TextNode append進(jìn)去

parseText的時(shí)候,通過正則表達(dá)式(/\{\{\{(.+?)\}\}\}|\{\{(.+?)\}\}/g)匹配字符串"{{message}}",得出的token包含這些信息:“這是個(gè)tag,而且是文本(text)而非HTML的tag,不是一次性的插值(one-time interpolation),tag的內(nèi)容是"message"”。這里用來做匹配的正則表達(dá)式是會(huì)根據(jù)delimiters和unsafeDelimiters的配置動(dòng)態(tài)生成的。

processTextToken之后,其實(shí)就得到了創(chuàng)建指令需要的所有信息:指令類型v-text,表達(dá)式"message",過濾器無,并且該指令負(fù)責(zé)跟進(jìn)的DOM是新創(chuàng)建的TextNode。接下來就是實(shí)例化指令了。

link

每個(gè)compile函數(shù)之后都會(huì)返回一個(gè)link function(linkFn)。linkFn就是去實(shí)例化指令,將指令和新建的元素link在一起,然后將元素替換到DOM tree中去。每個(gè)linkFn函數(shù)都會(huì)返回一個(gè)unlink function(unlinkFn)。unlinkFn是在vm銷毀的時(shí)候用的,這里不介紹。

實(shí)例化directive:new Directive(description, vm, el)

description是compile結(jié)果token中保存的信息,內(nèi)容如下: 

  1. description = { 
  2.     name'text', // text指令 
  3.     expression: 'message'
  4.     filters: undefined, 
  5.     def: vTextDefinition 

 def屬性上的是text指令的定義(definition),和Custome Directive一樣,text指令也有bind和update方法,其定義如下:

文件路徑:src/directives/public/text.js 

  1. export default { 
  2.  
  3.   bind () { 
  4.     this.attr = this.el.nodeType === 3 
  5.       ? 'data' 
  6.       : 'textContent' 
  7.   }, 
  8.  
  9.   update (value) { 
  10.     this.el[this.attr] = _toString(value) 
  11.   } 

 new Directive()構(gòu)造函數(shù)里面只是一些內(nèi)部屬性的賦值,真正的綁定過程還需要調(diào)用Directive.prototype._bind,它是在Vue實(shí)例方法_bindDir()中被調(diào)用的。

在_bind里面,會(huì)創(chuàng)建watcher,并***次通過watcher去獲得表達(dá)式"message"的計(jì)算值,更新到之前新建的TextNode中去,完成在頁(yè)面上渲染"Hello World"。

watcher

For every directive / data binding in the template, there will be a corresponding watcher object, which records any properties “touched” during its evaluation as dependencies. Later on when a dependency’s setter is called, it triggers the watcher to re-evaluate, and in turn causes its associated directive to perform DOM updates.

每個(gè)與數(shù)據(jù)綁定的directive都有一個(gè)watcher,幫它監(jiān)聽表達(dá)式的值,如果發(fā)生變化,則通知它update自己負(fù)責(zé)的DOM。一直說的dependency collection就在這里發(fā)生。

Directive.prototype._bind()里面,會(huì)new Watcher(expression, update),把表達(dá)式和directive的update方法傳進(jìn)去。

Watcher會(huì)去parseExpression:

文件路徑:src/parsers/expression.js 

  1. export function parseExpression (exp, needSet) { 
  2.   exp = exp.trim() 
  3.   // try cache 
  4.   var hit = expressionCache.get(exp) 
  5.   if (hit) { 
  6.     if (needSet && !hit.set) { 
  7.       hit.set = compileSetter(hit.exp) 
  8.     } 
  9.     return hit 
  10.   } 
  11.   var res = { exp: exp } 
  12.   res.get = isSimplePath(exp) && exp.indexOf('[') < 0 
  13.     // optimized super simple getter 
  14.     ? makeGetterFn('scope.' + exp) 
  15.     // dynamic getter 
  16.     : compileGetter(exp) 
  17.   if (needSet) { 
  18.     res.set = compileSetter(exp) 
  19.   } 
  20.   expressionCache.put(exp, res) 
  21.   return res 
  22.  

這里的expression是"message",單一變量,被認(rèn)為是簡(jiǎn)單的數(shù)據(jù)訪問路徑(simplePath)。simplePath的值如何計(jì)算,怎么通過"message"字符串獲得data.message的值呢?

獲取字符串對(duì)應(yīng)的變量的值,除了用eval,還可以用Function。上面的makeGetterFn('scope.' + exp)返回: 

  1. var getter = new Function('scope''return ' + body + ';') // new Function('scope''return scope.message;'

Watch.prototype.get()獲取表達(dá)式值的時(shí)候, 

  1. var scope = this.vm 
  2. getter.call(scope, scope) // 即執(zhí)行vm.message  

由于initState時(shí)對(duì)數(shù)據(jù)進(jìn)行了代理(proxy),這里的vm.message即為vm._data.message,即是data選項(xiàng)中定義的"Hello World"。

值拿到了,那什么時(shí)候?qū)essage設(shè)為依賴的呢?這就要結(jié)合前面observe data里說到的reactiveGetter了。

文件路徑:src/watcher.js 

  1. Watcher.prototype.get = function () { 
  2.   this.beforeGet()        // -> Dep.target = this 
  3.   var scope = this.scope || this.vm 
  4.   ... 
  5.   var value value = this.getter.call(scope, scope) 
  6.   ... 
  7.   this.afterGet()         // -> Dep.target = null 
  8.   return value 
  9.  

watcher獲取表達(dá)式的值分三步:

  1. beforeGet:設(shè)置Dep.target = this
  2. 調(diào)用表達(dá)式的getter,讀取(getter)vm.message的值,進(jìn)入了message的reactiveGetter,由于Dep.target有值,因此執(zhí)行了dep.depend()將target,即當(dāng)前watcher,收入dep.subs數(shù)組里
  3. afterGet:設(shè)置Dep.target = null

這里值得注意的是Dep.target,由于JS的單線程特性,同一時(shí)刻只能有一個(gè)watcher去get數(shù)據(jù)的值,所以target在全局下只需要有一個(gè)就可以了。

文件路徑:src/observer/dep.js 

  1. // the current target watcher being evaluated. 
  2. // this is globally unique because there could be only one 
  3. // watcher being evaluated at any time
  4. Dep.target = null  

就這樣,指令通過watcher,去touch了表達(dá)式中涉及到的數(shù)據(jù),同時(shí)被該數(shù)據(jù)(reactive data)保存為其變化的訂閱者(subscriber),數(shù)據(jù)變化時(shí),通過dep.notify() -> watcher.update() -> directive.update() -> textDirective.update(),完成DOM的更新。

到這里,“Hello World”怎么渲染到頁(yè)面上的過程基本就結(jié)束了。這里針對(duì)最簡(jiǎn)單的使用,挑選了最核心的步驟進(jìn)行分析,更多內(nèi)部細(xì)節(jié),后面慢慢分享。

責(zé)任編輯:龐桂玉 來源: segmentfault
相關(guān)推薦

2011-06-08 14:39:06

Qt 教程

2016-09-21 13:32:13

JavascriptWeb前端

2011-09-08 10:41:12

Node.js

2013-12-12 17:30:03

Lua例子

2018-04-04 10:32:13

前端JavascriptVue.js

2017-07-04 17:55:37

Vue.js插件開發(fā)

2016-11-04 19:58:39

vue.js

2011-03-14 09:33:35

Mono

2014-12-19 10:07:10

C

2017-11-23 17:45:46

Yii框架IntelYii框架深度剖析

2020-09-16 06:12:30

Vue.js 3.0Suspense組件前端

2017-08-30 17:10:43

前端JavascriptVue.js

2018-07-10 15:35:33

Vue前端架構(gòu)

2022-01-19 22:18:56

Vue.jsVue SPA開發(fā)

2017-07-20 11:18:22

Vue.jsMVVMMVC

2024-05-13 08:04:26

Vue.jsWeb應(yīng)用程序

2017-07-11 18:00:21

vue.js數(shù)據(jù)組件

2021-01-22 11:47:27

Vue.js響應(yīng)式代碼

2016-11-01 19:10:33

vue.js前端前端框架

2020-09-07 14:40:20

Vue.js構(gòu)建工具前端
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

成人精品视频一区| 色综合久久久| 99re热视频这里只精品| 久久综合九色综合97婷婷| 欧洲在线/亚洲| 免费国产一区二区| 最近中文字幕在线免费观看 | 午夜羞羞小视频在线观看| 99精品网站| 91麻豆精品国产自产在线 | 免费av毛片在线看| 成人永久免费视频| 日韩av免费在线| 国产视频不卡在线| 日韩精品亚洲人成在线观看| 国产精品欧美一区二区三区不卡| 亚洲成av在线| 国产精品欧美久久久久一区二区 | 国产日韩欧美综合| 佐佐木明希电影| 欧洲成人一区二区三区| 黄色在线一区| 一区二区三区日韩在线| 日本高清久久久| 免费a级片在线观看| 亚洲国产高清视频| 欧美精品乱人伦久久久久久| 亚洲综合av一区| 刘玥91精选国产在线观看| 精品999网站| 最新亚洲国产精品| 欧美日韩黄色一级片| 中文字幕在线2018| 亚洲高清成人| 中文字幕综合在线| 黄色动漫在线免费看| 国产喷水吹潮视频www| 国产综合自拍| 中文字幕精品www乱入免费视频| 性生生活大片免费看视频| 欧美6一10sex性hd| 日韩成人av影视| 亚洲欧美综合v| 欧美成在线视频| 久久久久久九九| 国产午夜精品理论片| 少妇精品视频在线观看| 亚州成人在线电影| 91视频免费在线观看| 国产又粗又长又硬| 另类激情视频| 亚洲欧美偷拍卡通变态| 明星裸体视频一区二区| 99久久国产免费| 秋霞av亚洲一区二区三| 精品亚洲一区二区三区在线播放| 亚洲爆乳无码精品aaa片蜜桃| 三级在线观看| 不卡欧美aaaaa| 91精品视频网站| 在线视频精品免费| 亚洲尤物精选| 欧洲成人免费视频| 亚洲日本韩国在线| 色综合久久中文| 亚洲成av人在线观看| 亚洲福利av在线| 国产最新视频在线| 蜜乳av一区二区| 国产精品 欧美在线| 久久久久久久久97| 一级欧美视频| 亚洲自拍偷拍av| 久久久久久99| 天天干在线观看| 成人精品在线视频观看| 亚洲一区二区在线| 国产片高清在线观看| 久久99精品国产麻豆不卡| 尤物yw午夜国产精品视频明星| 在线观看亚洲免费视频| 麻豆蜜桃在线观看| 激情懂色av一区av二区av| 亚洲乱码日产精品bd在线观看| 麻豆免费在线观看| 136国产福利精品导航| 国产精品久久久久久久久久新婚| 999国产在线| 貂蝉被到爽流白浆在线观看| 99a精品视频在线观看| 欧美一级欧美一级在线播放| 手机看片福利盒子久久| 亚洲va中文在线播放免费| 欧美三级欧美成人高清www| 久久久久高清| 免费在线国产| 国产精品网曝门| 四虎影院一区二区| 午夜成年人在线免费视频| 国产日韩精品视频一区| 亚洲综合第一页| 国产三级按摩推拿按摩| 国产中文字幕一区| 91九色偷拍| 亚洲欧洲成人在线| 日韩国产欧美在线视频| 国产精品久久久久久久久久新婚 | 国产日韩中文在线中文字幕| 欧美剧情片在线观看| 无套内谢丰满少妇中文字幕| 国产成人免费视频网站视频社区 | 在线a人片免费观看视频| 精品一区二区三区蜜桃| 国产一区香蕉久久| www.看毛片| 91免费视频网址| 亚洲三区在线| 黄页网站在线观看免费| 偷偷要91色婷婷| 精品日韩久久久| 国产一区二区| 国产亚洲精品日韩| 久久免费黄色网址| 久久国产综合精品| 黄色国产精品一区二区三区| 香蕉视频黄在线观看| 欧美国产一区二区在线观看| 91精品欧美福利在线观看| 深夜福利成人| 黄网站在线观| 欧美三级在线播放| 中文字幕精品视频在线| 成人羞羞网站入口| 欧美福利在线观看| 怡春院在线视频| av网站一区二区三区| 日韩三级电影网站| 第一福利在线视频| 日韩美一区二区三区| 鲁大师私人影院在线观看| 日本一区二区在线看| 欧美国产在线视频| 一级黄色片在线看| 2020日本不卡一区二区视频| 先锋影音一区二区三区| 9999在线视频| 亚洲欧美激情视频在线观看一区二区三区 | 国产精品久久久久久久小唯西川| 乱子伦一区二区三区| 免费在线看一区| 国产无套精品一区二区| 久操视频在线| 欧美日韩中文另类| 色屁屁草草影院ccyy.com| 亚洲国产精品一区| 91色视频在线导航| 免费在线看黄色| 欧美亚洲国产怡红院影院| 欧美另类一区| 日韩人妻无码精品久久久不卡| 羞羞视频在线观看免费| 欧美色男人天堂| 性欧美一区二区| 久久aⅴ国产紧身牛仔裤| 粉嫩高清一区二区三区精品视频 | 日本在线播放| 欧美羞羞免费网站| 美女100%露胸无遮挡| 欧美暴力喷水在线| 亚洲r级在线观看| 国产日产一区二区三区| 欧美在线观看你懂的| 好吊日免费视频| 国产精品theporn| 99re在线| 黄视频在线免费看| 亚洲精品国产精品国自产在线 | 欧美人与性动交α欧美精品图片| 欧美日韩在线精品一区二区三区激情| 亚洲性猛交xxxx乱大交| 欧美一区 二区| 国产一区二区三区四区福利| 久久久久久久久久网站| 国产在线一区观看| 欧美黑人在线观看| 精品国产午夜肉伦伦影院| 久久精品日产第一区二区| 国模吧一区二区| 五月天激情婷婷| 日韩欧美在线视频免费观看| 秘密基地免费观看完整版中文| 欧美久久综合| 久久爱av电影| 国精产品一区二区三区有限公司| 亚洲天堂男人天堂女人天堂| 欧美一区二区激情视频| 91免费视频大全| 色婷婷综合久久久久中文字幕| 91欧美在线| 久久99精品国产99久久| 91亚洲精品| 韩国一区二区电影| 青青青青在线| 日韩大陆欧美高清视频区| 美女100%露胸无遮挡| 久草在线在线精品观看| r级无码视频在线观看| 欧美精品一区二区三区精品| 国产精品久久久久久久久久久不卡| 欧美13一16娇小xxxx| 亚洲电影免费观看| 日干夜干天天干| 国产精品久久久久一区| 中文字幕99页| 久久超碰97中文字幕| 国产片高清在线观看| 亚洲线精品一区二区三区| 欧美bbbbb性bbbbb视频| 黄色小说综合网站| 可以在线看的黄色网址| 欧美777四色影| 亚洲精品日韩在线观看| 日韩中文一区二区| 国产日本欧美在线观看| 深夜在线视频| 久久久久久国产精品三级玉女聊斋 | 欧美日韩水蜜桃| 精品网站在线看| 亚洲3区在线| 国产专区精品视频| 99久久综合国产精品二区| 国产乱人伦偷精品视频免下载| 91久久精品久久国产性色也91| 久草免费在线视频| 久久久久久国产精品| h网站久久久| 精品国产依人香蕉在线精品| 蜜桃视频污在线观看| 91精品婷婷国产综合久久性色| 国产成人精品777777| 午夜精品久久久久久久久久久| 破处女黄色一级片| 亚洲视频1区2区| 国产免费一区二区三区四区| 久久久99精品久久| 在线免费观看麻豆| 国产拍揄自揄精品视频麻豆| 亚洲成年人在线观看| 午夜欧美激情| 另类尿喷潮videofree| 亚洲欧美高清| 亚洲美女淫视频| 中文欧美在线视频| 国产精品加勒比| 91人人澡人人爽人人精品| 日韩成人毛片视频| 少妇精品视频一区二区| 欧美大胆成人| 先锋资源久久| 久久欧美一区二区| 欧美不卡一区二区三区四区| 欧美黑人视频一区| 亚洲一区二区三区欧美| 国产三级三级看三级| 久久人人爽人人爽爽久久| 热久久这里只有精品| 国产视频福利一区| 亚洲精品自在在线观看| 三年中文在线观看免费大全中国| 亚洲欧美国产高清va在线播放| 欧美日韩亚洲一区三区| 亚洲自拍偷拍第一页| 日本亚洲视频| 黑人巨大精品欧美一区二区小视频| 91精品丝袜国产高跟在线| 国产精品久久久对白| 懂色av一区二区| 欧美日韩亚洲免费| 亚洲精品久久| 国产69精品久久久久久久| 国产日韩欧美三级| 国产免费又粗又猛又爽| 激情亚洲综合在线| 男人的天堂影院| 国产亚洲精品免费| 唐朝av高清盛宴| 91久久精品一区二区三| 中文亚洲av片在线观看| 91麻豆精品国产无毒不卡在线观看| 国内精品偷拍视频| 精品小视频在线| 永久免费av片在线观看全网站| 精品国产一区久久久| 男女在线观看视频| 国产精品久久久久9999| 无码人妻精品中文字幕| 奇米亚洲午夜久久精品| 中文字幕日韩久久| av午夜精品一区二区三区| 欧美做受xxxxxⅹ性视频| 中文字幕一区视频| 国产又黄又爽又色| 在线综合+亚洲+欧美中文字幕| 天堂网av2014| 久久五月情影视| 久久野战av| 国产久一道中文一区| 欧美一级精品片在线看| xxxxxx在线观看| 日韩成人综合网| 国产精品精品软件视频| 成人免费电影网址| 国产中文字幕视频在线观看| 日韩黄色免费电影| 中文在线观看免费视频| 亚洲国产精品99久久久久久久久| 美女福利视频在线观看| 色欧美88888久久久久久影院| 又骚又黄的视频| 亚洲色图在线观看| 欧美a级在线观看| 1卡2卡3卡精品视频| 国产一区二区欧美| 播放灌醉水嫩大学生国内精品| 国产在线视视频有精品| 日本少妇xxxxx| 欧美性猛交xxxx免费看久久久| 精品区在线观看| 久久精品欧美视频| 玖玖精品在线| 亚洲精品在线视频观看| 欧美亚洲视频| 性色av蜜臀av色欲av| 一区二区三区高清在线| 91 中文字幕| 色噜噜狠狠狠综合曰曰曰| 三上悠亚一区二区| 欧美日韩在线精品| 三级一区在线视频先锋| 日韩免费高清一区二区| 亚洲高清久久久| 日本波多野结衣在线| 色综合久久天天综线观看| 综合久久av| 91社在线播放| 国产精品一级片| 欧美成人黄色网| 欧美成人乱码一区二区三区| 日韩伦理在线电影| 国产主播欧美精品| 欧美国产专区| 精品激情国产视频| 亚洲女同志亚洲女同女播放| 亚洲最新av在线网站| 欧美精品总汇| 天天综合狠狠精品| 久久99热99| 亚洲国产精品免费在线观看| 欧美色视频在线| 九七久久人人| 国产精品免费一区二区三区在线观看 | 午夜精品久久久久久久久久| 国产成人精品白浆久久69| 久热精品视频在线观看一区| 青青久久精品| 青青在线免费观看| 久久久国产精品不卡| 老熟妇一区二区三区| 一本色道久久88综合日韩精品 | 国产午夜在线观看| xvideos亚洲人网站| 成人在线高清| 香蕉视频免费版| 成人av电影在线观看| 九九热在线视频播放| 精品爽片免费看久久| 91福利在线尤物| 日本一区二区三区在线视频| 免费看的黄色欧美网站| 日韩中文字幕有码| 91麻豆精品国产91久久久久久久久| 伊人222成人综合网| 国产尤物99| 美女mm1313爽爽久久久蜜臀| 萌白酱视频在线| 亚洲国产成人久久| 国产成人久久精品麻豆二区| 曰韩不卡视频| av在线播放一区二区三区| 337p粉嫩色噜噜噜大肥臀| 久久成人一区二区| 中日韩免视频上线全都免费| 手机看片福利盒子久久| 一区二区三区中文字幕电影| 好吊视频一区二区三区| 国产精品高清在线观看| 午夜日韩激情| 亚洲精品视频网址| 亚洲国产天堂网精品网站| 伦一区二区三区中文字幕v亚洲|