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

深入Vue2.0底層思想–模板渲染

開發 前端
Vue 2.0 中模板渲染與 Vue 1.0 完全不同,1.0 中采用的 DocumentFragment (想了解可以觀看這篇文章),而 2.0 中借鑒 React 的 Virtual DOM。基于 Virtual DOM,2.0 還可以支持服務端渲染(SSR),也支持 JSX 語法。

初衷

在使用vue2.0的過程,有時看API很難理解vue作者的思想,這促使我想要去深入了解vue底層的思想,了解完底層的一些思想,才能更好的用活框架,雖然網上已經有很多源碼解析的文檔,但我覺得只有自己動手了,才能更加深印象。

vue2.0和1.0模板渲染的區別

Vue 2.0 中模板渲染與 Vue 1.0 完全不同,1.0 中采用的 DocumentFragment (想了解可以觀看這篇文章),而 2.0 中借鑒 React 的 Virtual DOM。基于 Virtual DOM,2.0 還可以支持服務端渲染(SSR),也支持 JSX 語法。

知識普及

在開始閱讀源碼之前,先了解一些相關的知識:AST 數據結構,VNode 數據結構,createElement 的問題,render函數。

AST 數據結構

AST 的全稱是 Abstract Syntax Tree(抽象語法樹),是源代碼的抽象語法結構的樹狀表現形式,計算機學科中編譯原理的概念。而vue就是將模板代碼映射為AST數據結構,進行語法解析。

