久久福利_99r_国产日韩在线视频_直接看av的网站_中文欧美日韩_久久一

您的位置:首頁技術文章
文章詳情頁

從vue-router看前端路由的兩種實現

瀏覽:73日期:2022-09-30 09:57:59

隨著前端應用的業務功能越來越復雜、用戶對于使用體驗的要求越來越高,單頁應用(SPA)成為前端應用的主流形式。大型單頁應用最顯著特點之一就是采用前端路由系統,通過改變URL,在不重新請求頁面的情況下,更新頁面視圖。

“更新視圖但不重新請求頁面”是前端路由原理的核心之一,目前在瀏覽器環境中這一功能的實現主要有兩種方式:

利用URL中的hash(“#”) 利用History interface在 HTML5中新增的方法

vue-router是Vue.js框架的路由插件,下面我們從它的源碼入手,邊看代碼邊看原理,由淺入深觀摩vue-router是如何通過這兩種方式實現前端路由的。

模式參數

在vue-router中是通過mode這一參數控制路由的實現模式的:

const router = new VueRouter({ mode: ’history’, routes: [...]})

創建VueRouter的實例對象時,mode以構造函數參數的形式傳入。帶著問題閱讀源碼,我們就可以從VueRouter類的定義入手。一般插件對外暴露的類都是定義在源碼src根目錄下的index.js文件中,打開該文件,可以看到VueRouter類的定義,摘錄與mode參數有關的部分如下:

export default class VueRouter { mode: string; // 傳入的字符串參數,指示history類別 history: HashHistory | HTML5History | AbstractHistory; // 實際起作用的對象屬性,必須是以上三個類的枚舉 fallback: boolean; // 如瀏覽器不支持,’history’模式需回滾為’hash’模式 constructor (options: RouterOptions = {}) {let mode = options.mode || ’hash’ // 默認為’hash’模式 this.fallback = mode === ’history’ && !supportsPushState // 通過supportsPushState判斷瀏覽器是否支持’history’模式 if (this.fallback) { mode = ’hash’ } if (!inBrowser) { mode = ’abstract’ // 不在瀏覽器環境下運行需強制為’abstract’模式 } this.mode = mode // 根據mode確定history實際的類并實例化 switch (mode) { case ’history’:this.history = new HTML5History(this, options.base)break case ’hash’:this.history = new HashHistory(this, options.base, this.fallback)break case ’abstract’:this.history = new AbstractHistory(this, options.base)break default:if (process.env.NODE_ENV !== ’production’) { assert(false, `invalid mode: ${mode}`)} } } init (app: any /* Vue component instance */) {const history = this.history // 根據history的類別執行相應的初始化操作和監聽 if (history instanceof HTML5History) { history.transitionTo(history.getCurrentLocation()) } else if (history instanceof HashHistory) { const setupHashListener = () => {history.setupListeners() } history.transitionTo(history.getCurrentLocation(),setupHashListener,setupHashListener ) } history.listen(route => { this.apps.forEach((app) => {app._route = route }) }) } // VueRouter類暴露的以下方法實際是調用具體history對象的方法 push (location: RawLocation, onComplete?: Function, onAbort?: Function) { this.history.push(location, onComplete, onAbort) } replace (location: RawLocation, onComplete?: Function, onAbort?: Function) { this.history.replace(location, onComplete, onAbort) }}

可以看出:

作為參數傳入的字符串屬性mode只是一個標記,用來指示實際起作用的對象屬性history的實現類,兩者對應關系如下:

mode history hash abstract history HTML5History HashHistory AbstractHistory

在初始化對應的history之前,會對mode做一些校驗:若瀏覽器不支持HTML5History方式(通過supportsPushState變量判斷),則mode強制設為’hash’;若不是在瀏覽器環境下運行,則mode強制設為’abstract’

VueRouter類中的onReady(), push()等方法只是一個代理,實際是調用的具體history對象的對應方法,在init()方法中初始化時,也是根據history對象具體的類別執行不同操作

在瀏覽器環境下的兩種方式,分別就是在HTML5History,HashHistory兩個類中實現的。他們都定義在src/history文件夾下,繼承自同目錄下base.js文件中定義的History類。History中定義的是公用和基礎的方法,直接看會一頭霧水,我們先從HTML5History,HashHistory兩個類中看著親切的push(), replace()方法的說起。

HashHistory

看源碼前先回顧一下原理:

hash(“#”)符號的本來作用是加在URL中指示網頁中的位置:

www.example.com/index.html#…

#符號本身以及它后面的字符稱之為hash,可通過window.location.hash屬性讀取。它具有如下特點:

hash雖然出現在URL中,但不會被包括在HTTP請求中。它是用來指導瀏覽器動作的,對服務器端完全無用,因此,改變hash不會重新加載頁面 可以為hash的改變添加監聽事件:

window.addEventListener('hashchange', funcRef, false)

每一次改變hash(window.location.hash),都會在瀏覽器的訪問歷史中增加一個記錄

利用hash的以上特點,就可以來實現前端路由“更新視圖但不重新請求頁面”的功能了。

HashHistory.push()

我們來看HashHistory中的push()方法:

push (location: RawLocation, onComplete?: Function, onAbort?: Function) { this.transitionTo(location, route => { pushHash(route.fullPath) onComplete && onComplete(route) }, onAbort)}function pushHash (path) { window.location.hash = path}

transitionTo()方法是父類中定義的是用來處理路由變化中的基礎邏輯的,push()方法最主要的是對window的hash進行了直接賦值:

window.location.hash = route.fullPath

hash的改變會自動添加到瀏覽器的訪問歷史記錄中。

那么視圖的更新是怎么實現的呢,我們來看父類History中transitionTo()方法的這么一段:

transitionTo (location: RawLocation, onComplete?: Function, onAbort?: Function) { const route = this.router.match(location, this.current) this.confirmTransition(route, () => { this.updateRoute(route) ... })}updateRoute (route: Route) { this.cb && this.cb(route) }listen (cb: Function) { this.cb = cb}

可以看到,當路由變化時,調用了History中的this.cb方法,而this.cb方法是通過History.listen(cb)進行設置的。回到VueRouter類定義中,找到了在init()方法中對其進行了設置:

init (app: any /* Vue component instance */) { this.apps.push(app) history.listen(route => { this.apps.forEach((app) => { app._route = route }) })}

根據注釋,app為Vue組件實例,但我們知道Vue作為漸進式的前端框架,本身的組件定義中應該是沒有有關路由內置屬性_route,如果組件中要有這個屬性,應該是在插件加載的地方,即VueRouter的install()方法中混合入Vue對象的,查看install.js源碼,有如下一段:

export function install (Vue) { Vue.mixin({ beforeCreate () { if (isDef(this.$options.router)) {this._router = this.$options.routerthis._router.init(this)Vue.util.defineReactive(this, ’_route’, this._router.history.current) } registerInstance(this, this) }, })}

通過Vue.mixin()方法,全局注冊一個混合,影響注冊之后所有創建的每個 Vue 實例,該混合在beforeCreate鉤子中通過Vue.util.defineReactive()定義了響應式的_route屬性。所謂響應式屬性,即當_route值改變時,會自動調用Vue實例的render()方法,更新視圖。

總結一下,從設置路由改變到視圖更新的流程如下:

$router.push() --> HashHistory.push() --> History.transitionTo() --> History.updateRoute() --> {app._route = route} --> vm.render()HashHistory.replace()

replace()方法與push()方法不同之處在于,它并不是將新路由添加到瀏覽器訪問歷史的棧頂,而是替換掉當前的路由:

replace (location: RawLocation, onComplete?: Function, onAbort?: Function) { this.transitionTo(location, route => { replaceHash(route.fullPath) onComplete && onComplete(route) }, onAbort)} function replaceHash (path) { const i = window.location.href.indexOf(’#’) window.location.replace( window.location.href.slice(0, i >= 0 ? i : 0) + ’#’ + path )}

可以看出,它與push()的實現結構上基本相似,不同點在于它不是直接對window.location.hash進行賦值,而是調用window.location.replace方法將路由進行替換。

監聽地址欄

以上討論的VueRouter.push()和VueRouter.replace()是可以在vue組件的邏輯代碼中直接調用的,除此之外在瀏覽器中,用戶還可以直接在瀏覽器地址欄中輸入改變路由,因此VueRouter還需要能監聽瀏覽器地址欄中路由的變化,并具有與通過代碼調用相同的響應行為。在HashHistory中這一功能通過setupListeners實現:

setupListeners () { window.addEventListener(’hashchange’, () => { if (!ensureSlash()) { return } this.transitionTo(getHash(), route => { replaceHash(route.fullPath) }) })}

該方法設置監聽了瀏覽器事件hashchange,調用的函數為replaceHash,即在瀏覽器地址欄中直接輸入路由相當于代碼調用了replace()方法

HTML5History

History interface是瀏覽器歷史記錄棧提供的接口,通過back(), forward(), go()等方法,我們可以讀取瀏覽器歷史記錄棧的信息,進行各種跳轉操作。

從HTML5開始,History interface提供了兩個新的方法:pushState(), replaceState()使得我們可以對瀏覽器歷史記錄棧進行修改:

window.history.pushState(stateObject, title, URL)window.history.replaceState(stateObject, title, URL) stateObject: 當瀏覽器跳轉到新的狀態時,將觸發popState事件,該事件將攜帶這個stateObject參數的副本 title: 所添加記錄的標題 URL: 所添加記錄的URL

這兩個方法有個共同的特點:當調用他們修改瀏覽器歷史記錄棧后,雖然當前URL改變了,但瀏覽器不會立即發送請求該URL(the browser won’t attempt to load this URL after a call to pushState()),這就為單頁應用前端路由“更新視圖但不重新請求頁面”提供了基礎。

我們來看vue-router中的源碼:

push (location: RawLocation, onComplete?: Function, onAbort?: Function) { const { current: fromRoute } = this this.transitionTo(location, route => { pushState(cleanPath(this.base + route.fullPath)) handleScroll(this.router, route, fromRoute, false) onComplete && onComplete(route) }, onAbort)}replace (location: RawLocation, onComplete?: Function, onAbort?: Function) { const { current: fromRoute } = this this.transitionTo(location, route => { replaceState(cleanPath(this.base + route.fullPath)) handleScroll(this.router, route, fromRoute, false) onComplete && onComplete(route) }, onAbort)}// src/util/push-state.jsexport function pushState (url?: string, replace?: boolean) { saveScrollPosition() // try...catch the pushState call to get around Safari // DOM Exception 18 where it limits to 100 pushState calls const history = window.history try { if (replace) { history.replaceState({ key: _key }, ’’, url) } else { _key = genKey() history.pushState({ key: _key }, ’’, url) } } catch (e) { window.location[replace ? ’replace’ : ’assign’](url) }}export function replaceState (url?: string) { pushState(url, true)}

代碼結構以及更新視圖的邏輯與hash模式基本類似,只不過將對window.location.hash直接進行賦值window.location.replace()改為了調用history.pushState()和history.replaceState()方法。

在HTML5History中添加對修改瀏覽器地址欄URL的監聽是直接在構造函數中執行的:

constructor (router: Router, base: ?string) { window.addEventListener(’popstate’, e => { const current = this.current this.transitionTo(getLocation(this.base), route => { if (expectScroll) {handleScroll(router, route, current, true) } }) })}

當然了HTML5History用到了HTML5的新特特性,是需要特定瀏覽器版本的支持的,前文已經知道,瀏覽器是否支持是通過變量supportsPushState來檢查的:

// src/util/push-state.jsexport const supportsPushState = inBrowser && (function () { const ua = window.navigator.userAgent if ( (ua.indexOf(’Android 2.’) !== -1 || ua.indexOf(’Android 4.0’) !== -1) && ua.indexOf(’Mobile Safari’) !== -1 && ua.indexOf(’Chrome’) === -1 && ua.indexOf(’Windows Phone’) === -1 ) { return false } return window.history && ’pushState’ in window.history})()

以上就是hash模式與history模式源碼的導讀,這兩種模式都是通過瀏覽器接口實現的,除此之外vue-router還為非瀏覽器環境準備了一個abstract模式,其原理為用一個數組stack模擬出瀏覽器歷史記錄棧的功能。當然,以上只是一些核心邏輯,為保證系統的魯棒性,源碼中還有大量的輔助邏輯,也很值得學習。此外在vue-router中還有路由匹配、router-view視圖組件等重要部分

兩種模式比較

在一般的需求場景中,hash模式與history模式是差不多的,但幾乎所有的文章都推薦使用history模式,理由竟然是:'#' 符號太丑...0_0 '

如果不想要很丑的 hash,我們可以用路由的 history 模式 ——官方文檔

當然,嚴謹的我們肯定不應該用顏值評價技術的好壞。根據MDN的介紹,調用history.pushState()相比于直接修改hash主要有以下優勢:

pushState設置的新URL可以是與當前URL同源的任意URL;而hash只可修改#后面的部分,故只可設置與當前同文檔的URL pushState設置的新URL可以與當前URL一模一樣,這樣也會把記錄添加到棧中;而hash設置的新值必須與原來不一樣才會觸發記錄添加到棧中 pushState通過stateObject可以添加任意類型的數據到記錄中;而hash只可添加短字符串 pushState可額外設置title屬性供后續使用 history模式的一個問題

我們知道對于單頁應用來講,理想的使用場景是僅在進入應用時加載index.html,后續在的網絡操作通過Ajax完成,不會根據URL重新請求頁面,但是難免遇到特殊情況,比如用戶直接在地址欄中輸入并回車,瀏覽器重啟重新加載應用等。

hash模式僅改變hash部分的內容,而hash部分是不會包含在HTTP請求中的:

http://oursite.com/#/user/id // 如重新請求只會發送http://oursite.com/

故在hash模式下遇到根據URL請求頁面的情況不會有問題。

而history模式則會將URL修改得就和正常請求后端的URL一樣

http://oursite.com/user/id

在此情況下重新向后端發送請求,如后端沒有配置對應/user/id的路由處理,則會返回404錯誤。官方推薦的解決辦法是在服務端增加一個覆蓋所有情況的候選資源:如果 URL 匹配不到任何靜態資源,則應該返回同一個 index.html 頁面,這個頁面就是你 app 依賴的頁面。同時這么做以后,服務器就不再返回 404 錯誤頁面,因為對于所有路徑都會返回 index.html 文件。為了避免這種情況,在 Vue 應用里面覆蓋所有的路由情況,然后在給出一個 404 頁面。或者,如果是用 Node.js 作后臺,可以使用服務端的路由來匹配 URL,當沒有匹配到路由的時候返回 404,從而實現 fallback。

直接加載應用文件

Tip: built files are meant to be served over an HTTP server.

Opening index.html over file:// won’t work.

Vue項目通過vue-cli的webpack打包完成后,命令行會有這么一段提示。通常情況,無論是開發還是線上,前端項目都是通過服務器訪問,不存在 'Opening index.html over file://' ,但程序員都知道,需求和場景永遠是千奇百怪的,只有你想不到的,沒有產品經理想不到的。

本文寫作的初衷就是遇到了這樣一個問題:需要快速開發一個移動端的展示項目,決定采用WebView加載Vue單頁應用的形式,但沒有后端服務器提供,所以所有資源需從本地文件系統加載:

// AndroidAppWrapperpublic class MainActivity extends AppCompatActivity { private WebView webView; @Override protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);webView = new WebView(this);webView.getSettings().setJavaScriptEnabled(true);webView.loadUrl('file:///android_asset/index.html');setContentView(webView); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) {if ((keyCode == KeyEvent.KEYCODE_BACK) && webView.canGoBack()) { webView.goBack(); return true;}return false; }}

此情此景看來是必須 'Opening index.html over file://' 了,為此,我首先要進行了一些設置

在項目config.js文件中將assetsPublicPath字段的值改為相對路徑 ’./’ 調整生成的static文件夾中圖片等靜態資源的位置與代碼中的引用地址一致

這是比較明顯的需要改動之處,但改完后依舊無法順利加載,經過反復排查發現,項目在開發時,router設置為了history模式(為了美觀...0_0'),當改為hash模式后就可正常加載了。

為什么會出現這種情況呢?我分析原因可能如下:

當從文件系統中直接加載index.html時,URL為:

file:///android_asset/index.html

而首頁視圖需匹配的路徑為path: ’/’ :

export default new Router({ mode: ’history’, routes: [ { path: ’/’, name: ’index’, component: IndexView } ]})

我們先來看history模式,在HTML5History中:

ensureURL (push?: boolean) { if (getLocation(this.base) !== this.current.fullPath) { const current = cleanPath(this.base + this.current.fullPath) push ? pushState(current) : replaceState(current) }}export function getLocation (base: string): string { let path = window.location.pathname if (base && path.indexOf(base) === 0) { path = path.slice(base.length) } return (path || ’/’) + window.location.search + window.location.hash}

邏輯只會確保存在URL,path是通過剪切的方式直接從window.location.pathname獲取到的,它的結尾是index.html,因此匹配不到 ’/’ ,故 'Opening index.html over file:// won’t work' 。

再看hash模式,在HashHistory中:

export class HashHistory extends History { constructor (router: Router, base: ?string, fallback: boolean) { ... ensureSlash() } // this is delayed until the app mounts // to avoid the hashchange listener being fired too early setupListeners () { window.addEventListener(’hashchange’, () => { if (!ensureSlash()) {return } ... }) } getCurrentLocation () { return getHash() }}function ensureSlash (): boolean { const path = getHash() if (path.charAt(0) === ’/’) { return true } replaceHash(’/’ + path) return false}export function getHash (): string { const href = window.location.href const index = href.indexOf(’#’) return index === -1 ? ’’ : href.slice(index + 1)}

我們看到在代碼邏輯中,多次出現一個函數ensureSlash(),當#符號后緊跟著的是’/’,則返回true,否則強行插入這個’/’,故我們可以看到,即使是從文件系統打開index.html,URL依舊會變為以下形式:

file:///C:/Users/dist/index.html#/

getHash()方法返回的path為 ’/’ ,可與首頁視圖的路由匹配。

故要想從文件系統直接加載Vue單頁應用而不借助后端服務器,除了打包后的一些路徑設置外,還需確保vue-router使用的是hash模式。

以上就是從vue-router看前端路由的兩種實現的詳細內容,更多關于vue前端路由的兩種實現的資料請關注好吧啦網其它相關文章!

標簽: Vue
相關文章:
主站蜘蛛池模板: 一区视频网站 | 91精品久久久久久久久久久 | 操操操影院| 国产精品久热 | 国产成人精品一区二区三区视频 | 一区二区激情 | 中文字幕天堂在线 | 精品久久久久久国产 | 99这里只有精品视频 | 欧美日韩久久久 | 九九porny88av | 欧美日韩亚洲国内综合网 | 日韩在线亚洲 | 色婷婷av一区二区三区大白胸 | 成人午夜在线视频 | 欧美激情国产日韩精品一区18 | 久久久91精品国产一区二区精品 | 国产精品久久久久久吹潮 | 毛片av片| 免费观看一区二区三区毛片 | 黄色一级片免费 | 日韩欧美精品一区二区三区 | 亚洲日本精品视频 | 国产精品久久久久久久久久久久久久 | 日本黄色大片免费 | 欧美激情一区二区三区四区 | 国产精品免费观看 | 久久69精品久久久久久久电影好 | 欧美二区视频 | 中文字幕本久久精品一区 | 51国产午夜精品免费视频 | 成人免费毛片aaaaaa片 | 午夜精品视频 | 久久精品久久久久久久久久16 | 狠狠色丁香婷婷综合 | 91精品久久久久久久久入口 | 一级黄色影片在线观看 | 亚洲一区视频在线 | 一本大道综合伊人精品热热 | 在线观看国产视频 | 久草热视频| 国产一区二区三区精品久久久 | 国产视频中文字幕 | 北条麻妃国产九九九精品小说 | 精品久久久久久久久久久久久久 | 国产九九精品 | 伊人超碰 | 7777视频| 国产一区二区在线播放 | 91网在线观看 | 国产一区二区视频在线观看 | 国产精品久久久久久久 | 欧美激情一区二区三级高清视频 | 日韩欧美在线视频免费观看 | 久草在线在线精品观看 | 午夜精品久久久久久 | 欧美日韩一区二区在线观看 | 国产九九av | 亚洲成av| 五月婷婷狠狠爱 | 一区二区三区国产视频 | 欧美精品成人一区二区在线 | 中文 日韩 欧美 | 久久国产精品无码网站 | 日韩成人高清视频 | 免费在线精品视频 | 日韩精品一区二区三区四区视频 | 黄色电影在线免费观看 | 日日夜夜草 | 97理论片| 热久久这里只有精品 | 看亚洲a级一级毛片 | 四虎在线视频 | 欧美激情视频一区二区三区在线播放 | 国产精品美女久久久久aⅴ国产馆 | 婷婷五月色综合香五月 | 免费观看特级毛片 | 日韩欧美一区二区三区免费观看 | 精品一区二区三区免费 | 日韩一区电影 | 午夜色福利 | 精品久久久久久久久久久久久久久久久久 | 国产高清精品一区二区三区 | 亚洲 自拍 另类 欧美 丝袜 | 日韩在线播放欧美字幕 | 成年人在线视频播放 | 国产精品久久久久久 | 午夜妇女aaaa区片 | 免费国产一区 | 免费观看一区二区三区毛片 | 亚洲一区二区三区四区的 | 男女羞羞视频网站18 | 日韩成人高清电影 | 高清国产视频 | 国产成人av网站 | 欧美视频一区二区三区在线观看 | 91精品国产综合久久久久久 | 欧美性猛交一区二区三区精品 | 在线区| 日韩三区 | 四虎影院在线免费播放 | 亚洲精品乱码久久久久久花季 | 国产精品久久久 | 日韩精品免费在线观看 | 夜夜操操操 | 亚洲视频免费观看 | av免费资源| 国产精品久久久久久婷婷天堂 | 亚洲自拍偷拍精品 | 北条麻妃一区二区三区在线观看 | 国产日韩精品视频 | 欧美国产视频一区 | 日本大人吃奶视频xxxx | 国产毛片在线看 | 一级在线观看视频 | 欧美jizzhd精品欧美巨大免费 | 日韩av一区二区在线观看 | 免费成人一级片 | 国产黄色大片 | 国产乡下妇女做爰视频 | 99精品热 | 精品一区二区三区免费 | 精品国产第一国产综合精品 | 九九九视频| 欧美日韩精品网站 | www.涩涩视频 | 国产97在线播放 | 无码日韩精品一区二区免费 | 国产日韩免费 | 日韩av高清 | 亚洲精品二区 | 久久99视频精品 | 在线99| 午夜在线 | 九色91视频 | 亚洲免费人成在线视频观看 | 一区二区三区在线 | 欧 | 亚洲欧美在线观看 | 国产精品三级视频 | 国产毛片在线 | 毛片在线视频 | 91在线视频 | 一级电影免费在线观看 | 欧美在线一区二区三区 | 久久精品1区 | 欧美视频综合 | 一区二区三区四区精品 | 日本亚洲视频 | 成人午夜啪啪好大 | 久草电影网 | 日韩成人影院 | 国产视频一区二区三区四区 | 伊人网综合视频 | 青青久在线视频 | 三级在线观看 | 国产精品综合视频 | 国产精品999 | 国产高清视频在线 | 国产毛片精品 | 欧美福利一区 | 久久久久国产精品 | 久久久亚洲一区 | 亚洲一区视频 | 久久亚洲国产视频 | 一色桃子av一区二区免费 | 欧美中文字幕在线 | 精品国产一区二区三区成人影院 | 91视频88av| 日日干夜夜操 | 国产在线a | 国产91久久久久 | 91精品国产日韩91久久久久久 | 免费国产黄网站在线观看视频 | 亚洲国产日韩a在线播放性色 | 国产精品久久久久久婷婷天堂 | 久久99国产精品 | 日本欧美在线 | 国产农村妇女精品 | 蜜桃视频麻豆女神沈芯语免费观看 | 亚洲综合首页 | 精品视频在线免费观看 | 亚洲日韩欧美一区二区在线 | 国产精品99久久久久久动医院 | 亚洲综合区 | 国产一区二区三区色淫影院 | 久久久久国产 | a级毛片基地 | 亚洲最新中文字幕 | 精品久久久久久久久久久 | 精品国产乱码久久久久久88av | 成人午夜精品 | 亚洲欧洲无码一区二区三区 | 精品国产不卡一区二区三区 | 精品国产乱码久久久久久1区2区 | 国产在线1 | 欧美日韩午夜 | 亚洲免费观看视频 | 国产福利在线观看 | 国产免费一区二区三区网站免费 | 综合色婷婷一区二区亚洲欧美国产 | 日韩一区二区三区在线观看 | 国产精品欧美一区二区三区 | 国产精品久久国产精品99 gif | 亚洲一区二区三区四区 | 97精品超碰一区二区三区 | 久久精品久| 成人国产在线 | 国产日韩精品一区二区 | 欧美日韩a v | 欧美日韩一区二区中文字幕 | 久久av一区二区三区 | 国产免费观看一区二区三区 | 免费黄色片在线观看 | 亚洲天堂一区二区 | 国产日皮视频 | 日本免费一区二区在线观看 | 欧美精品一区在线发布 | 婷婷色视频 | 国产精品视屏 | 午夜小视频免费 | 亚洲精品视频在线 | 欧美一级特 | 久久韩剧网 | 欧美日韩精品区 | 久久99精品久久久久久琪琪 | 中文字幕一区二区在线观看 | 成人精品| 2012中文版免费观看 | 亚洲午夜视频 | 伊人天堂在线 | 成人深夜小视频 | 亚洲综合大片69999 | 欧美午夜三级视频 | 日本一区二区三区视频免费看 | 国产视频一区二区 | 奇米av| 极品毛片 | 久久精品国产免费 | 中文字幕久久精品 | 亚洲福利小视频 | 亚洲一二三 | 久久久91精品国产一区二区 | 久久国产精品一区二区 | 天天干狠狠操 | 午夜电影网址 | 成人欧美日韩一区二区三区 | 久久久精品 | 成人午夜影院 | 国产区在线观看 | 日本一区二区成人 | 国产一区二区三区在线看 | 国产羞羞视频 | 亚洲视频在线观看 | 欧美视频免费在线 | www.久久久.com | 国产亚洲欧美一区二区三区 | 精品久久久免费视频 | 中国一级大黄大黄大色毛片 | 成人免费crm在线观看 | 夏同学福利网 | 黄色资源在线观看 | 久久人人爽人人爽 | 欧美高清视频一区 | 亚洲免费片 | 欧美成人第一页 | 国产玖玖 | 国产一区二区三区在线视频 | 99久久99| 国产不卡在线观看 | 久久国产精品视频 | www.久久久久| 在线欧美日韩 | 欧美日韩在线看 | 日韩在线免费 | 97综合色 | 国产在线一级视频 | 在线亚洲精品 | 99青青草| 国产高清一区 | 国内精品视频一区国产 | 欧美视频在线免费 | 久久视频一区 | 91影库 | 爱爱视频在线观看 | 骚黄视频 | 欧美激情专区 | 亚洲精品视频在线播放 | 黄色拍拍视频 | 久久久精品视频免费观看 | 久久精品视频在线播放 | 国产精品一二三 | 天天拍天天草 | 日韩不卡一二三 | 国产高清在线视频 | 国产麻豆乱码精品一区二区三区 | 亚洲精品乱码久久久久久按摩观 | 国产一区二区三区免费 | 日韩中文字幕在线播放 | 夜夜夜久久| 天天艹夜夜艹 | 日韩欧美一区二区三区视频 | www.99精品| 日本亚洲欧美 | 精品一区二区三区在线观看 | 亚洲h在线观看 | 欧美成人精品激情在线观看 | 一级片在线观看 | 99久久婷婷国产综合精品电影 | 国产精品夜间视频香蕉 | 韩日中文字幕 | 一区二区免费视频 | 亚洲区一区二 | 禁果av一区二区三区 | 在线一区观看 | 91精品国产乱码久久久久久久久 | 欧美成人小视频 | 欧美日本韩国一区二区 | 国产欧美中文字幕 | 骚黄视频 | www.久久精品 | 亚洲午夜视频 | а天堂中文官网 | 日韩城人网站 | 免费一区二区三区 | 日韩一区二区在线电影 | 国产精品久久久久久久久久久小说 | 狠狠操夜夜爱 | 欧美日韩电影一区二区三区 | 亚洲国产精品99久久久久久久久 | 亚洲成人福利 | 国产精品久久久久久久久久久久久久 | 特黄特黄视频 | 国产日韩精品视频 | 免费看的毛片 | 在线观看欧美一区 | 毛片在线免费 | 成人在线播放网站 | 免费av毛片| 伊人天堂在线 | 白浆视频在线观看 | 欧美视频免费在线观看 | 国产999精品久久久久久麻豆 | 日韩欧美一级在线 | 国产精品久久av | 国产精品久久久久影院色老大 | 黄片毛片 | 久久99精品久久久久久按摩秒播 | 人干人人 | 国内精品一区二区 | 一区二区三区免费在线观看 | 欧美黑人巨大xxx极品 | 日韩午夜激情 | 国产高潮失禁喷水爽网站 | 91久久久久久久久久久久久 | 免费看毛片的网站 | av一区二区三区 | 国产精品久久久久久久久 | 亚洲欧美在线观看 | 午夜精品久久久久久久 | 亚洲高清视频在线 | 成人精品一区二区三区中文字幕 | 国产欧精精久久久久久久 | 激情毛片 | 精品中文在线 | 久久久91精品国产一区二区三区 | 99精品国产一区二区 | 日本在线观看 | 君岛美绪一区二区三区在线视频 | 51ⅴ精品国产91久久久久久 | 亚洲视频免费 | 黄色一级视屏 | 免费黄色小视频 | 美女一级| 精品在线一区 | 免费成人一级片 | 超碰高清| 久久国产精品一区 | www麻豆| 国产激情毛片 | 久久久久久久久久久久久久久久久久久 | gav成人免费播放视频 | 日韩99 | 亚洲第一免费视频网站 | 欧美日本亚洲 | 日韩一区二区中文字幕 | 国产激情性色视频在线观看 | 欧美午夜一区二区福利视频 | 久久久久国产精品 | 午夜a v电影 | 国产偷录视频叫床高潮对白 | 欧美色综合 | 国产免费一区二区 | 亚洲成人精品在线观看 | 亚洲国产福利一区 | 男女羞羞视频网站18 | 国产在线成人 | 91九色视频| 激情久久久久 | 国产精品不卡 | 精品欧美一区二区在线观看视频 | 色综合色综合 | 亚洲一区二区av | 欧美一区二区三区精品免费 | 97精品国产97久久久久久免费 | 亚洲高清免费视频 | 97碰碰碰| 黄色av网站在线观看 | 日日操av| 中文字幕高清视频 | 国产专区在线视频 | 中文字幕一区日韩精品欧美 | 午夜精品久久久久久99热软件 | 国产中文字幕在线 | 亚洲精品高清视频 | 成人网在线| 国产一区二区久久 | 国产欧美精品一区二区色综合朱莉 | 国产91网| 国产一区二区三区免费看 | 久久麻豆视频 | 国产在线成人 | 91大片 | 国产欧美日韩精品一区 | 国产精品777一区二区 | 国产一区二区三区在线免费观看 | 亚洲免费网站 | 激情图区在线观看 | 中文字幕视频在线 | 国产一区二区精品在线 | 亚洲欧美一区二区三区在线 | 国产一区在线视频 | 91久久精品国产亚洲a∨麻豆 | 欧美中文 | 亚洲高清在线观看视频 | 国产精品久久久久久久久大全 | 国产超碰人人爽人人做人人爱 | 一区二区三区在线播放 | 一区二区三区在线播放 | 黄色免费在线观看网址 | 亚洲三级av| 国产精品久久片 | 亚洲免费视频网站 | 国产精品jizz在线观看麻豆 | 91av在线免费看 | 欧美中文字幕在线观看 | 一本大道综合伊人精品热热 | 国产色在线观看 | 在线亚洲一区 | 亚洲精品在线播放 | 91中文字幕 | 久久久久久国产精品 | 精品日韩一区二区 | 成人精品国产一区二区4080 | 亚洲成人精品在线观看 | 黄色一级网站视频 | 欧美日韩中文 | 成人精品视频免费在线观看 | 国产精品久久久久久久久久久久午夜片 | 亚洲精品视频一区 | 欧美成人精品在线观看 | 欧美精品在线观看 | 国产精品美女av | caoporn免费 | 国产成人精品一区 | 欧美精品一区二区三区一线天视频 | 一区视频在线 | 亚洲视频中文字幕 | 国产综合99 | 久久综合久久久 | 好姑娘影视在线观看高清 | 亚洲精品二区 | 国产女人和拘做受视频 | 欧美日韩中文字幕在线 | 日韩一区二区在线观看视频 | 久久国产区 | 日韩成人在线观看 | av黄色在线| 北条麻妃一区二区三区在线观看 | 久久99深爱久久99精品 | 久久久久久久久久久免费视频 | 久久亚洲国产精品 | 欧美精品免费在线观看 | 操操网 | 国产欧美综合视频 | 国产精品国产精品国产专区不片 | 欧美亚洲一区 | 欧美日韩免费在线 | 午夜精品久久久久久久久 | 91精产国品一二三区在线观看 | 精品一二三区在线观看 | 91精品国产一区二区三区四区在线 | 激情婷婷| 狠狠操精品视频 | 国产伦精品一区二区三区四区视频 | 精品久久久久久国产 | 精品1区 | 午夜精 | 亚洲精选国产 | 日韩美一级 | 欧美日本国产 | 欧美人成在线视频 | 色五月激情五月 | 四虎影院在线看 | 欧美日韩亚洲国产综合 | 欧美激情精品久久久久久 | 99在线视频观看 | 国产二区三区 | 久久精品一区二区三区四区 | 亚洲永久免费视频 | 国产精品伦一区二区三级视频 | 91精品国产乱码久久久久久 | 中国一级免费毛片 | 欧美一区二区三区免费电影 | 国产精品美女久久久久aⅴ国产馆 | 亚洲在线| 青青久久网 | 91丝袜 | 日韩精品一区二区在线观看 | 国产精品久久久久久久7电影 | 狠狠躁夜夜躁人人爽天天天天97 | 日韩在线免费视频 | 国产不卡一区 | 久久久久国产精品www | 欧美成在线视频 | 欧美日韩一区二区三区在线观看 | 免费一区二区三区 | 黄色网址免费在线 | 国产91精品在线 | 中文字幕1区 | 国产成人在线视频 | 日本一区二区三区中文字幕 | 天天爽夜夜爽夜夜爽精品视频 | 欧美激情在线播放 | 青青久久av北条麻妃海外网 | 亚洲国产网站 | 欧美顶级毛片在线播放 | 亚洲成人福利 | 91精品久久久久久综合五月天 | 久草视| 国产精久久久久久久妇剪断 | 成人免费福利 | 欧美成在线观看 | 国产日韩欧美综合 | 午夜影院免费体验区 | 亚洲综合久久网 | 国产精品国产三级国产a | 久久久久久久久一区 | 久久国产一区二区三区 | 精品一区二区三区三区 | 91精品国产综合久久久久久蜜月 | 欧洲另类在线1 | 欧美综合色 | 亚洲日韩欧美一区二区在线 | 精品久久99| 99精品久久精品一区二区爱城 | 精品在线一区二区三区 | 99国产精品久久久 | 日韩精品视频免费专区在线播放 | 亚洲精彩视频在线 | www.色在线| 一级毛片在线看aaaa | 免费啪啪网站 | 国产成人午夜 | 成人免费视频观看视频 | 天天插天天射天天干 | 97视频精品 | 在线欧美日韩 | 国产免费一区二区 | 在线一区视频 | 国产精品片aa在线观看 | 亚洲一区二区三区在线播放 | 国产欧美网址 | 狠狠躁夜夜躁人人爽天天天天97 | 狠狠爱综合| 91在线精品视频 | 国产电影一区二区 | 免费福利视频一区 | 精品中文在线 | 日韩欧美一级 | 亚洲 欧美日韩 国产 中文 | 久久久久亚洲 | 国产精品久久久久久久久久东京 | 久久久久久亚洲 | 午夜精品一区二区三区免费视频 | 国产精品国产精品国产专区不卡 | 国产黄色免费视频 | 欧美精品第一页 | 剑来高清在线观看 | 欧美日韩一区二区三区在线观看 | 韩国久久精品 | 欧美一区二区三区精品 | 日韩精品 | a在线看 | 日韩成人久久 | 日韩超碰在线观看 | 久久久久一 | 久久99精品国产.久久久久 | 91电影在线观看 | 国产精品丝袜一区二区 | 欧美日韩一区二区三区四区 | 欧美精品成人 | 欧美日韩在线免费观看 | 日韩综合| 国产精品精品视频一区二区三区 | 久草视频国产 | 狠狠操夜夜操 | 国产高清美女一级a毛片久久 | 国产成人99久久亚洲综合精品 | 99精品国产在热久久 | 波多野结衣先锋影音 | 久久久一| 久久精品小视频 | 国产激情性色视频在线观看 | 日韩欧美精品 | av在线免费观看网址 |