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

聊聊 Nuxt 開箱即用的特性

開發 前端
最近公司項目中使用了 Nuxt 框架,進行首屏的服務端渲染,加快了內容的到達時間 (time-to-content),于是筆者開始了對 Nuxt 的學習和使用。以下是從源碼角度對 Nuxt 的一些特性的介紹和分析。

 [[420713]]

引文

最近公司項目中使用了 Nuxt 框架,進行首屏的服務端渲染,加快了內容的到達時間 (time-to-content),于是筆者開始了對 Nuxt 的學習和使用。以下是從源碼角度對 Nuxt 的一些特性的介紹和分析。

FEATURES

服務端渲染(SSR)

Vue.js 是構建客戶端應用程序的框架。默認情況下,可以在瀏覽器中輸出 Vue 組件,進行生成 DOM 和操作 DOM。然而,也可以將同一個組件渲染為服務器端的 HTML 字符串,將它們直接發送到瀏覽器,最后將這些靜態標記"激活"為客戶端上完全可交互的應用程序。 ------Vue SSR 指南

官方Vue SSR指南的基本用法章節,給出了 demo 級別的服務端渲染實現,Nuxt 也是基于該章節實現的,大體流程幾乎一致。建議先食用官方指南,再看本文定大有裨益。

Nuxt 作為一個服務端渲染框架,了解其服務端渲染的實現原理必然是重中之重,就讓我們通過相關源碼,看看其具體實現吧!