我們看一下 Vue 2.0 源碼中 AST 數據結構 的定義:

  1. declare type ASTNode = ASTElement | ASTText | ASTExpression 
  2.  
  3. declare type ASTElement = { // 有關元素的一些定義 
  4.  
  5.   type: 1; 
  6.  
  7.   tag: string; 
  8.  
  9.   attrsList: Array{ name: string; value: string }>; 
  10.  
  11.   attrsMap: { [key: string]: string | null }; 
  12.  
  13.   parent: ASTElement | void; 
  14.  
  15.   children: ArrayASTNode>; 
  16.  
  17.   //...... 
  18.  
  19.  
  20. declare type ASTExpression = { 
  21.  
  22.   type: 2; 
  23.  
  24.   expression: string; 
  25.  
  26.   text: string; 
  27.  
  28.   static?: boolean; 
  29.  
  30.  
  31. declare type ASTText = { 
  32.  
  33.   type: 3; 
  34.  
  35.   text: string; 
  36.  
  37.   static?: boolean; 
  38.  
  39.  

我們看到 ASTNode 有三種形式:ASTElement,ASTText,ASTExpression。用屬性 type 區分。

VNode數據結構

下面是 Vue 2.0 源碼中 VNode 數據結構 的定義 (帶注釋的跟下面介紹的內容有關):

  1. constructor { 
  2.  
  3.   this.tag = tag   //元素標簽 
  4.  
  5.   this.data = data  //屬性 
  6.  
  7.   this.children = children  //子元素列表 
  8.  
  9.   this.text = text 
  10.  
  11.   this.elm = elm  //對應的真實 DOM 元素 
  12.  
  13.   this.ns = undefined 
  14.  
  15.   this.context = context 
  16.  
  17.   this.functionalContext = undefined 
  18.  
  19.   this.key = data && data.key 
  20.  
  21.   this.componentOptions = componentOptions 
  22.  
  23.   this.componentInstance = undefined 
  24.  
  25.   this.parent = undefined 
  26.  
  27.   this.raw = false 
  28.  
  29.   this.isStatic = false //是否被標記為靜態節點 
  30.  
  31.   this.isRootInsert = true 
  32.  
  33.   this.isComment = false 
  34.  
  35.   this.isCloned = false 
  36.  
  37.   this.isOnce = false 
  38.  
  39.  

真實DOM存在什么問題,為什么要用虛擬DOM

我們為什么不直接使用原生 DOM 元素,而是使用真實 DOM 元素的簡化版 VNode,最大的原因就是 document.createElement 這個方法創建的真實 DOM 元素會帶來性能上的損失。我們來看一個 document.createElement 方法的例子

  1. let div = document.createElement('div'); 
  2.  
  3. for(let k in div) { 
  4.  
  5.   console.log(k); 
  6.  
  7.  

打開 console 運行一下上面的代碼,會發現打印出來的屬性多達 228 個,而這些屬性有 90% 多對我們來說都是無用的。VNode 就是簡化版的真實 DOM 元素,關聯著真實的dom,比如屬性elm,只包括我們需要的屬性,并新增了一些在 diff 過程中需要使用的屬性,例如 isStatic。

render函數

這個函數是通過編譯模板文件得到的,其運行結果是 VNode。render 函數 與 JSX 類似,Vue 2.0 中除了 Template 也支持 JSX 的寫法。大家可以使用 Vue.compile(template)方法編譯下面這段模板。

  1. div id="app"
  2.  
  3.   header> 
  4.  
  5.     h1>I am a template!/h1> 
  6.  
  7.   /header> 
  8.  
  9.   p v-if="message"
  10.  
  11.     {{ message }} 
  12.  
  13.   /p> 
  14.  
  15.   p v-else
  16.  
  17.     No message. 
  18.  
  19.   /p> 
  20.  
  21. /div>  

方法會返回一個對象,對象中有 render 和 staticRenderFns 兩個值。看一下生成的 render函數

  1. (function() { 
  2.  
  3.   with(this){ 
  4.  
  5.     return _c('div',{   //創建一個 div 元素 
  6.  
  7.       attrs:{"id":"app"}  //div 添加屬性 id 
  8.  
  9.       },[ 
  10.  
  11.         _m(0),  //靜態節點 header,此處對應 staticRenderFns 數組索引為 0 的 render 函數 
  12.  
  13.         _v(" "), //空的文本節點 
  14.  
  15.         (message) //三元表達式,判斷 message 是否存在 
  16.  
  17.          //如果存在,創建 p 元素,元素里面有文本,值為 toString(message) 
  18.  
  19.         ?_c('p',[_v("\n    "+_s(message)+"\n  ")]) 
  20.  
  21.         //如果不存在,創建 p 元素,元素里面有文本,值為 No message. 
  22.  
  23.         :_c('p',[_v("\n    No message.\n  ")]) 
  24.  
  25.       ] 
  26.  
  27.     ) 
  28.  
  29.   } 
  30.  
  31. })  

要看懂上面的 render函數,只需要了解 _c,_m,_v,_s 這幾個函數的定義,其中 _c 是 createElement(創建元素),_m 是 renderStatic(渲染靜態節點),_v 是 createTextVNode(創建文本dom),_s 是 toString (轉換為字符串)

除了 render 函數,還有一個 staticRenderFns 數組,這個數組中的函數與 VDOM 中的 diff 算法優化相關,我們會在編譯階段給后面不會發生變化的 VNode 節點打上 static 為 true 的標簽,那些被標記為靜態節點的 VNode 就會單獨生成 staticRenderFns 函數

  1. (function() { //上面 render 函數 中的 _m(0) 會調用這個方法 
  2.  
  3.   with(this){ 
  4.  
  5.     return _c('header',[_c('h1',[_v("I'm a template!")])]) 
  6.  
  7.   } 
  8.  
  9. })  

模板渲染過程(重要的函數介紹)

了解完一些基礎知識后,接下來我們講解下模板的渲染過程

 

$mount 函數,主要是獲取 template,然后進入 compileToFunctions 函數。

compileToFunctions 函數,主要將 template 編譯成 render 函數。首先讀緩存,沒有緩存就調用 compile 方法拿到 render 函數 的字符串形式,再通過 new Function 的方式生成 render 函數。

  1. // 有緩存的話就直接在緩存里面拿 
  2.  
  3. const key = options && options.delimiters 
  4.  
  5.             ? String(options.delimiters) + template 
  6.  
  7.             : template 
  8.  
  9. if (cache[key]) { 
  10.  
  11.     return cache[key
  12.  
  13.  
  14. const res = {} 
  15.  
  16. const compiled = compile(template, options) // compile 后面會詳細講 
  17.  
  18. res.render = makeFunction(compiled.render) //通過 new Function 的方式生成 render 函數并緩存 
  19.  
  20. const l = compiled.staticRenderFns.length 
  21.  
  22. res.staticRenderFns = new Array(l) 
  23.  
  24. for (let i = 0; i  l; i++) { 
  25.  
  26.     res.staticRenderFns[i] = makeFunction(compiled.staticRenderFns[i]) 
  27.  
  28.  
  29. ...... 
  30.  
  31.  
  32. return (cache[key] = res) // 記錄至緩存中  

compile 函數就是將 template 編譯成 render 函數的字符串形式,后面一小節我們會詳細講到。

完成render方法的生成后,會進入 _mount 中進行DOM更新。該方法的核心邏輯如下:

  1. // 觸發 beforeMount 生命周期鉤子 
  2.  
  3. callHook(vm, 'beforeMount'
  4.  
  5. // 重點:新建一個 Watcher 并賦值給 vm._watcher 
  6.  
  7. vm._watcher = new Watcher(vm, function updateComponent () { 
  8.  
  9.   vm._update(vm._render(), hydrating) 
  10.  
  11. }, noop) 
  12.  
  13. hydrating = false 
  14.  
  15. // manually mounted instance, call mounted on self 
  16.  
  17. // mounted is called for render-created child components in its inserted hook 
  18.  
  19. if (vm.$vnode == null) { 
  20.  
  21.   vm._isMounted = true 
  22.  
  23.   callHook(vm, 'mounted'
  24.  
  25.  
  26. return vm  

首先會new一個watcher對象(主要是將模板與數據建立聯系),在watcher對象創建后,會運行傳入的方法 vm._update(vm._render(), hydrating) 。其中的vm._render()主要作用就是運行前面compiler生成的render方法,并返回一個vNode對象。vm.update() 則會對比新的 vdom 和當前 vdom,并把差異的部分渲染到真正的 DOM 樹上。

推薦個圖,響應式工程流程

 

(想深入了解watcher的背后實現原理的,可以觀看這篇文章 Vue2.0 源碼閱讀:響應式原理)

compile

上文中提到 compile 函數就是將 template 編譯成 render 函數 的字符串形式。

  1. export function compile ( 
  2.  
  3.   template: string, 
  4.  
  5.   options: CompilerOptions 
  6.  
  7. ): CompiledResult { 
  8.  
  9.   const AST = parse(template.trim(), options) //1. parse 
  10.  
  11.   optimize(AST, options)  //2.optimize 
  12.  
  13.   const code = generate(AST, options) //3.generate 
  14.  
  15.   return { 
  16.  
  17.     AST, 
  18.  
  19.     render: code.render, 
  20.  
  21.     staticRenderFns: code.staticRenderFns 
  22.  
  23.   } 
  24.  
  25.  

這個函數主要有三個步驟組成:parse,optimize 和 generate,分別輸出一個包含 AST,staticRenderFns 的對象和 render函數 的字符串。

parse 函數,主要功能是將 template字符串解析成 AST。前面定義了ASTElement的數據結構,parse 函數就是將template里的結構(指令,屬性,標簽等)轉換為AST形式存進ASTElement中,最后解析生成AST。

optimize 函數(src/compiler/optimizer.js)主要功能就是標記靜態節點,為后面 patch 過程中對比新舊 VNode 樹形結構做優化。被標記為 static 的節點在后面的 diff 算法中會被直接忽略,不做詳細的比較。

generate 函數(src/compiler/codegen/index.js)主要功能就是根據 AST 結構拼接生成 render 函數的字符串。

  1. const code = AST ? genElement(AST) : '_c("div")' 
  2.  
  3. staticRenderFns = prevStaticRenderFns 
  4.  
  5. onceCount = prevOnceCount 
  6.  
  7. return { 
  8.  
  9.     render: `with(this){return ${code}}`, //最外層包一個 with(this) 之后返回 
  10.  
  11.     staticRenderFns: currentStaticRenderFns 
  12.  
  13.  

其中 genElement 函數(src/compiler/codegen/index.js)是會根據 AST 的屬性調用不同的方法生成字符串返回。

  1. function genElement (el: ASTElement): string { 
  2.  
  3.   if (el.staticRoot && !el.staticProcessed) { 
  4.  
  5.     return genStatic(el) 
  6.  
  7.   } else if (el.once && !el.onceProcessed) { 
  8.  
  9.     return genOnce(el) 
  10.  
  11.   } else if (el.for && !el.forProcessed) { 
  12.  
  13.     return genFor(el) 
  14.  
  15.   } else if (el.if && !el.ifProcessed) { 
  16.  
  17.     return genIf(el) 
  18.  
  19.   } else if (el.tag === 'template' && !el.slotTarget) { 
  20.  
  21.     return genChildren(el) || 'void 0' 
  22.  
  23.   } else if (el.tag === 'slot') { 
  24.  
  25.   } 
  26.  
  27.     return code 
  28.  
  29.   } 
  30.  
  31.  

以上就是 compile 函數中三個核心步驟的介紹,compile 之后我們得到了 render 函數 的字符串形式,后面通過 new Function 得到真正的渲染函數。數據發現變化后,會執行 Watcher 中的 _update 函數(src/core/instance/lifecycle.js),_update 函數會執行這個渲染函數,輸出一個新的 VNode 樹形結構的數據。然后在調用 patch 函數,拿這個新的 VNode 與舊的 VNode 進行對比,只有發生了變化的節點才會被更新到真實 DOM 樹上。

patch

patch.js 就是新舊 VNode 對比的 diff 函數,主要是為了優化dom,通過算法使操作dom的行為降到最低,diff 算法來源于 snabbdom,是 VDOM 思想的核心。snabbdom 的算法為了 DOM 操作跨層級增刪節點較少的這一目標進行優化,它只會在同層級進行, 不會跨層級比較。

想更加深入VNode diff算法原理的,可以觀看(解析vue2.0的diff算法)

總結

  • compile 函數主要是將 template 轉換為 AST,優化 AST,再將 AST 轉換為 render函數;
  • render函數 與數據通過 Watcher 產生關聯;
  • 在數據發生變化時調用 patch 函數,執行此 render 函數,生成新 VNode,與舊 VNode 進行 diff,最終更新 DOM 樹。 
責任編輯:龐桂玉 來源: 前端大全
相關推薦

2016-11-03 13:19:38

vue.jsjavascript前端

2021-08-27 12:59:59

React前端命令

2019-03-20 11:20:31

VueWeb 前端

2020-09-14 08:56:30

Vue模板

2024-10-17 16:39:18

2010-09-13 13:21:29

CSS排版

2020-08-10 18:03:54

Cache存儲器CPU

2022-11-04 09:43:05

Java線程

2011-02-15 11:46:41

2022-02-18 09:39:51

Vue3.0Vue2.0Script Set

2017-05-03 17:00:16

Android渲染機制

2010-09-13 09:17:27

DIV頁面

2020-03-17 08:36:22

數據庫存儲Mysql

2020-03-26 16:40:07

MySQL索引數據庫

2017-08-31 11:28:47

Slice底層實現

2018-01-11 14:58:40

2015-12-23 14:39:04

云計算2.0應用業務

2022-08-09 11:46:58

Vue遞歸組件

2017-03-12 10:15:18

瀏覽器DOM樹CSSOM樹

2019-06-12 09:50:23

selectMySQLSQL
點贊
收藏

51CTO技術棧公眾號

男女羞羞在线观看| av中文在线观看| 国产精品免费大片| 欧美影院午夜播放| 亚洲五码在线观看视频| 日韩在线视频免费| 秋霞成人午夜伦在线观看| 久久69精品久久久久久国产越南| av网页在线观看| 四虎国产精品成人免费影视| 午夜久久久久久| 一区二区在线观看网站| 婷婷久久久久久| 精品在线一区二区| 青草成人免费视频| 九九九免费视频| 黄色一级片黄色| 丁香六月色婷婷| 久久国产日韩欧美精品| 国语自产偷拍精品视频偷| 国产精品久久久视频| 欧美大片网址| 日韩精品专区在线影院重磅| 男女污污的视频| 国产在线精彩视频| 亚洲最新在线观看| 亚洲第一精品区| 成年人视频网站在线| 99精品视频中文字幕| 7777精品久久久大香线蕉小说| 青青艹在线观看| 亚洲永久视频| 欧美激情国产高清| 粉嫩av性色av蜜臀av网站| 不卡中文一二三区| 国产午夜精品视频免费不卡69堂| 人妖粗暴刺激videos呻吟| 国产色99精品9i| 欧美日韩成人激情| 天天干天天综合| 日韩欧美少妇| 色婷婷综合在线| 国产 福利 在线| 精精国产xxxx视频在线播放| 亚洲一区在线看| 日韩a级黄色片| 最近中文字幕免费mv2018在线| 亚洲欧洲av一区二区三区久久| 亚洲ai欧洲av| www亚洲人| 国产精品网曝门| 亚洲高清视频一区| 调教视频免费在线观看| 国产精品久久午夜夜伦鲁鲁| 亚洲一区二区三区免费观看| 97电影在线观看| 国产精品久久久久婷婷二区次| 亚洲成人午夜在线| 成年人免费在线播放| 日韩免费av片| 99国产精品视频免费观看一公开 | 欧美三级在线视频| 亚洲老女人av| 亚洲欧美综合久久久久久v动漫| 欧美日韩久久一区| 一级黄色片在线免费观看| 国产精品亚洲欧美一级在线| 日韩一区二区中文字幕| 四虎永久免费观看| 色婷婷av一区二区三区丝袜美腿| 亚洲色图综合网| 成人18视频免费69| 欧美日韩影院| 欧美一级视频一区二区| 一级一级黄色片| 国产精品一区在线观看乱码| 国产成人精品免费视频大全最热| 欧美 日韩 国产 成人 在线 91| ww久久中文字幕| 亚洲欧美日韩精品在线| 日本在线观看大片免费视频| 五月天亚洲精品| 91蝌蚪视频在线观看| 亚洲精品三区| 亚洲国产高清福利视频| 精品人妻一区二区三区四区| 91精品在线观看国产| 91精品91久久久久久| 狠狠躁夜夜躁人人爽视频| 国产福利一区二区三区视频在线| 精品网站在线看| 99视频在线观看地址| 亚洲免费av高清| 日韩精品视频一区二区在线观看| 免费在线成人激情电影| 精品久久久久久久久久久院品网 | 欧美亚洲在线视频| 中文字幕色一区二区| 日批视频免费观看| 丁香啪啪综合成人亚洲小说| 日韩欧美在线观看强乱免费| 亚洲卡一卡二| 在线观看日韩电影| xfplay5566色资源网站| 四虎国产精品免费观看| 欧美又大又硬又粗bbbbb| 国产精品一区二区免费视频 | 国产伦精品一区二区三区免| 北条麻妃在线| 偷拍亚洲欧洲综合| 日日夜夜精品视频免费观看| 精品国产99| 性欧美xxxx交| www.四虎在线观看| 国产精品美日韩| 国产v亚洲v天堂无码久久久| 大香伊人久久精品一区二区| 久久亚洲电影天堂| 中文字幕777| 久久蜜臀精品av| 免费拍拍拍网站| 激情综合五月| 日韩在线视频免费观看高清中文| 亚洲天堂av片| 成人免费毛片片v| 午夜久久久久久久久久久| 国产成人免费精品| 亚洲日韩第一页| 日韩精品在线观看免费| 成人一区二区三区在线观看 | 欧美人与性囗牲恔配| 一本久久知道综合久久| 国产精品v欧美精品v日韩| 久草免费在线观看| 欧美日韩中文另类| 国产又黄又粗的视频| 久久精品成人| 欧美日韩系列| 国产免费不卡| 亚洲男人天堂久| 亚洲熟女综合色一区二区三区| 国产精品xx| 亚洲精品免费在线| 伊人色在线视频| 国产精品88久久久久久| 国产视频福利一区| 网友自拍视频在线| 在线播放国产精品二区一二区四区| 少妇视频在线播放| 青青草97国产精品免费观看无弹窗版| 日韩aⅴ视频一区二区三区| 不卡一二三区| 国产亚洲欧洲高清一区| 中文字幕在线观看你懂的| 中文字幕av一区 二区| 日日噜噜夜夜狠狠| 五月天久久网站| 亚洲一区二区中文| 日韩精品卡一| 亚洲国产婷婷香蕉久久久久久| 天天操天天射天天爽| 91伊人久久大香线蕉| 免费欧美一级视频| 欧美三级三级| 91香蕉亚洲精品| 超碰在线资源| 日韩成人在线观看| 午夜一区二区三区四区| 亚洲三级电影网站| 可以看的av网址| 99pao成人国产永久免费视频| 麻豆av一区| 日韩一区二区三免费高清在线观看| 日韩视频永久免费观看| 国产18精品乱码免费看| 欧美日韩激情小视频| 伊人影院综合网| 国产精品影视网| 鲁一鲁一鲁一鲁一色| 波多野结衣在线观看一区二区三区| 91在线视频九色| 9999热视频在线观看| 国产一区二区精品丝袜| 国产乱叫456在线| 五月综合激情网| 老头老太做爰xxx视频| 国产精品一色哟哟哟| 美女福利视频在线| 亚洲v在线看| 久久久久久久免费| 亚洲无人区码一码二码三码| 国产精品最新| 99视频在线免费观看| 写真福利精品福利在线观看| 欧美www在线| 你懂的在线播放| 欧美成人福利视频| 国产精品尤物视频| 午夜一区二区三区在线观看| 国产一二三av| 不卡视频一二三| 17c国产在线| 新狼窝色av性久久久久久| 成人短视频在线看| 女厕嘘嘘一区二区在线播放| 官网99热精品| 日韩福利影视 | 中文字幕 在线观看| 美女撒尿一区二区三区| 国产乱子伦三级在线播放| 亚洲成人在线网| 国产精品自产拍| 色94色欧美sute亚洲13| 久一视频在线观看| 亚洲欧洲一区二区三区| 亚洲第一成人网站| 狠狠色丁香久久婷婷综| 免费看污污网站| 亚洲欧美成人| 水蜜桃色314在线观看| 伊人久久大香线蕉综合四虎小说 | 91久久精品国产91性色tv| 精品少妇久久久| 亚洲日本在线天堂| 你懂得视频在线观看| 久久色成人在线| 影音先锋黄色资源| 高清av一区二区| 色男人天堂av| 国产在线精品一区二区三区不卡| 久久精品免费网站| 久久精品导航| 亚洲熟妇av一区二区三区| 亚洲精品看片| 精品视频免费在线播放| 韩国亚洲精品| 香港三级日本三级a视频| 天天综合精品| 日本特级黄色大片| 91精品一区二区三区综合| 国产欧美精品在线观看| 色综合久久久无码中文字幕波多| 紧缚捆绑精品一区二区| 亚洲精品mv在线观看| 久久精品国产免费| 国产精品久久久久久久av福利| 精品一区二区在线视频| 五月天开心婷婷| 国产呦萝稀缺另类资源| 久久精品亚洲天堂| 国产成人精品免费在线| 亚洲成人精品在线播放| 国产成人精品影视| 小毛片在线观看| 91色视频在线| 国产一二三四区在线| 中文字幕av一区 二区| www.97视频| 一区二区三区在线播放| 精国产品一区二区三区a片| 亚洲国产一二三| 亚洲免费在线观看av| 色婷婷综合久色| 国产一区二区三区四区视频| 91精品免费观看| 十八禁一区二区三区| 亚洲男人天堂网站| 欧美另类极品| 欧美激情在线一区| 亚洲精品88| 成人h片在线播放免费网站| 日韩精品亚洲专区在线观看| 精品在线观看一区二区| 日韩精品中文字幕第1页| 日本老太婆做爰视频| 亚洲精品资源| 少妇一级淫免费放| 国产成人亚洲综合a∨婷婷图片| 日韩av手机在线播放| 国产欧美精品一区二区色综合 | 欧美熟妇精品一区二区| 97久久人人超碰| 特级西西人体高清大胆| 一区二区三区精品视频| 日韩电影在线观看一区二区| 91精品黄色片免费大全| 午夜影院在线视频| 久久精品一区中文字幕| 国产拍在线视频| 91精品视频在线看| 香蕉久久夜色精品国产更新时间| 一区二区三区精品国产| av成人黄色| 日本在线观看视频一区| 久久影院午夜片一区| 成人黄色av片| 国产视频第一区| 中文字幕亚洲激情| www在线观看黄色| 亚洲va国产va天堂va久久| 日本精品影院| 91免费版看片| 奇米亚洲午夜久久精品| 在线观看国产网站| 一卡二卡欧美日韩| 中文区中文字幕免费看| 日韩精品视频在线观看免费| 成人在线观看免费网站| 日韩免费在线播放| 欧美黑白配在线| 干日本少妇视频| 日韩高清在线不卡| 国产美女视频免费观看下载软件| 亚洲图片激情小说| 免费看污视频的网站| 日韩电视剧在线观看免费网站| 肉体视频在线| 91九色国产在线| 日韩综合一区| 宅男噜噜噜66国产免费观看| 337p粉嫩大胆噜噜噜噜噜91av| 久草免费在线观看视频| 欧美人妖巨大在线| 99reav在线| 欧洲一区二区视频| 欧美91在线| 国产精品久久久久久久乖乖| 国产福利91精品一区| 欧美h片在线观看| 欧美年轻男男videosbes| 国产高清av在线| 国产精品777| 国产亚洲第一伦理第一区| 亚洲熟妇av一区二区三区| 91免费视频网址| 亚洲伊人成人网| 日韩电影中文字幕在线观看| 96av在线| 蜜桃传媒视频麻豆第一区免费观看| 亚洲人成高清| 激情综合丁香五月| 欧美日韩精品在线视频| 视频二区在线| 日本欧美一级片| 欧美亚洲激情| 最新天堂在线视频| 亚洲免费三区一区二区| 亚洲春色一区二区三区| 欧美第一黄网免费网站| 大香伊人久久精品一区二区| 黄色www网站| 久久亚区不卡日本| 青青国产在线视频| 日韩在线观看免费全| 久久免费福利| 丰满人妻一区二区三区53号| 懂色一区二区三区免费观看| 动漫精品一区一码二码三码四码| 亚洲国产精品专区久久| 亚洲天堂免费电影| 亚洲欧美日韩国产精品| 久久免费少妇高潮99精品| 精品国内二区三区| 深夜成人在线| 色女孩综合网| 国产乱码精品一区二区三区av| 久久久综合久久久| 亚洲精品在线视频| 成人国产一区二区三区精品麻豆| 一区二区不卡视频| 成人午夜伦理影院| 亚洲精品中文字幕乱码三区91| 伊人一区二区三区久久精品| 国产情侣一区在线| 人人妻人人添人人爽欧美一区| 久久久国产综合精品女国产盗摄| 91久久国语露脸精品国产高跟| 欧美大片免费观看| 蜜桃一区二区| 日韩久久久久久久久久久| 岛国精品视频在线播放| 日本a级在线| 国内精品久久久久久久果冻传媒| 日本不卡的三区四区五区| 久久久精品视频在线| 亚洲香蕉成人av网站在线观看 | 国产cdts系列另类在线观看| 国产精品一区二区不卡视频| 奇米亚洲午夜久久精品| 国产精品第72页| 永久555www成人免费| 亚洲一区网址| 日本三级黄色网址| 午夜不卡在线视频| 国产黄色在线观看| 日本高清一区| www.66久久| 精品久久在线观看| 国产精品久久久久国产a级| 亚洲国产精品一区|