我們通過 nuxt 啟動 Nuxt 項目,其首先會執行 startDev 方法,然后調用_listenDev 方法,獲取 Nuxt 配置,調用getNuxt方法實例化 Nuxt。然后執行 nuxt.ready() 方法,生成渲染器。

  1. // @nuxt/server/src/server.js 
  2. async ready () { 
  3.  // Initialize vue-renderer 
  4.  this.serverContext = new ServerContext(this) 
  5.  this.renderer = new VueRenderer(this.serverContext) 
  6.  await this.renderer.ready() 
  7.  
  8.  // Setup nuxt middleware 
  9.  await this.setupMiddleware() 
  10.  
  11.  return this 

在 ready 中會執行 this.setupMiddleware() ,其中會調用nuxtMiddleware 中間件(這里是響應的關鍵)。

  1. // @nuxt/server/src/middleware/nuxt.js 
  2. export default ({ options, nuxt, renderRoute, resources }) => async function nuxtMiddleware (req, res, next) { 
  3.  const context = getContext(req, res) 
  4.  try { 
  5.    const url = normalizeURL(req.url) 
  6.    res.statusCode = 200 
  7.    const result = await renderRoute(url, context) // 渲染相應路由,后文會展開 
  8.     
  9.    const { 
  10.      html, 
  11.      redirected, 
  12.      preloadFiles 
  13.   } = result // 得到html 
  14.  
  15.    // 設置頭部字段 
  16.    res.setHeader('Content-Type''text/html; charset=utf-8'
  17.    res.setHeader('Accept-Ranges''none'
  18.    res.setHeader('Content-Length', Buffer.byteLength(html)) 
  19.    res.end(html, 'utf8') // 做出響應 
  20.    return html 
  21. } catch (err) { 
  22.    if (context && context.redirected) { 
  23.      consola.error(err) 
  24.      return err 
  25.   } 
  26.    next(err) 

nuxtMiddleware 中間件中首先標準化請求的url,設置請求狀態碼,通過url匹配到相應的路由,渲染出對應的路由組件,設置頭部信息,最后做出響應。

  1. renderSSR (renderContext) { 
  2.  // Call renderToString from the bundleRenderer and generate the HTML (will update the renderContext as well) 
  3.  // renderSSR 只是 universal app的渲染方法,Nuxt 也可以進行開發普通的 SPA 項目 
  4.  const renderer = renderContext.modern ? this.renderer.modern : this.renderer.SSR 
  5.  return renderer.render(renderContext) 

其中 renderRoute 方法會調用 @nuxt/vue-render 的renderSSR 進行服務端渲染操作。

  1. // @nuxt/vue-renderer/src/renderers/SSR.js 
  2. async render (renderContext) { 
  3.  // Call Vue renderer renderToString 
  4.  let APP = await this.vueRenderer.renderToString(renderContext) 
  5.  
  6.  let HEAD = '' 
  7.  // ... 此處省略n行HEAD拼接代碼,后續 HEAD 管理部分會提及 
  8.     
  9.  // Render with SSR template 
  10.  const html = this.renderTemplate(this.serverContext.resources.SSRTemplate, templateParams) 
  11.  
  12.  return { 
  13.    html, 
  14.    preloadFiles 

而 renderSSR 又會調用 renderer.render 方法,將 url 匹配的路由渲染成字符串,將字符串與模版相結合,得到最終返回給瀏覽器的html,至此 Nuxt 服務端渲染完成。

最后貼一張盜來的 Nuxt 執行流程圖,圖畫的很棒,流程也很清晰,感謝。

數據拉取(Data Fetching)

在客戶端程序(CSR)可以通過在 mounted 鉤子中獲取數據,但在通用程序(Universal)中則需要使用特定的鉤子才能在服務端獲取數據。

Nuxt 中主要提供了兩種鉤子獲取數據

  • asyncData
    • 只可以在頁面級組件中獲取,不可以訪問 this
    • 通過返回對象保存數據狀態或與Vuex配合進行狀態保存
  • fetch
    • 所有組件中都可以獲取,可以訪問 this
    • 無需傳入 context,傳入 context 會 fallback 到老版的 fetch,功能類似于 asyncData
  1. // .nuxt/server.js 
  2. // Components are already resolved by setContext -> getRouteData (app/utils.js) 
  3. const Components = getMatchedComponents(app.context.route) 
  4.   
  5. // 在匹配的路由中,調用 asyncData 和 legacy 版本的 fetch方法 
  6. const asyncDatas = await Promise.all(Components.map((Component) => { 
  7.  const promises = [] 
  8.  
  9.  // 調用 asyncData(context) 
  10.  if (Component.options.asyncData && typeof Component.options.asyncData === 'function') { 
  11.    const promise = promisify(Component.options.asyncData, app.context) 
  12.    promise.then((asyncDataResult) => { 
  13.      SSRContext.asyncData[Component.cid] = asyncDataResult 
  14.      applyAsyncData(Component) 
  15.      return asyncDataResult 
  16.   }) 
  17.    promises.push(promise) 
  18.   } else { 
  19.      promises.push(null
  20.   } 
  21.  
  22.    // 調用 legacy 版本的fetch(context) 兼容老版本的 fetch 
  23.    if (Component.options.fetch && Component.options.fetch.length) { 
  24.      promises.push(Component.options.fetch(app.context)) 
  25.   } else { 
  26.    promises.push(null
  27.  
  28.  return Promise.all(promises) 
  29. })) 

在生成的 .nuxt/server.js 中,會遍歷匹配的組件,查看組件中是否定義了 asyncData 選項以及 legacy 版 fetch ,存在就依次調用,獲得 asyncDatas。

  1. // .nuxt/mixins/fetch.server.js  
  2. // nuxt v2.14及之后 
  3. async function serverPrefetch() { 
  4.  // Call and await on $fetch 
  5.  // v2.14 之后推薦的 fetch 
  6.  try { 
  7.    await this.$options.fetch.call(this) 
  8. } catch (err) { 
  9.    if (process.dev) { 
  10.      console.error('Error in fetch():', err) 
  11.   }  
  12.  this.$fetchState.pending = false // 設置fetchState 為 false 

在服務端實例化 vue 實例之后,執行 serverPrefetch,觸發 fetch 選項方法,獲取數據,數據會作用于生成 html的過程。

HEAD 管理(Meta Tags and SEO)

截至目前,Google 和 Bing 可以很好對同步 JavaScript 應用程序進行索引。但是對于異步獲取數據的網站來說,主流的搜索引擎暫時還無法支持,于是造成網站搜索排名靠后,于是希望獲得更好的SEO成為眾多網站考慮使用SSR框架的原因。

為了獲得良好的SEO,那么就需要對HEAD進行精細化的配置和管理。讓我們看看其是如何實現的吧~

Nuxt框架借助 vue-meta 庫實現全局、單個頁面的 meta 標簽的自定義。Nuxt 內部的實現也幾乎遵循 vue-meta 官方的 SSR meta 管理的流程。具體詳情請查看。

  1. // @nuxt/vue-app/template/index.js 
  2. // step1 
  3. Vue.use(Meta, JSON.stringify(vueMetaOptions)) 
  4.  
  5. // @nuxt/vue-app/template/template.js 
  6. // step2 
  7. export default async (SSRContext) => { 
  8.  const _app = new Vue(app) 
  9.  // Add meta infos (used in renderer.js) 
  10.  SSRContext.meta = _app.$meta() 
  11.  return _app 

首先通過Vue插件的形式,注冊vue-meta,內部會在Vue的原型上掛載$meta屬性。然后將meta添加到服務端渲染上下文中。

  1. async render (renderContext) { 
  2.    // Call Vue renderer renderToString 
  3.    let APP = await this.vueRenderer.renderToString(renderContext) 
  4.    // step3 
  5.    let HEAD = '' 
  6.  
  7.    // Inject head meta 
  8.    // (this is unset when features.meta is false in server template) 
  9.    // 以下就是上文省略的 n 行 HEAD 拼接代碼,可以適當忽略 
  10.    // 了解主要過程即可,具體細節按需查看 
  11.    const meta = renderContext.meta && renderContext.meta.inject({ 
  12.      isSSR: renderContext.nuxt.serverRendered, 
  13.      ln: this.options.dev 
  14.   }) 
  15.  
  16.    if (meta) { 
  17.      HEAD += meta.title.text() + meta.meta.text() 
  18.   } 
  19.  
  20.    if (meta) { 
  21.      HEAD += meta.link.text() + 
  22.        meta.style.text() + 
  23.        meta.script.text() + 
  24.        meta.noscript.text() 
  25.   } 
  26.  
  27.    // Check if we need to inject scripts and state 
  28.    const shouldInjectScripts = this.options.render.injectScripts !== false 
  29.  
  30.    // Inject resource hints 
  31.    if (this.options.render.resourceHints && shouldInjectScripts) { 
  32.      HEAD += this.renderResourceHints(renderContext) 
  33.   } 
  34.  
  35.    // Inject styles 
  36.    HEAD += this.renderStyles(renderContext) 
  37.  
  38.  
  39.    // Prepend scripts 
  40.    if (shouldInjectScripts) { 
  41.      APP += this.renderScripts(renderContext) 
  42.   } 
  43.  
  44.    if (meta) { 
  45.      const appendInjectorOptions = { body: true } 
  46.      // Append body scripts 
  47.      APP += meta.meta.text(appendInjectorOptions) 
  48.      APP += meta.link.text(appendInjectorOptions) 
  49.      APP += meta.style.text(appendInjectorOptions) 
  50.      APP += meta.script.text(appendInjectorOptions) 
  51.      APP += meta.noscript.text(appendInjectorOptions) 
  52.   } 
  53.  
  54.    // Template params 
  55.    const templateParams = { 
  56.      HTML_ATTRS: meta ? meta.htmlAttrs.text(renderContext.nuxt.serverRendered /* addSrrAttribute */) : ''
  57.      HEAD_ATTRS: meta ? meta.headAttrs.text() : ''
  58.      BODY_ATTRS: meta ? meta.bodyAttrs.text() : ''
  59.      HEAD, 
  60.      APP, 
  61.      ENV: this.options.env 
  62.   } 
  63.  
  64.    // Render with SSR template 
  65.    // 通過模版和參數 生成html 
  66.    const html = this.renderTemplate(this.serverContext.resources.SSRTemplate, templateParams) 
  67.  
  68.    let preloadFiles 
  69.    if (this.options.render.http2.push) { 
  70.      // 獲取需要預加載的文件 
  71.      preloadFiles = this.getPreloadFiles(renderContext) 
  72.   } 
  73.  
  74.    return { 
  75.      html, 
  76.      preloadFiles, 
  77.   } 

最后在響應的 html 中注入 metadata 即可。

文件系統路由(File System Routing)

想必使用過 Nuxt 的同學應該都對其基于文件生成路由的特性,印象深刻。讓我從源碼角度看看 Nuxt 是如何實現基于 pages 目錄(可配置),自動生成路由的。

首先在啟動 Nuxt 項目或者修改文件時,會自動調 generateRoutesAndFiles 方法,生成路由 以及 .nuxt 目錄下的文件。

  1. // @nuxt/builder/src/builder.js 
  2. async generateRoutesAndFiles() { 
  3.   ... 
  4.   await Promise.all([ 
  5.     this.resolveLayouts(templateContext), 
  6.     this.resolveRoutes(templateContext), //解析生成路由,需要關注的重點 
  7.     this.resolveStore(templateContext), 
  8.     this.resolveMiddleware(templateContext) 
  9.   ]) 
  10.   ... 

解析路由會存在三種情況:一是修改了默認的 pages 目錄名稱,且未在 nuxt.config.js 中配置相關目錄,二是使用 nuxt 默認的 pages 目錄,三是使用調用用戶自定義的路由生成方法生成路由。

  1. // @nuxt/builder/src/builder.js 
  2. async resolveRoutes({ templateVars }) { 
  3.   consola.debug('Generating routes...'
  4.   if (this._defaultPage) { 
  5.     // 在srcDir下未找到pages目錄 
  6.   } else if (this._nuxtPage) { 
  7.     // 使用nuxt動態生成路由 
  8.   } else { 
  9.     // 用戶提供了自定義方法去生成路由,提供用戶自定義路由的能力 
  10.   } 
  11.   // router.extendRoutes method 
  12.   if (typeof this.options.router.extendRoutes === 'function') { 
  13.     const extendedRoutes = await this.options.router.extendRoutes( 
  14.       templateVars.router.routes, 
  15.       resolve 
  16.     ) 
  17.     if (extendedRoutes !== undefined) { 
  18.       templateVars.router.routes = extendedRoutes 
  19.     } 
  20.   } 

除此之外,還可以提供相應的 extendRoutes 方法,在 nuxt 生成路由的基礎上添加自定義路由。

  1. export default { 
  2.   router: { 
  3.     extendRoutes(routes, resolve) { 
  4.       // 例如添加 404 頁面 
  5.       routes.push({ 
  6.         name'custom'
  7.         path: '*'
  8.         component: resolve(__dirname, 'pages/404.vue'
  9.       }) 
  10.     } 
  11.   } 

其中當修改了默認的 pages 目錄,導致找不到相關的目錄,會使用 @nuxt/vue-app/template/pages/index.vue 文件生成路由。

  1. async resolveRoutes({ templateVars }) { 
  2.   if (this._defaultPage) { 
  3.     // createRoutes 方法根據傳參,生成路由。具體算法,不再展開 
  4.     templateVars.router.routes = createRoutes({ 
  5.       files: ['index.vue'], 
  6.       srcDir: this.template.dir + '/pages', // 指向@nuxt/vue-app/template/pages/index.vue 
  7.       routeNameSplitter, // 路由名稱分隔符,默認`-` 
  8.       trailingSlash // 尾斜杠 / 
  9.     }) 
  10.   } else if (this._nuxtPage) { 
  11.     const files = {} 
  12.     const ext = new RegExp(`\\.(${this.supportedExtensions.join('|')})$`) 
  13.     for (const page of await this.resolveFiles(this.options.dir.pages)) { 
  14.       const key = page.replace(ext, ''
  15.       // .vue file takes precedence over other extensions 
  16.       if (/\.vue$/.test(page) || !files[key]) { 
  17.         files[key] = page.replace(/(['"])/g, '\\$1') 
  18.       } 
  19.     } 
  20.     templateVars.router.routes = createRoutes({ 
  21.       files: Object.values(files), 
  22.       srcDir: this.options.srcDir, 
  23.       pagesDir: this.options.dir.pages, 
  24.       routeNameSplitter, 
  25.       supportedExtensions: this.supportedExtensions, 
  26.       trailingSlash 
  27.     }) 
  28.     } else { 
  29.       templateVars.router.routes = await this.options.build.createRoutes(this.options.srcDir) 
  30.     } 
  31.     // router.extendRoutes method 
  32.     if (typeof this.options.router.extendRoutes === 'function') { 
  33.       const extendedRoutes = await this.options.router.extendRoutes( 
  34.         templateVars.router.routes, 
  35.         resolve 
  36.       ) 
  37.       if (extendedRoutes !== undefined) { 
  38.         templateVars.router.routes = extendedRoutes 
  39.       } 
  40.   } 

然后就是調用 createRoutes 方法,生成路由。生成的路由大致長這樣,和手動書寫的路由文件幾乎一致(后續還會進行打包??,懶加載引入路由組件)。

  1.   { 
  2.     name'index'
  3.     path: '/'
  4.     chunkName: 'pages/index'
  5.     component: 'Users/username/projectName/pages/index.vue' 
  6.   }, 
  7.   { 
  8.     name'about'
  9.     path: '/about'
  10.     chunkName: 'pages/about/index'
  11.     component: 'Users/username/projectName/pages/about/index.vue' 
  12.   } 

智能預取(Smart Prefetching)

從 Nuxt v2.4.0 開始,當 出現在可視區域后,Nuxt將會預取經過code-splitted的 page 頁面的腳本,使得在用戶點擊之前,該路由指向的地址,就處于 ready 狀態,這將極大的提升用戶的體驗。

相關實現邏輯集中于 .nuxt/components/nuxt-link.client.js 中。

首先 Smart Prefetching 特性的實現依賴于window.IntersectionObserver 這個實驗性的 API,如果瀏覽器不支持該 API,就不會進行組件預取操作。

  1. mounted () { 
  2.   if (this.prefetch && !this.noPrefetch) { 
  3.     this.handleId = requestIdleCallback(this.observe, { timeout: 2e3 }) 
  4.   } 

然后在需要預取的 組件掛載階段,會調用 requestIdleCallback 方法在瀏覽器的空閑時段內調用 observe 方法。

  1. const observer = window.IntersectionObserver && new window.IntersectionObserver((entries) => { 
  2.   entries.forEach(({ intersectionRatio, target: link }) => { 
  3.     // 如果intersectionRatio 小于等于0,表示目標不在viewport內 
  4.     if (intersectionRatio <= 0 || !link.__prefetch) { 
  5.       return 
  6.     } 
  7.     // 進行預取數據(其實就是加載組件) 
  8.     link.__prefetch() 
  9.   }) 
  10. }) 

當被監聽的元素的可視情況發生改變的時候(且出現在視圖內時),會觸發 new window.IntersectionObserver(callback) 的回調,執行真正的預取操作prefetchLink。

  1. prefetchLink () { 
  2.   // 判斷網絡環境,離線或者2G環境下,不進行預取操作 
  3.   if (!this.canPrefetch()) { 
  4.     return 
  5.   } 
  6.   // 停止監聽該元素,提高性能 
  7.   observer.unobserve(this.$el) 
  8.   const Components = this.getPrefetchComponents() 
  9.  
  10.   for (const Component of Components) { 
  11.     // 及時加載組件,使得用戶點擊時,該組件是一個就緒的狀態 
  12.     const componentOrPromise = Component() 
  13.     if (componentOrPromise instanceof Promise) { 
  14.       componentOrPromise.catch(() => {}) 
  15.     Component.__prefetched = true // 已經預取的標志位 
  16.   } 

總結

上文從源碼角度介紹了 Nuxt 服務端渲染的實現、服務端數據的獲取以及 Nuxt 開箱即用的幾個特性:HEAD 管理、基于文件系統的路由和智能預取 code-splitted 的路由。如果希望對 SSR 進行更深入研究,還可以橫向學習 React 的 SSR 實現 Next 框架。

希望對您有所幫助,如有紕漏,望請輔正。

參考

為什么使用服務器端渲染 (SSR)?

Nuxt源碼精讀

Vue Meta

Introducing Smart prefetching

服務端渲染

 

責任編輯:武曉燕 來源: 大轉轉FE
相關推薦

2024-11-25 06:20:00

Netty封裝框架

2023-01-15 20:28:32

前端圖片壓縮

2023-03-08 21:25:58

開源工具庫開箱

2022-08-08 08:29:55

圖片壓縮前端互聯網

2023-11-04 12:43:44

前端圖片參數

2021-09-26 05:41:47

基礎設施連接無線技術網絡

2025-07-10 00:00:05

開箱ApacheHertzbeat

2021-09-01 17:43:32

StreamNativ開源

2021-09-28 09:30:18

uni-appVue 3.0uniCloud

2023-01-29 07:49:57

2022-08-02 09:01:55

后臺管理模版

2025-04-14 11:00:00

2013-11-01 09:37:19

Android系統架構工具

2022-01-03 18:15:35

FlaskTepHttpRunner

2025-05-15 08:35:00

2015-06-30 09:49:19

管理平臺開源KVM

2019-11-25 00:00:00

開源技術 數據

2023-04-04 10:09:09

2021-04-22 10:28:52

開發技能代碼
點贊
收藏

51CTO技術棧公眾號

xfplay5566色资源网站| 尤物一区二区三区| √资源天堂中文在线| 久久不见久久见免费视频7| 欧美性生交片4| 午夜日韩福利| 欧美一区二区三区婷婷月色| 精品成在人线av无码免费看| 精品一二三区视频| 国产在线精品一区二区不卡了| 色综合导航网站| 一级性生活毛片| 精品国产三级| 在线亚洲一区观看| 欧美在线观看黄| 国产69精品久久app免费版| 国产精品资源在线看| 青草成人免费视频| 亚洲成人生活片| 啄木系列成人av电影| 91精品国产手机| 无码人妻精品一区二区三区在线| 麻豆影视在线观看_| 久久综合久久综合久久| 亚洲www在线观看| 91在线视频免费播放| 欧美黄色免费| 最新国产精品拍自在线播放| 精品影片一区二区入口| 24小时成人在线视频| 日本久久一区二区三区| av日韩在线看| 精品欧美色视频网站在线观看| 91亚洲午夜精品久久久久久| 99久久精品免费看国产一区二区三区| 日本免费在线观看视频| 欧美午夜不卡| 欧美成人午夜影院| 精品人体无码一区二区三区| 亚洲+变态+欧美+另类+精品| 精品福利视频一区二区三区| 污视频在线观看免费网站| 99热播精品免费| 一本久久a久久精品亚洲| 久久这里只有精品18| 菠萝菠萝蜜在线视频免费观看| 亚洲国产精品高清| 欧美一区二区在线| 久久av一区二区三区漫画| av鲁丝一区鲁丝二区鲁丝三区| 四虎国产精品免费久久| 欧美色图在线观看| 丁香婷婷激情网| 性感美女一区二区在线观看| 精品人伦一区二区三区蜜桃网站| 97超碰国产精品| 羞羞网站在线免费观看| 亚洲欧美日韩中文播放| 国产高潮呻吟久久久| 麻豆传媒在线完整视频| ●精品国产综合乱码久久久久 | 999久久欧美人妻一区二区| 午夜看片在线免费| 国产精品欧美一区喷水| 亚洲国产精品一区在线观看不卡| 久久天堂电影| 亚洲国产高清aⅴ视频| 欧美污视频久久久| 国产免费av高清在线| 国产日韩欧美不卡| 一级做a爰片久久| 国产日产一区二区| 一区二区三区中文字幕电影| 日韩国产小视频| 91九色在线播放| 欧美日韩激情视频| 99精品视频在线看| 91九色综合| 欧美裸体bbwbbwbbw| 日本亚洲一区二区三区| 一区二区三区在线资源| 精品视频久久久久久| 性猛交娇小69hd| 在线一区免费| 97精品久久久中文字幕免费| 久草手机在线视频| 久久精品国产秦先生| 91手机视频在线观看| 亚洲精品国产片| 久久人人爽爽爽人久久久| 日韩欧美在线电影| a视频在线免费看| 黄网站色欧美视频| 亚洲视频中文字幕| 动漫一区二区在线| 男男电影完整版在线观看| 中文字幕av资源一区| 日韩一二区视频| 天堂在线中文网官网| 欧美性色黄大片手机版| 国产男女无遮挡猛进猛出| 精品三级av| 日韩天堂在线视频| 国产精品不卡av| 开心九九激情九九欧美日韩精美视频电影 | 青青草华人在线视频| 欧美在线免费| 欧洲美女免费图片一区| 一级黄色小视频| av亚洲精华国产精华精华| 亚洲国产精品视频一区| а√在线天堂官网| 制服丝袜亚洲色图| 在哪里可以看毛片| 欧美日韩18| 国产欧美最新羞羞视频在线观看| 免费国产精品视频| 国产精品久久三| 999香蕉视频| 你懂的在线观看一区二区| 久久中文字幕在线| 成人看片人aa| 国产中文字幕免费| 久久国产精品72免费观看| 久久99精品久久久久久久久久| 麻豆影视在线观看_| 一本久道中文字幕精品亚洲嫩| 动漫美女无遮挡免费| 国产精品videosex性欧美| 日本免费久久高清视频| 天天av天天翘| 亚洲一本大道在线| 红桃视频一区二区三区免费| 日韩av专区| 国产91免费看片| 欧洲亚洲精品视频| 福利精品视频在线| 亚洲av综合色区无码另类小说| 91亚洲国产| 国产精品一区久久久| 国产区高清在线| 色综合久久中文综合久久97| 麻豆精品国产传媒av| 欧美日韩亚洲一区三区| 91人人爽人人爽人人精88v| 国产性一乱一性一伧一色| av在线三区| 精品久久久久久亚洲国产300| 在线播放第一页| 欧美国产高清| 91青青草免费在线看| 国内精品久久久久国产| 91精品在线观看入口| 黄色a级片在线观看| 韩国av一区二区三区在线观看 | 一区二区日韩欧美| 91精品视频在线| а√天堂资源地址在线下载| 欧美一区二区三区视频在线| 日本少妇高清视频| 国产iv一区二区三区| 欧美亚洲色图视频| 成人直播在线观看| 欧美在线观看视频| 毛片免费在线播放| 欧美午夜寂寞影院| 国产精品国产三级国产传播| 国产91综合网| 欧美亚洲日本一区二区三区| 久久不见久久见中文字幕免费| 国产精品久久久久久av| 日本欧美在线视频免费观看| 日韩欧美激情一区| 日韩免费不卡视频| 国产亚洲精品久| 91视频这里只有精品| 欧美一区免费| 蜜桃精品久久久久久久免费影院| 99久久精品一区二区成人| 久久亚洲电影天堂| 深爱激情五月婷婷| 欧美性色黄大片手机版| 国内偷拍精品视频| 91首页免费视频| 亚洲欧洲日本精品| 伊人久久婷婷| 亚洲国产一区在线| 一区二区三区四区精品视频 | 最新日韩av| 久久99国产精品| 国产一区二区三区朝在线观看| 久久视频在线免费观看| 四虎影视2018在线播放alocalhost| 日本韩国精品在线| 婷婷在线精品视频| 久久久亚洲综合| 亚洲黄色片免费看| 亚洲一区二区三区高清不卡| 一区二区三区四区欧美日韩| 精品国产导航| 91精品国产自产在线观看永久| 97人澡人人添人人爽欧美| 在线观看欧美视频| 日韩一区二区三区不卡| 欧美视频在线不卡| 日韩精品一区二区在线播放| 亚洲日韩欧美一区二区在线| 右手影院亚洲欧美| 国产福利电影一区二区三区| 五月婷婷之综合激情| 亚洲经典三级| 国产精品12p| 精品国内自产拍在线观看视频| 91青青草免费观看| 欧美91在线|欧美| 国产69精品久久久久久| 色婷婷在线播放| 中文字幕视频一区二区在线有码| 天天操天天干天天插| 91精品免费在线| 自拍偷拍福利视频| 欧美性xxxxhd| 国产视频91在线| 亚洲一级不卡视频| 538精品在线视频| 国产精品进线69影院| 91国模少妇一区二区三区| 成人黄页毛片网站| 亚洲AV成人精品| 国内不卡的二区三区中文字幕| 久久综合伊人77777麻豆最新章节| 国产欧美在线| 国精产品一区一区三区视频| 狠狠综合久久| 日韩中文在线字幕| 99久久激情| 中文字幕一区二区中文字幕| 日本a级不卡| 亚洲成人第一| 成人羞羞网站| 视频在线观看成人| 青青草原综合久久大伊人精品| 日韩.欧美.亚洲| 狠狠色狠狠色综合婷婷tag| 欧美成人dvd在线视频| 久久无码高潮喷水| 99热在线成人| 久久免费看毛片| 国产精品91一区二区三区| 亚洲免费视频一区| 日韩午夜电影网| 一本一本a久久| 亚洲成人二区| 小泽玛利亚av在线| 欧美久久九九| 人妻久久久一区二区三区| 亚洲国产日韩在线| 男人天堂1024| 老司机精品视频网站| 男人舔女人下面高潮视频| 日韩成人伦理电影在线观看| 尤蜜粉嫩av国产一区二区三区| 日本网站在线观看一区二区三区| 狠狠操狠狠干视频| 国模大尺度一区二区三区| 日本wwwxx| 成人av网站在线观看| 中文乱码人妻一区二区三区视频| 91农村精品一区二区在线| 香蕉视频黄色在线观看| 亚洲国产成人午夜在线一区| 尤物在线免费视频| 亚洲图片一区二区| 亚洲黄网在线观看| 欧美精品在线一区二区| 亚洲AV无码国产精品午夜字幕 | 免费观看一区二区三区| 成人一区在线看| 国产精品久久久久无码av色戒| 国产精品系列在线| 欧美毛片在线观看| 欧美性生交xxxxx久久久| 中文字幕自拍偷拍| 欧美变态tickle挠乳网站| 五月婷婷激情在线| 中文字幕精品网| 丰满的护士2在线观看高清| 日本高清久久天堂| 24小时成人在线视频| 久久综合九色综合网站| 香蕉久久网站| 久久国产亚洲精品无码| 美国av一区二区| 深田咏美中文字幕| 国产精品免费免费| 国产一卡二卡在线| 欧美日韩亚洲综合在线| 黄色一级a毛片| 日日噜噜噜夜夜爽亚洲精品| 三级在线看中文字幕完整版| 91精品国产综合久久久久久久久| 欧美午夜18电影| 400部精品国偷自产在线观看 | 亚洲资源在线观看| 日韩在线视频不卡| 日韩和的一区二区| 好吊色欧美一区二区三区| 成人激情免费视频| 欧美v在线观看| 国产精品99久久久久久久vr| 亚洲精品国产一区黑色丝袜| 亚洲一区二区三区四区在线 | 日本成人在线不卡视频| 国产国语老龄妇女a片| 国产精品久久久久三级| 成人午夜视频在线播放| 欧美一级久久久久久久大片| 大乳在线免费观看| 97视频在线观看成人| 亚洲超碰在线观看| 国产精品亚洲天堂| 鲁大师成人一区二区三区 | 亚洲特级黄色片| 日韩精品视频在线观看网址| 久久亚洲导航| 91精品国自产在线观看| 久久影院资源站| 日韩精品在线视频免费观看| 极品少妇xxxx精品少妇偷拍| 一级二级黄色片| 91福利视频久久久久| 亚洲人妻一区二区三区| 欧美激情视频在线观看| 日韩五码电影| 伊人情人网综合| 蜜臂av日日欢夜夜爽一区| 成人性生交大免费看| 欧美视频不卡中文| 偷拍25位美女撒尿视频在线观看| 久久欧美在线电影| 国产精品xxxav免费视频| 欧美另类videosbestsex日本| 狠狠色2019综合网| 91麻豆精品成人一区二区| 欧美人狂配大交3d怪物一区| av在线播放免费| 国产欧美精品日韩| 久久精品亚洲人成影院 | 超碰cao国产精品一区二区| 黄色特一级视频| 国产风韵犹存在线视精品| 美女的奶胸大爽爽大片| 日韩欧美成人午夜| 97蜜桃久久| 麻豆传媒一区二区| 视频一区中文字幕| 嘿嘿视频在线观看| 在线成人免费视频| 操你啦视频在线| 国产伦精品一区二区三毛| 99热免费精品在线观看| 中国黄色a级片| 在线中文字幕不卡| 欧美日本一道| 91深夜福利视频| 亚洲精品国产日韩| 精品人妻无码一区二区三区| 欧美亚州韩日在线看免费版国语版| а天堂8中文最新版在线官网| 欧美午夜精品久久久久久浪潮| 性爱在线免费视频| 欧美一三区三区四区免费在线看| 四季久久免费一区二区三区四区| 超碰97人人人人人蜜桃| 亚洲一区中文| 中国特黄一级片| 欧美成人a∨高清免费观看| 女人让男人操自己视频在线观看| 日产精品久久久一区二区| 国产一区二区在线观看视频| 黄色激情视频在线观看| 亚洲欧美激情另类校园| 亚洲伦理一区二区| 日韩a∨精品日韩在线观看| 国产清纯在线一区二区www| 99热这里只有精品66| 欧洲亚洲妇女av| 欧美fxxxxxx另类| 亚洲欧美视频在线播放| 欧美精品一二三四| 国产在线精彩视频| 亚洲欧洲精品一区二区三区波多野1战4 | 国产一区二区三区四区五区| 久久久久久久久久久久久国产| 久久色在线观看| 亚洲AV无码国产精品午夜字幕| 国产精品对白刺激| 国产精品扒开腿做爽爽爽软件| 亚洲黄色免费视频| 亚洲成人激情在线观看|