日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > vue >内容正文

vue

element label动态赋值_浅析 vuerouter 源码和动态路由权限分配

發(fā)布時(shí)間:2023/12/9 vue 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 element label动态赋值_浅析 vuerouter 源码和动态路由权限分配 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

背景

上月立過一個(gè) flag,看完 vue-router 的源碼,可到后面逐漸發(fā)現(xiàn) vue-router 的源碼并不是像很多總結(jié)的文章那么容易理解,閱讀過你就會(huì)發(fā)現(xiàn)里面的很多地方都會(huì)有多層的函數(shù)調(diào)用關(guān)系,還有大量的 this 指向問題,而且會(huì)有很多輔助函數(shù)需要去理解。但還是堅(jiān)持啃下來了(當(dāng)然還沒看完,內(nèi)容是真的多),下面是我在政采云(實(shí)習(xí))工作閑暇時(shí)間閱讀源碼的一些感悟和總結(jié),并帶分析了大三時(shí)期使用的 vue-element-admin (https://panjiachen.gitee.io/vue-element-admin-site/zh/guide/#%E5%8A%9F%E8%83%BD) 這個(gè) vuer 無所不知的后臺(tái)框架的動(dòng)態(tài)路由權(quán)限控制原理。順便附帶本文實(shí)踐 demo 地址: 基于后臺(tái)框架開發(fā)的 學(xué)生管理系統(tǒng) (https://github.com/251205668/student-admin-template)。

vue-router 源碼分析

首先閱讀源碼之前最好是將 Vue 和 vue-router 的源碼克隆下來,然后第一遍閱讀建議先跟著 官方文檔 (https://router.vuejs.org/zh/) 先走一遍基礎(chǔ)用法,然后第二遍開始閱讀源碼,先理清楚各層級(jí)目錄的作用和抽出一些核心的文件出來,過一遍代碼的同時(shí)寫個(gè)小的 demo 邊看邊打斷點(diǎn)調(diào)試,看不懂沒關(guān)系,可以邊看邊參考一些總結(jié)的比較好的文章,最后將比較重要的原理過程根據(jù)自己的理解整理出來,然后畫一畫相關(guān)的知識(shí)腦圖加深印象。

前置知識(shí): flow 語法

JS 在編譯過程中可能看不出一些隱蔽的錯(cuò)誤,但在運(yùn)行過程中會(huì)報(bào)各種各樣的 bug。flow (https://flow.org/en/docs/getting-started/) 的作用就是編譯期間進(jìn)行靜態(tài)類型檢查,盡早發(fā)現(xiàn)錯(cuò)誤,拋出異常。

Vue、Vue-router 等大型項(xiàng)目往往需要這種工具去做靜態(tài)類型檢查以保證代碼的可維護(hù)性和可靠性。本文所分析的 vue-router 源碼中就大量的采用了 flow 去編寫函數(shù),所以學(xué)習(xí) flow 的語法是有必要的。

首先安裝 flow 環(huán)境,初始化環(huán)境

npm?install?flow-bin?-g
flow?init

在 index.js 中輸入這一段報(bào)錯(cuò)的代碼

/*@flow*/
function add(x: string, y: number): number {
return x + y
}
add(2, 11)

在控制臺(tái)輸入 flow,這個(gè)時(shí)候不出意外就會(huì)拋出異常提示,這就是簡單的 flow 使用方法。

具體用法還需要參考 flow官網(wǎng) (https://flow.org/en/docs/types/primitives/),另外這種語法是類似于 TypeScript (https://www.typescriptlang.org/) 的。

注冊

我們平時(shí)在使用 vue-router 的時(shí)候通常需要在 main.js 中初始化 Vue 實(shí)例時(shí)將 vue-router 實(shí)例對象當(dāng)做參數(shù)傳入

例如:

import?Router?from?'vue-router'
Vue.use(Router)
const?routes?=?[
???{
?????path:?'/student',
????name:?'student',
????component:?Layout,
????meta:?{?title:?'學(xué)生信息查詢',?icon:?'documentation',?roles:?['student']?},
????children:?[
??????{
????????path:?'info',
????????component:?()?=>?import('@/views/student/info'),
????????name:?'studentInfo',
????????meta:?{?title:?'信息查詢',?icon:?'form'?}
??????},
??????{
????????path:?'score',
????????component:?()?=>?import('@/views/student/score'),
????????name:?'studentScore',
????????meta:?{?title:?'成績查詢',?icon:?'score'?}
??????}
????]
??}
??...
];
const?router?=?new?Router({
??mode:?"history",
??linkActiveClass:?"active",
??base:?process.env.BASE_URL,
??routes
});
new?Vue({
????router,
????store,
????render:?h?=>?h(App)
}).$mount("#app");

Vue.use

那么 Vue.use(Router) 又在做什么事情呢

問題定位到 Vue 源碼中的 src/core/global-api/use.js 源碼地址 (https://github.com/vuejs/vue/blob/dev/src/core/global-api/use.js)

export?function?initUse?(Vue:?GlobalAPI)?{
??Vue.use?=?function?(plugin:?Function?|?Object)?{
????//?拿到?installPlugins?
????const?installedPlugins?=?(this._installedPlugins?||?(this._installedPlugins?=?[]))
????//?保證不會(huì)重復(fù)注冊
????if?(installedPlugins.indexOf(plugin)?>?-1)?{
??????return?this
????}
????//?獲取第一個(gè)參數(shù)?plugins?以外的參數(shù)
????const?args?=?toArray(arguments,?1)
????//?將?Vue?實(shí)例添加到參數(shù)
????args.unshift(this)
????//?執(zhí)行?plugin?的?install?方法?每個(gè)?insatll?方法的第一個(gè)參數(shù)都會(huì)變成?Vue,不需要額外引入
????if?(typeof?plugin.install?===?'function')?{
??????plugin.install.apply(plugin,?args)
????}?else?if?(typeof?plugin?===?'function')?{
??????plugin.apply(null,?args)
????}
????//?最后用?installPlugins?保存?
????installedPlugins.push(plugin)
????return?this
??}
}

可以看到 Vue 的 use 方法會(huì)接受一個(gè) plugin 參數(shù),然后使用 installPlugins 數(shù)組 保存已經(jīng)注冊過的 plugin。首先保證 plugin 不被重復(fù)注冊,然后將 Vue 從函數(shù)參數(shù)中取出,將整個(gè) Vue 作為 plugin 的install 方法的第一個(gè)參數(shù),這樣做的好處就是不需要麻煩的另外引入 Vue,便于操作。接著就去判斷 plugin 上是否存在 install 方法。存在則將賦值后的參數(shù)傳入執(zhí)行 ,最后將所有的存在 install 方法的 plugin 交給 installPlugins維護(hù)。

install

了解清楚 Vue.use 的結(jié)構(gòu)之后,可以得出 Vue 注冊插件其實(shí)就是在執(zhí)行插件的 install 方法,參數(shù)的第一項(xiàng)就是 Vue,所以我們將代碼定位到 vue-router 源碼中的 src/install.js 源碼地址 (https://github.com/vuejs/vue-router/blob/dev/src/install.js)

//?保存?Vue?的局部變量
export?let?_Vue
export?function?install?(Vue)?{
??//?如果已安裝
??if?(install.installed?&&?_Vue?===?Vue)?return
??install.installed?=?true
?//?局部變量保留傳入的?Vue
??_Vue?=?Vue
??const?isDef?=?v?=>?v?!==?undefined
??const?registerInstance?=?(vm,?callVal)?=>?{
????let?i?=?vm.$options._parentVnode
????if?(isDef(i)?&&?isDef(i?=?i.data)?&&?isDef(i?=?i.registerRouteInstance))?{
??????i(vm,?callVal)
????}
??}
??//?全局混入鉤子函數(shù)?每個(gè)組件都會(huì)有這些鉤子函數(shù),執(zhí)行就會(huì)走這里的邏輯
??Vue.mixin({
????beforeCreate?()?{
??????if?(isDef(this.$options.router))?{
????????//?new?Vue?時(shí)傳入的根組件?router?router對象傳入時(shí)就可以拿到?this.$options.router
????????//?根?router
????????this._routerRoot?=?this
????????this._router?=?this.$options.router
????????this._router.init(this)
????????//?變成響應(yīng)式
????????Vue.util.defineReactive(this,?'_route',?this._router.history.current)
??????}?else?{
????????//?非根組件訪問根組件通過$parent
????????this._routerRoot?=?(this.$parent?&&?this.$parent._routerRoot)?||?this
??????}
??????registerInstance(this,?this)
????},
????destroyed?()?{
??????registerInstance(this)
????}
??})
??//?原型加入?$router?和?$route
??Object.defineProperty(Vue.prototype,?'$router',?{
????get?()?{?return?this._routerRoot._router?}
??})
??Object.defineProperty(Vue.prototype,?'$route',?{
????get?()?{?return?this._routerRoot._route?}
??})
//?全局注冊
??Vue.component('RouterView',?View)
??Vue.component('RouterLink',?Link)
//?獲取合并策略
??const?strats?=?Vue.config.optionMergeStrategies
??//?use?the?same?hook?merging?strategy?for?route?hooks
??strats.beforeRouteEnter?=?strats.beforeRouteLeave?=?strats.beforeRouteUpdate?=?strats.created
}

可以看到這段代碼核心部分就是在執(zhí)行 install 方法時(shí)使用 mixin 的方式將每個(gè)組件都混入 beforeCreate,destroyed 這兩個(gè)生命周期鉤子。在 beforeCreate 函數(shù)中會(huì)去判斷當(dāng)前傳入的 router 實(shí)例是否是根組件,如果是,則將 _routerRoot 賦值為當(dāng)前組件實(shí)例、_router 賦值為傳入的VueRouter 實(shí)例對象,接著執(zhí)行 init 方法初始化 router,然后將 this_route 響應(yīng)式化。非根組件的話 _routerRoot 指向 $parent 父實(shí)例。然后執(zhí)行 registerInstance(this,this) 方法,該方法后會(huì),接著原型加入 $router 和 $route,最后注冊 RouterView 和 RouterLink,這就是整個(gè) install 的過程。

小結(jié)

Vue.use(plugin) 實(shí)際上在執(zhí)行 plugin上的 install 方法,insatll 方法有個(gè)重要的步驟:

  • 使用 mixin 在組件中混入 beforeCreate , destory 這倆個(gè)生命周期鉤子
  • 在 beforeCreate 這個(gè)鉤子進(jìn)行初始化。
  • 全局注冊 router-view,router-link組件

VueRouter

接著就是這個(gè)最重要的 class : VueRouter。這一部分代碼比較多,所以不一一列舉,挑重點(diǎn)分析。vueRouter源碼地址 (https://github.com/vuejs/vue-router/blob/v3.1.2/src/index.js)。

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

??constructor?(options:?RouterOptions?=?{})?{
????this.app??=?null
????this.apps?=?[]
????//?傳入的配置項(xiàng)
????this.options?=?options
????this.beforeHooks?=?[]
????this.resolveHooks?=?[]
????this.afterHooks?=?[]
????this.matcher?=?createMatcher(options.routes?||?[],?this)
????//?一般分兩種模式?hash?和?history?路由?第三種是抽象模式
????let?mode?=?options.mode?||?'hash'
????//?判斷當(dāng)前傳入的配置是否能使用?history?模式
????this.fallback?=?mode?===?'history'?&&?!supportsPushState?&&?options.fallback?!==?false
????//?降級(jí)處理
????if?(this.fallback)?{
??????mode?=?'hash'
????}
????if?(!inBrowser)?{
??????mode?=?'abstract'
????}
????this.mode?=?mode
????//?根據(jù)模式實(shí)例化不同的?history,history?對象會(huì)對路由進(jìn)行管理?繼承于history?class
????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}`)
????????}
????}
??}

首先在初始化 vueRouter 整個(gè)對象時(shí)定義了許多變量,app 代表 Vue 實(shí)例,options 代表傳入的配置參數(shù),然后就是路由攔截有用的 hooks 和重要的 matcher (后文會(huì)寫到)。構(gòu)造函數(shù)其實(shí)在做兩件事情: 1. 確定當(dāng)前路由使用的 mode;2. 實(shí)例化對應(yīng)的 history 對象。

init

接著完成實(shí)例化 vueRouter 之后,如果這個(gè)實(shí)例傳入后,也就是剛開始說的將 vueRouter 實(shí)例在初始化 Vue 時(shí)傳入,它會(huì)在執(zhí)行 beforeCreate 時(shí)執(zhí)行 init 方法

init?(app:?any)?{
??...
??this.apps.push(app)
??//?確保后面的邏輯只走一次
??if?(this.app)?{
????return
??}
??//?保存?Vue?實(shí)例
??this.app?=?app
??const?history?=?this.history
??//?拿到?history?實(shí)例之后,調(diào)用?transitionTo?進(jìn)行路由過渡
??if?(history?instanceof?HTML5History)?{
????history.transitionTo(history.getCurrentLocation())
??}?else?if?(history?instanceof?HashHistory)?{
????const?setupHashListener?=?()?=>?{
??????history.setupListeners()
????}
????history.transitionTo(
??????history.getCurrentLocation(),
??????setupHashListener,
??????setupHashListener
????)
??}
}

init 方法傳入 Vue 實(shí)例,保存到 this.apps 當(dāng)中。Vue實(shí)例 會(huì)取出當(dāng)前的 this.history,如果是哈希路由,先走 setupHashListener 函數(shù),然后調(diào)一個(gè)關(guān)鍵的函數(shù) transitionTo 路由過渡,這個(gè)函數(shù)其實(shí)調(diào)用了 this.matcher.match 去匹配。

小結(jié)

首先在 vueRouter 構(gòu)造函數(shù)執(zhí)行完會(huì)完成路由模式的選擇,生成 matcher ,然后初始化路由需要傳入 vueRouter 實(shí)例對象,在組件初始化階段執(zhí)行 beforeCreate 鉤子,調(diào)用 init 方法,接著拿到 this.history 去調(diào)用 transitionTo 進(jìn)行路由過渡。

Matcher

之前在 vueRouter 的構(gòu)造函數(shù)中初始化了 macther,本節(jié)將詳細(xì)分析下面這句代碼到底在做什么事情,以及 match 方法在做什么 源碼地址 (https://github.com/vuejs/vue-router/blob/dev/src/create-matcher.js)。

?this.matcher?=?createMatcher(options.routes?||?[],?this)

首先將代碼定位到create-matcher.js

export?function?createMatcher?(
??routes:?Array,
??router:?VueRouter):?Matcher?{
??//?創(chuàng)建映射表
??const?{?pathList,?pathMap,?nameMap?}?=?createRouteMap(routes)
??//?添加動(dòng)態(tài)路由
??function?addRoutes(routes){...}
??//?計(jì)算新路徑
??function?match?(
????raw:?RawLocation,
????currentRoute?:?Route,
????redirectedFrom?:?Location):?Route?{...}
??//?...?后面的一些方法暫不展開
??
???return?{
????match,
????addRoutes
??}
}

createMatcher 接受倆參數(shù),分別是 routes,這個(gè)就是我們平時(shí)在 router.js 定義的路由表配置,然后還有一個(gè)參數(shù)是 router 他是 new vueRouter 返回的實(shí)例。

createRouteMap

下面這句代碼是在創(chuàng)建一張 path-record,name-record 的映射表,我們將代碼定位到 create-route-map.js 源碼地址 (https://github.com/vuejs/vue-router/blob/dev/src/create-route-map.js)

export?function?createRouteMap?(
??routes:?Array,
??oldPathList?:?Array,
??oldPathMap?:?Dictionary,
??oldNameMap?:?Dictionary):?{
??pathList:?Array,pathMap:?Dictionary,nameMap:?Dictionary
}?{//?記錄所有的?pathconst?pathList:?Array?=?oldPathList?||?[]//?記錄?path-RouteRecord?的?Mapconst?pathMap:?Dictionary?=?oldPathMap?||?Object.create(null)//?記錄?name-RouteRecord?的?Mapconst?nameMap:?Dictionary?=?oldNameMap?||?Object.create(null)//?遍歷所有的?route?生成對應(yīng)映射表
??routes.forEach(route?=>?{
????addRouteRecord(pathList,?pathMap,?nameMap,?route)
??})//?調(diào)整優(yōu)先級(jí)for?(let?i?=?0,?l?=?pathList.length;?i?????if?(pathList[i]?===?'*')?{
??????pathList.push(pathList.splice(i,?1)[0])
??????l--
??????i--
????}
??}return?{
????pathList,
????pathMap,
????nameMap
??}
}

createRouteMap 需要傳入路由配置,支持傳入舊路徑數(shù)組和舊的 Map 這一步是為后面遞歸和 addRoutes 做好準(zhǔn)備。首先用三個(gè)變量記錄 path,pathMap,nameMap,接著我們來看 addRouteRecord 這個(gè)核心方法。這一塊代碼太多了,列舉幾個(gè)重要的步驟

//?解析路徑
const?pathToRegexpOptions:?PathToRegexpOptions?=
????route.pathToRegexpOptions?||?{}
//?拼接路徑
const?normalizedPath?=?normalizePath(path,?parent,?pathToRegexpOptions.strict)
//?記錄路由信息的關(guān)鍵對象,后續(xù)會(huì)依此建立映射表
const?record:?RouteRecord?=?{
??path:?normalizedPath,
??regex:?compileRouteRegex(normalizedPath,?pathToRegexpOptions),
??//?route?對應(yīng)的組件
??components:?route.components?||?{?default:?route.component?},
??//?組件實(shí)例
??instances:?{},
??name,
??parent,
??matchAs,
??redirect:?route.redirect,
??beforeEnter:?route.beforeEnter,
??meta:?route.meta?||?{},
??props:?route.props?==?null
??????{}
????:?route.components
????????route.props
??????:?{?default:?route.props?}
}

使用 recod 對象 記錄路由配置有利于后續(xù)路徑切換時(shí)計(jì)算出新路徑,這里的 path 其實(shí)是通過傳入父級(jí) record 對象的path和當(dāng)前 path 拼接出來的 ?。然后 regex 使用一個(gè)庫將 path 解析為正則表達(dá)式。如果 route 有子節(jié)點(diǎn)就遞歸調(diào)用 addRouteRecord

?//?如果有?children?遞歸調(diào)用?addRouteRecord
????route.children.forEach(child?=>?{
??????const?childMatchAs?=?matchAs
??????????cleanPath(`${matchAs}/${child.path}`)
????????:?undefined
??????addRouteRecord(pathList,?pathMap,?nameMap,?child,?record,?childMatchAs)
????})

最后映射兩張表,并將 record·path 保存進(jìn) pathList,nameMap 邏輯相似就不列舉了

??if?(!pathMap[record.path])?{
????pathList.push(record.path)
????pathMap[record.path]?=?record
??}

廢了這么大勁將 pathList 和 pathMap 和 nameMap 抽出來是為啥呢? 首先 pathList 是記錄路由配置所有的 path,然后 pathMap 和 nameMap 方便我們傳入 path 或者 name 快速定位到一個(gè) record,然后輔助后續(xù)路徑切換計(jì)算路由的。

addRoutes

這是在 vue2.2.0 之后新添加的 api ,或許很多情況路由并不是寫死的,需要?jiǎng)討B(tài)添加路由。有了前面的 createRouteMap 的基礎(chǔ)上我們只需要傳入 routes 即可,他就能在原基礎(chǔ)上修改

function?addRoutes?(routes)?{
??createRouteMap(routes,?pathList,?pathMap,?nameMap)
}

并且看到在 createMathcer 最后返回了這個(gè)方法,所以我們就可以使用這個(gè)方法

return?{
????match,
????addRoutes
??}

match

function?match?(
??raw:?RawLocation,
??currentRoute?:?Route,
??redirectedFrom?:?Location):?Route?{
??...
}

接下來就是 match 方法,它接收 3 個(gè)參數(shù),其中 raw 是 RawLocation 類型,它可以是一個(gè) url 字符串,也可以是一個(gè) Location 對象;currentRoute 是 Route 類型,它表示當(dāng)前的路徑;redirectedFrom 和重定向相關(guān)。match 方法返回的是一個(gè)路徑,它的作用是根據(jù)傳入的 raw 和當(dāng)前的路徑 currentRoute 計(jì)算出一個(gè)新的路徑并返回。至于他是如何計(jì)算出這條路徑的,可以詳細(xì)看一下如何計(jì)算出location的 normalizeLocation 方法和 _createRoute 方法。

小結(jié)

  • createMatcher: 根據(jù)路由的配置描述建立映射表,包括路徑、名稱到路由 record 的映射關(guān)系, 最重要的就是 createRouteMap 這個(gè)方法,這里也是動(dòng)態(tài)路由匹配和嵌套路由的原理。
  • addRoutes: 動(dòng)態(tài)添加路由配置
  • match: 根據(jù)傳入的 raw 和當(dāng)前的路徑 currentRoute 計(jì)算出一個(gè)新的路徑并返回。

路由模式

vue-router 支持三種路由模式(mode):hash、history、abstract,其中 abstract 是在非瀏覽器環(huán)境下使用的路由模式 源碼地址 (https://github.com/vuejs/vue-router/blob/dev/src/index.js)。

這一部分在前面初始化 vueRouter 對象時(shí)提到過,首先拿到配置項(xiàng)的模式,然后根據(jù)當(dāng)前傳入的配置判斷當(dāng)前瀏覽器是否支持這種模式,默認(rèn) IE9 以下會(huì)降級(jí)為 hash。然后根據(jù)不同的模式去初始化不同的 history 實(shí)例。

????//?一般分兩種模式?hash?和?history?路由?第三種是抽象模式不常用
????let?mode?=?options.mode?||?'hash'
????//?判斷當(dāng)前傳入的配置是否能使用?history?模式
????this.fallback?=?mode?===?'history'?&&?!supportsPushState?&&?options.fallback?!==?false
????//?降級(jí)處理
????if?(this.fallback)?{
??????mode?=?'hash'
????}
????if?(!inBrowser)?{
??????mode?=?'abstract'
????}
????this.mode?=?mode
????//?根據(jù)模式實(shí)例化不同的?history?history?對象會(huì)對路由進(jìn)行管理?繼承于?history?class
????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}`)
????????}
????}

小結(jié)

vue-router 支持三種路由模式,hash、history和?abstract。默認(rèn)為 hash,如果當(dāng)前瀏覽器不支持?history則會(huì)做降級(jí)處理,然后完成 history 的初始化。

路由切換

切換 url 主要是調(diào)用了 push 方法,下面以哈希模式為例,分析push方法實(shí)現(xiàn)的原理 。push 方法切換路由的實(shí)現(xiàn)原理 源碼地址 (https://github.com/vuejs/vue-router/blob/dev/src/history/hash.js)

首先在 src/index.js 下找到 vueRouter 定義的 push 方法

??push?(location:?RawLocation,?onComplete?:?Function,?onAbort?:?Function)?{
????//?$flow-disable-line
????if?(!onComplete?&&?!onAbort?&&?typeof?Promise?!==?'undefined')?{
??????return?new?Promise((resolve,?reject)?=>?{
????????this.history.push(location,?resolve,?reject)
??????})
????}?else?{
??????this.history.push(location,?onComplete,?onAbort)
????}
??}

接著我們需要定位到 history/hash.js。這里首先獲取到當(dāng)前路徑然后調(diào)用了 transitionTo 做路徑切換,在回調(diào)函數(shù)當(dāng)中執(zhí)行 pushHash 這個(gè)核心方法。

push?(location:?RawLocation,?onComplete?:?Function,?onAbort?:?Function)?{
????const?{?current:?fromRoute?}?=?this
????//?路徑切換的回調(diào)函數(shù)中調(diào)用?pushHash
????this.transitionTo(
??????location,
??????route?=>?{
????????pushHash(route.fullPath)
????????handleScroll(this.router,?route,?fromRoute,?false)
????????onComplete?&&?onComplete(route)
??????},
??????onAbort
????)
??}

而 pushHash 方法在做完瀏覽器兼容判斷后調(diào)用的 pushState 方法,將 url 傳入

export?function?pushState?(url?:?string,?replace?:?boolean)?{
??const?history?=?window.history
??try?{
???//?調(diào)用瀏覽器原生的?history?的?pushState?接口或者?replaceState?接口,pushState?方法會(huì)將?url?入棧
????if?(replace)?{
??????history.replaceState({?key:?_key?},?'',?url)
????}?else?{
??????_key?=?genKey()
??????history.pushState({?key:?_key?},?'',?url)
????}
??}?catch?(e)?{
????window.location[replace???'replace'?:?'assign'](url)
??}
}

可以發(fā)現(xiàn),push 底層調(diào)用了瀏覽器原生的 history 的 pushState 和 replaceState 方法,不是 replace 模式 會(huì)將 url 推歷史棧當(dāng)中。

另外提一嘴拼接哈希的原理

源碼位置 (https://github.com/vuejs/vue-router/blob/dev/src/history/hash.js)

初始化 HashHistory 時(shí),構(gòu)造函數(shù)會(huì)執(zhí)行 ensureSlash 這個(gè)方法

export?class?HashHistory?extends?History?{
??constructor?(router:?Router,?base:??string,?fallback:?boolean)?{
????...
????ensureSlash()
??}
??...
??}

這個(gè)方法首先調(diào)用 getHash,然后執(zhí)行 replaceHash()

function?ensureSlash?():?boolean?{
??const?path?=?getHash()
??if?(path.charAt(0)?===?'/')?{
????return?true
??}
??replaceHash('/'?+?path)
??return?false
}

下面是這幾個(gè)方法

export?function?getHash?():?string?{
??const?href?=?window.location.href
??const?index?=?href.indexOf('#')
??return?index?===?-1???''?:?href.slice(index?+?1)
}
//?真正拼接哈希的方法?
function?getUrl?(path)?{
??const?href?=?window.location.href
??const?i?=?href.indexOf('#')
??const?base?=?i?>=?0???href.slice(0,?i)?:?href
??return?`${base}#${path}`
}
function?replaceHash?(path)?{
??if?(supportsPushState)?{
????replaceState(getUrl(path))
??}?else?{
????window.location.replace(getUrl(path))
??}
}
export?function?replaceState?(url?:?string)?{
??pushState(url,?true)
}

舉個(gè)例子來說: 假設(shè)當(dāng)前URL是 http://localhost:8080,path 為空,執(zhí)行 replcaeHash('/' + path),然后內(nèi)部執(zhí)行 getUrl 計(jì)算出 url 為http://localhost:8080/#/,最后執(zhí)行 pushState(url,true),就大功告成了!

小結(jié)

hash 模式的 push 方法會(huì)調(diào)用路徑切換方法 transitionTo,接著在回調(diào)函數(shù)中調(diào)用pushHash方法,這個(gè)方法調(diào)用的 pushState 方法底層是調(diào)用了瀏覽器原生 history 的方法。push 和 replace 的區(qū)別就在于一個(gè)將 url 推入了歷史棧,一個(gè)沒有,最直觀的體現(xiàn)就是 replace 模式下瀏覽器點(diǎn)擊后退不會(huì)回到上一個(gè)路由去 ,另一個(gè)則可以。

router-view & router-link

vue-router 在 install 時(shí)全局注冊了兩個(gè)組件一個(gè)是 router-view 一個(gè)是 router-link,這兩個(gè)組件都是典型的函數(shù)式組件。源碼地址 (https://github.com/vuejs/vue-router/tree/dev/src/components)

router-view

首先在 router 組件執(zhí)行 beforeCreate 這個(gè)鉤子時(shí),把 this._route 轉(zhuǎn)為了響應(yīng)式的一個(gè)對象

?Vue.util.defineReactive(this,?'_route',?this._router.history.current)

所以說每次路由切換都會(huì)觸發(fā) router-view 重新 render 從而渲染出新的視圖。

核心的 render 函數(shù)作用請看代碼注釋

??render?(_,?{?props,?children,?parent,?data?})?{
????...
????//?通過?depth?由?router-view?組件向上遍歷直到根組件,遇到其他的?router-view?組件則路由深度+1?這里的?depth?最直接的作用就是幫助找到對應(yīng)的?record
????let?depth?=?0
????let?inactive?=?false
????while?(parent?&&?parent._routerRoot?!==?parent)?{
??????//?parent.$vnode.data.routerView?為?true?則代表向上尋找的組件也存在嵌套的?router-view?
??????if?(parent.$vnode?&&?parent.$vnode.data.routerView)?{
????????depth++
??????}
??????if?(parent._inactive)?{
????????inactive?=?true
??????}
??????parent?=?parent.$parent
????}
????data.routerViewDepth?=?depth
????if?(inactive)?{
??????return?h(cache[name],?data,?children)
????}
???//?通過?matched?記錄尋找出對應(yīng)的?RouteRecord?
????const?matched?=?route.matched[depth]
????if?(!matched)?{
??????cache[name]?=?null
??????return?h()
????}
?//?通過?RouteRecord?找到?component
????const?component?=?cache[name]?=?matched.components[name]
???//?往父組件注冊?registerRouteInstance?方法
????data.registerRouteInstance?=?(vm,?val)?=>?{?????
??????const?current?=?matched.instances[name]
??????if?(
????????(val?&&?current?!==?vm)?||
????????(!val?&&?current?===?vm)
??????)?{
????????matched.instances[name]?=?val
??????}
????}
??//?渲染組件
????return?h(component,?data,?children)
??}

觸發(fā)更新也就是 setter 的調(diào)用,位于 src/index.js,當(dāng)修改 _route 就會(huì)觸發(fā)更新。

history.listen(route?=>?{
??this.apps.forEach((app)?=>?{
????//?觸發(fā)?setter
????app._route?=?route
??})
})

router-link

分析幾個(gè)重要的部分:

  • 設(shè)置 active 路由樣式

router-link 之所以可以添加 router-link-active 和 router-link-exact-active 這兩個(gè) class 去修改樣式,是因?yàn)樵趫?zhí)行 render 函數(shù)時(shí),會(huì)根據(jù)當(dāng)前的路由狀態(tài),給渲染出來的 active 元素添加 class

render?(h:?Function)?{
??...
??const?globalActiveClass?=?router.options.linkActiveClass
??const?globalExactActiveClass?=?router.options.linkExactActiveClass
??//?Support?global?empty?active?class
??const?activeClassFallback?=?globalActiveClass?==?null
??????'router-link-active'
????:?globalActiveClass
??const?exactActiveClassFallback?=?globalExactActiveClass?==?null
??????'router-link-exact-active'
????:?globalExactActiveClass
????...
}
  • router-link 默認(rèn)渲染為 a 標(biāo)簽,如果不是會(huì)去向上查找出第一個(gè) a 標(biāo)簽
?if?(this.tag?===?'a')?{
??????data.on?=?on
??????data.attrs?=?{?href?}
????}?else?{
??????//?find?the?first??child?and?apply?listener?and?href
??????const?a?=?findAnchor(this.$slots.default)
??????if?(a)?{
????????//?in?case?the??is?a?static?node
????????a.isStatic?=?false
????????const?aData?=?(a.data?=?extend({},?a.data))
????????aData.on?=?on
????????const?aAttrs?=?(a.data.attrs?=?extend({},?a.data.attrs))
????????aAttrs.href?=?href
??????}?else?{
????????//?不存在則渲染本身元素
????????data.on?=?on
??????}
????}
  • 切換路由,觸發(fā)相應(yīng)事件
const?handler?=?e?=>?{
??if?(guardEvent(e))?{
????if?(this.replace)?{
??????//?replace路由
??????router.replace(location)
????}?else?{
??????//?push?路由
??????router.push(location)
????}
??}
}

權(quán)限控制動(dòng)態(tài)路由原理分析

我相信,開發(fā)過后臺(tái)項(xiàng)目的同學(xué)經(jīng)常會(huì)碰到以下的場景: 一個(gè)系統(tǒng)分為不同的角色,然后不同的角色對應(yīng)不同的操作菜單和操作權(quán)限。例如: 教師可以查詢教師自己的個(gè)人信息查詢?nèi)缓筮€可以查詢操作學(xué)生的信息和學(xué)生的成績系統(tǒng)、學(xué)生用戶只允許查詢個(gè)人成績和信息,不允許更改。在 vue2.2.0 之前還沒有加入 addRoutes 這個(gè) API 是十分困難的的。

目前主流的路由權(quán)限控制的方式是:

  • 登錄時(shí)獲取 token 保存到本地,接著前端會(huì)攜帶 token 再調(diào)用獲取用戶信息的接口獲取當(dāng)前用戶的角色信息。
  • 前端再根據(jù)當(dāng)前的角色計(jì)算出相應(yīng)的路由表拼接到常規(guī)路由表后面。
  • 登錄生成動(dòng)態(tài)路由全過程

    了解 如何控制動(dòng)態(tài)路由之后,下面是一張全過程流程圖

    前端在 beforeEach 中判斷:

    • 緩存中存在 JWT 令牌
      • 訪問/login: 重定向到首頁 /
      • 訪問/login以外的路由: ?首次訪問,獲取用戶角色信息,然后生成動(dòng)態(tài)路由,然后訪問以 replace 模式訪問 /xxx 路由。這種模式用戶在登錄之后不會(huì)在 history 存放記錄
    • 不存在 JWT 令牌
      • 路由在白名單中: 正常訪問 /xxx 路由
      • 不在白名單中: 重定向到 /login 頁面

    結(jié)合框架源碼分析

    下面結(jié)合 vue-element-admin 的源碼分析該框架中如何處理路由邏輯的。

    路由訪問邏輯分析

    首先可以定位到和入口文件 main.js 同級(jí)的 permission.js, 全局路由守衛(wèi)處理就在此。源碼地址 (https://github.com/251205668/student-admin-template/blob/master/src/permission.js)

    const?whiteList?=?['/login',?'/register']?//?路由白名單,不會(huì)重定向
    //?全局路由守衛(wèi)
    router.beforeEach(async(to,?from,?next)?=>?{
    ??NProgress.start()?//路由加載進(jìn)度條
    ??//?設(shè)置?meta?標(biāo)題
    ??document.title?=?getPageTitle(to.meta.title)
    ??//?判斷?token?是否存在
    ??const?hasToken?=?getToken()
    ??if?(hasToken)?{
    ????if?(to.path?===?'/login')?{
    ??????//?有?token?跳轉(zhuǎn)首頁
    ??????next({?path:?'/'?})
    ??????NProgress.done()
    ????}?else?{
    ??????const?hasRoles?=?store.getters.roles?&&?store.getters.roles.length?>?0
    ??????if?(hasRoles)?{
    ????????next()
    ??????}?else?{
    ????????try?{
    ??????????//?獲取動(dòng)態(tài)路由,添加到路由表中
    ??????????const?{?roles?}?=?await?store.dispatch('user/getInfo')
    ??????????const?accessRoutes?=?await?store.dispatch('permission/generateRoutes',?roles)
    ??????????router.addRoutes(accessRoutes)
    ??????????//??使用?replace?訪問路由,不會(huì)在?history?中留下記錄,登錄到?dashbord?時(shí)回退空白頁面
    ??????????next({?...to,?replace:?true?})
    ????????}?catch?(error)?{
    ??????????next('/login')
    ??????????NProgress.done()
    ????????}
    ??????}
    ????}
    ??}?else?{
    ????//?無?token
    ????//?白名單不用重定向?直接訪問
    ????if?(whiteList.indexOf(to.path)?!==?-1)?{
    ??????next()
    ????}?else?{
    ??????//?攜帶參數(shù)為重定向到前往的路徑
    ??????next(`/login?redirect=${to.path}`)
    ??????NProgress.done()
    ????}
    ??}
    })

    這里的代碼我都添加了注釋方便大家好去理解,總結(jié)為一句話就是訪問路由 /xxx,首先需要校驗(yàn) token 是否存在,如果有就判斷是否訪問的是登錄路由,走的不是登錄路由則需要判斷該用戶是否是第一訪問首頁,然后生成動(dòng)態(tài)路由,如果走的是登錄路由則直接定位到首頁,如果沒有 token 就去檢查路由是否在白名單(任何情況都能訪問的路由),在的話就訪問,否則重定向回登錄頁面。

    下面是經(jīng)過全局守衛(wèi)后路由變化的截圖

    結(jié)合Vuex生成動(dòng)態(tài)路由

    下面就是分析這一步 const accessRoutes = await store.dispatch('permission/generateRoutes', roles) 是怎么把路由生成出來的。源碼地址 (https://github.com/251205668/student-admin-template/blob/master/src/store/modules/permission.js)

    首先 vue-element-admin 中路由是分為兩種的:

    • constantRoutes: 不需要權(quán)限判斷的路由
    • asyncRoutes: 需要?jiǎng)討B(tài)判斷權(quán)限的路由
    //?無需校驗(yàn)身份路由
    export?const?constantRoutes?=?[
    ??{
    ????path:?'/login',
    ????component:?()?=>?import('@/views/login/index'),
    ????hidden:?true
    ??}
    ??...
    ??],
    ?//?需要校驗(yàn)身份路由?
    export?const?asyncRoutes?=?[
    ??//?學(xué)生角色路由
    ??{
    ????path:?'/student',
    ????name:?'student',
    ????component:?Layout,
    ????meta:?{?title:?'學(xué)生信息查詢',?icon:?'documentation',?roles:?['student']?},
    ????children:?[
    ??????{
    ????????path:?'info',
    ????????component:?()?=>?import('@/views/student/info'),
    ????????name:?'studentInfo',
    ????????meta:?{?title:?'信息查詢',?icon:?'form'?}
    ??????},
    ??????{
    ????????path:?'score',
    ????????component:?()?=>?import('@/views/student/score'),
    ????????name:?'studentScore',
    ????????meta:?{?title:?'成績查詢',?icon:?'score'?}
    ??????}
    ????]
    ??}]
    ??...

    生成動(dòng)態(tài)路由的源碼位于 src/store/modules/permission.js 中的 generateRoutes 方法,源碼如下:

    ?generateRoutes({?commit?},?roles)?{
    ????return?new?Promise(resolve?=>?{
    ??????let?accessedRoutes
    ??????if?(roles.includes('admin'))?{
    ????????accessedRoutes?=?asyncRoutes?||?[]
    ??????}?else?{
    ??????//?不是?admin?去遍歷生成對應(yīng)的權(quán)限路由表
    ????????accessedRoutes?=?filterAsyncRoutes(asyncRoutes,?roles)
    ??????}
    ??????//?vuex?中保存異步路由和常規(guī)路由
    ??????commit('SET_ROUTES',?accessedRoutes)
    ??????resolve(accessedRoutes)
    ????})
    ??}

    從 route.js 讀取 asyncRoutes 和 constantRoutes 之后首先判斷當(dāng)前角色是否是 admin,是的話默認(rèn)超級(jí)管理員能夠訪問所有的路由,當(dāng)然這里也可以自定義,否則去過濾出路由權(quán)限路由表,然后保存到 Vuex 中。最后將過濾之后的 asyncRoutes 和 constantRoutes 進(jìn)行合并。過濾權(quán)限路由的源碼如下:

    export?function?filterAsyncRoutes(routes,?roles)?{
    ??const?res?=?[]
    ??routes.forEach(route?=>?{
    ????//?淺拷貝
    ????const?tmp?=?{?...route?}
    ????//?過濾出權(quán)限路由
    ????if?(hasPermission(roles,?tmp))?{
    ??????if?(tmp.children)?{
    ????????tmp.children?=?filterAsyncRoutes(tmp.children,?roles)
    ??????}
    ??????res.push(tmp)
    ????}
    ??})
    ??return?res
    }

    首先定義一個(gè)空數(shù)組,對傳入 asyncRoutes 進(jìn)行遍歷,判斷每個(gè)路由是否具有權(quán)限,未命中的權(quán)限路由直接舍棄 判斷權(quán)限方法如下:

    function?hasPermission(roles,?route)?{
    ??if?(route.meta?&&?route.meta.roles)?{
    ????//?roles?有對應(yīng)路由元定義的?role?就返回?true
    ????return?roles.some(role?=>?route.meta.roles.includes(role))
    ??}?else?{
    ????return?true
    ??}
    }

    接著需要判斷二級(jí)路由、三級(jí)路由等等的情況,再做一層迭代處理,最后將過濾出來的路由推進(jìn)數(shù)組返回。然后追加到 constantRoutes 后面

    ?SET_ROUTES:?(state,?routes)?=>?{
    ????state.addRoutes?=?routes
    ????state.routes?=?constantRoutes.concat(routes)
    ??}

    動(dòng)態(tài)路由生成全過程

    總結(jié)

    • vue-router 源碼分析部分

      • 注冊: 執(zhí)行 install 方法,注入生命周期鉤子初始化
      • vueRouter: 當(dāng)組件執(zhí)行 beforeCreate 傳入 router 實(shí)例時(shí),執(zhí)行 init 函數(shù),然后執(zhí)行 history.transitionTo 路由過渡
      • matcher : 根據(jù)傳入的 routes 配置創(chuàng)建對應(yīng)的 pathMap 和 nameMap ,可以根據(jù)傳入的位置和路徑計(jì)算出新的位置并匹配對應(yīng)的 record
      • 路由模式: 路由模式在初始化 vueRouter 時(shí)完成匹配,如果瀏覽器不支持則會(huì)降級(jí)
      • 路由 切換: 哈希模式下底層使用了瀏覽器原生的 pushState 和 replaceState 方法
      • router-view: 調(diào)用父組件上存儲(chǔ)的 $route.match 控制路由對應(yīng)的組件的渲染情況,并且支持嵌套。
      • router-link: 通過 to 來決定點(diǎn)擊事件跳轉(zhuǎn)的目標(biāo)路由組件,并且支持渲染成不同的 tag,還可以修改激活路由的樣式。
    • 權(quán)限控制動(dòng)態(tài)路由部分

      • 路由邏輯: 全局路由攔截,從緩存中獲取令牌,存在的話如果首次進(jìn)入路由需要獲取用戶信息,生成動(dòng)態(tài)路由,這里需要處理 /login 特殊情況,不存在則判斷白名單然后走對應(yīng)的邏輯
      • 動(dòng)態(tài)生成路由: 傳入需要 router.js 定義的兩種路由。判斷當(dāng)前身份是否是管理員,是則直接拼接,否則需要過濾出具備權(quán)限的路由,最后拼接到常規(guī)路由后面,通過 addRoutes 追加。

    讀后感想

    或許閱讀源碼的作用不能像一篇開發(fā)文檔一樣直接立馬對日常開發(fā)有所幫助,但是它的影響是長遠(yuǎn)的,在讀源碼的過程中都可以學(xué)到眾多知識(shí),類似閉包、設(shè)計(jì)模式、時(shí)間循環(huán)、回調(diào)等等 JS 進(jìn)階技能,并穩(wěn)固并提升了你的 JS 基礎(chǔ)。當(dāng)然這篇文章是有缺陷的,有幾個(gè)地方都沒有分析到,比如導(dǎo)航守衛(wèi)實(shí)現(xiàn)原理和路由懶加載實(shí)現(xiàn)原理,這一部分,我還在摸索當(dāng)中。

    如果一味的死記硬背一些所謂的面經(jīng),或者直接死記硬背相關(guān)的框架行為或者 API ,你很難在遇到比較復(fù)雜的問題下面去快速定位問題,了解怎么去解決問題,而且我發(fā)現(xiàn)很多人在使用一個(gè)新框架之后遇到點(diǎn)問題都會(huì)立馬去提對應(yīng)的 Issues,以至于很多流行框架 Issues 超過幾百個(gè)或者幾千個(gè),但是許多問題都是因?yàn)槲覀儾⑽窗凑赵O(shè)計(jì)者開發(fā)初設(shè)定的方向才導(dǎo)致錯(cuò)誤的,更多都是些粗心大意造成的問題。

    參考文章

    帶你全面分析 vue-router 源碼 (萬字長文) (https://juejin.im/post/6844904064367460366)

    vuejs 源碼解析 (https://github.com/answershuto/learnVue)

    近期1024程序員們過節(jié),他們都在干這件事....面試官:聊聊對Vue.js框架的理解若此文有用,何不素質(zhì)三連?? 創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)

    總結(jié)

    以上是生活随笔為你收集整理的element label动态赋值_浅析 vuerouter 源码和动态路由权限分配的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

    日本韩国精品在线 | 国产精品久久久久久久久久久久午 | 国产成人av网址 | 激情综合啪 | 国产精品久久久一区二区三区网站 | 国产一区二区中文字幕 | 91麻豆精品| 亚洲免费观看在线视频 | 在线观看久久久久久 | 日韩美精品视频 | 午夜av在线电影 | 国产精品18久久久久久vr | 日韩免费播放 | 亚洲国产剧情 | 亚洲精品美女在线观看播放 | 久久久久久久久久久成人 | 国产精品岛国久久久久久久久红粉 | 国产成人免费在线观看 | 99精品在这里 | 91精品1区| 99精品美女 | aav在线 | 国产免费三级在线观看 | 日韩电影在线看 | 国产精品大片在线观看 | 97国产在线观看 | 国产一区免费视频 | 一级黄视频 | 91av在线电影 | 在线免费观看成人 | 精品国自产在线观看 | www.色五月| 蜜臀av在线一区二区三区 | 国内外成人在线 | 久久伊人色综合 | 黄网站免费久久 | 免费精品久久久 | 狠狠躁日日躁狂躁夜夜躁av | 91免费看片黄 | 国产不卡免费视频 | 亚洲高清视频在线观看免费 | 久久久精品久久 | aaa毛片视频 | 成人午夜精品福利免费 | 国产99久久久精品视频 | 色鬼综合网 | 欧美一二三区在线观看 | 天天干天天操天天做 | 亚洲精品资源 | 亚洲一区日韩在线 | 久久综合九色99 | 亚洲在线网址 | 亚州精品天堂中文字幕 | 77国产精品 | 天天艹天天操 | 国精产品999国精产品视频 | 在线电影a | 国产日韩欧美在线观看视频 | 在线观看视频中文字幕 | 狠狠狠狠狠狠 | 国产精品亚 | 成人va天堂 | www99久久 | 日韩在线不卡av | 视频在线国产 | 91禁在线观看 | 精品久久九九 | 激情五月综合网 | ww亚洲ww亚在线观看 | 色播五月激情综合网 | 国产亚洲精品久久久久久久久久 | 亚洲经典视频 | 久久久久久久av麻豆果冻 | 九九热国产| 99久久精品免费看国产免费软件 | 天天操狠狠干 | 超碰在线色 | 欧美午夜a | 婷婷五月在线视频 | 四虎成人精品永久免费av九九 | 国产精品都在这里 | 天天狠狠干 | 欧美aⅴ在线观看 | 中文字幕在线看视频 | 久久激情五月丁香伊人 | 最新精品视频在线 | 国产精品精品久久久久久 | 成人综合日日夜夜 | 国产一区二区精品久久 | 日韩精品最新在线观看 | 天天摸夜夜操 | 天天摸日日操 | 九九久久影视 | 成人av高清在线 | 999久久久久久久久久久 | 久久综合综合久久综合 | 天天射天天干天天操 | 免费在线观看视频a | 久久综合毛片 | 色哟哟国产精品 | 精品国产免费人成在线观看 | 97精品国产| 天天射天天艹 | 欧美尹人 | 一级做a爱片性色毛片www | 免费看的黄网站软件 | 成人午夜电影网站 | 精品国产精品国产偷麻豆 | 久久手机免费视频 | 欧美日韩在线观看一区二区三区 | 五月丁香 | 日本不卡一区二区 | av免费线看 | 91成品人影院 | 国产永久网站 | 久久国产精品久久久 | 黄色小说视频在线 | 中文网丁香综合网 | 久久久国产精品亚洲一区 | 国产丝袜在线 | 亚洲视频精品在线 | 最新国产精品亚洲 | 一级黄色片网站 | 91自拍成人| 美女国产精品 | 中文字幕一区二区三区四区 | 波多野结衣在线观看一区二区三区 | 97超碰成人在线 | 欧美污在线观看 | 久久99婷婷 | av中文字幕在线免费观看 | 国产精品入口久久 | 欧美日韩69 | 亚洲一区二区三区四区精品 | 这里有精品在线视频 | 一区二区电影在线观看 | 人人爽人人爽人人片 | www.五月天| 中文理论片 | 不卡的av电影在线观看 | 91视频亚洲 | 日韩在线观看视频中文字幕 | 亚洲国产精品500在线观看 | 97干com| 国产手机av在线 | 久久69精品 | 97视频免费观看2区 亚洲视屏 | 久久久精品国产一区二区 | 中文字幕免费高清在线 | 久久精品99精品国产香蕉 | 欧美久久久久久久久久久久 | 欧美激情va永久在线播放 | 日韩免费在线视频观看 | 婷婷色婷婷 | 免费看av片网站 | 高清不卡毛片 | 精品视频免费久久久看 | 97在线播放 | 成人av电影网址 | 亚洲日本国产 | 91探花国产综合在线精品 | 欧美一区免费观看 | 亚洲国产中文在线观看 | 国产欧美精品一区二区三区四区 | 免费看片成人 | 亚洲爱视频 | 久久伊人婷婷 | 国产精品久久久久婷婷二区次 | 国产一区二区观看 | 伊人伊成久久人综合网小说 | 国内精品久久久精品电影院 | 国产精品免费人成网站 | 午夜.dj高清免费观看视频 | av免费网站观看 | 免费观看的av网站 | 99r在线精品 | 中文字幕在线观看国产 | 精品播放 | 亚洲91精品在线观看 | 欧美日韩激情视频8区 | 四虎8848免费高清在线观看 | 99视频这里有精品 | 色瓜| 日韩a欧美 | 欧美日韩国产一二 | 狠狠色丁香婷婷综合视频 | www日日夜夜| 国产91免费在线观看 | 日韩在线第一 | 国产一区免费在线观看 | 狠狠干婷婷 | 成人黄在线观看 | 国产香蕉97碰碰碰视频在线观看 | 日韩一区二区三区免费视频 | 国产福利91精品张津瑜 | 免费a视频在线 | 午夜精品视频在线 | 中文字幕一区在线观看视频 | 爱情影院aqdy鲁丝片二区 | 九九在线视频免费观看 | 777xxx欧美| 草久久影院 | 一区二区三区日韩在线观看 | 97久久精品午夜一区二区 | 久久免费视频一区 | 国产高h视频 | 日本中文字幕网站 | 久久在现| 中文字幕观看视频 | 国产精品精品 | 国产视频在线一区二区 | 国产毛片久久 | 欧美成人h版| 毛片无卡免费无播放器 | 国产亚洲视频系列 | 国产午夜亚洲精品 | 国产一卡久久电影永久 | 99久久综合狠狠综合久久 | 欧美精品一区在线发布 | 97精产国品一二三产区在线 | 国产乱码精品一区二区蜜臀 | 日韩专区一区二区 | 成人免费看视频 | 蜜臀一区二区三区精品免费视频 | 欧美日韩在线视频一区二区 | 久久综合在线 | 亚洲午夜精品久久久久久久久 | 久久免费黄色 | 精品国产乱码久久久久 | 99r精品视频在线观看 | 日韩av手机在线观看 | 国产成人免费高清 | 久久国产网| 激情视频一区 | 免费看污污视频的网站 | 中文字幕免费一区二区 | 亚洲 欧美 另类人妖 | 又黄又爽又无遮挡的视频 | 国产精品va视频 | 亚洲成人麻豆 | 亚洲四虎在线 | 久草在线视频网 | 天天操人 | 久久国产热 | 亚洲精品美女在线观看播放 | 中文字幕日韩精品有码视频 | 国产很黄很色的视频 | 91福利社在线观看 | 亚洲国产999 | 国产韩国精品一区二区三区 | 欧美激情视频在线免费观看 | 亚洲第一伊人 | 欧美一级黄色片 | 天天操天天干天天爱 | 精品婷婷 | 国产精品久久久一区二区 | 日韩精品无码一区二区三区 | 一二三精品视频 | 在线观看免费一级片 | 亚洲免费精品一区二区 | 国产一区二区三区高清播放 | 天天天干天天天操 | 青青五月天| 一区二区三区在线看 | 久久人人97超碰国产公开结果 | 久久国产精品第一页 | 天天色天天射天天综合网 | 一区二区不卡高清 | 欧美精品久久人人躁人人爽 | 亚洲精品字幕在线观看 | 免费一级片观看 | 狠狠五月天| 香蕉视频在线网站 | 国产精品毛片一区二区 | 狠狠狠狠狠狠狠 | 国产免费xvideos视频入口 | av在线精品| 午夜狠狠操 | 国产精品毛片一区二区三区 | 在线欧美小视频 | 免费色视频在线 | 婷婷丁香狠狠爱 | 久久字幕 | 这里只有精品视频在线 | 欧美最猛性xxxxx(亚洲精品) | 国产原创中文在线 | 免费在线观看黄 | 亚洲www天堂com| 国产又粗又猛又黄视频 | www五月婷婷 | 一区二区激情视频 | 成人午夜在线观看 | 9色在线视频 | 视频在线一区二区三区 | 一区二区不卡高清 | 亚洲综合婷婷 | 成人一区二区三区在线观看 | 制服丝袜一区二区 | 超碰资源在线 | 99国产免费网址 | 综合激情久久 | 中文字幕韩在线第一页 | 欧美日韩中文在线 | 在线观看 国产 | 一区二区三区手机在线观看 | 色综合久久88色综合天天免费 | 国产精品久久一区二区无卡 | 色网免费观看 | 麻豆传媒视频观看 | 国产黄大片 | 97超碰福利久久精品 | 天天射射天天 | 五月天久久久 | 免费日韩一区二区三区 | 中文字幕一区在线 | 欧美日韩在线精品 | 成人毛片a | 五月的婷婷 | 狠狠艹夜夜干 | 成人免费在线播放 | 久久久亚洲精华液 | 日本护士三级少妇三级999 | 中文字幕黄色网 | 女人18片 | 久久黄色小说视频 | 四虎影视成人精品国库在线观看 | 国产精品久久久久久久久久 | 欧美永久视频 | 色视频在线看 | 亚洲成人资源在线观看 | 欧美一级黄色视屏 | 天天干天天天天 | 成人精品一区二区三区电影免费 | 天天曰夜夜爽 | 国产成人无码AⅤ片在线观 日韩av不卡在线 | 国产精品黑丝在线观看 | 91亚洲欧美 | av成人在线播放 | 欧美日本在线视频 | 免费黄色在线播放 | 精品一区二区日韩 | 国产精品av免费 | 天天操天天操一操 | 五月婷婷,六月丁香 | 日韩a级免费视频 | 波多野结衣久久资源 | 久久久久久久久久久久久国产精品 | 久久精品久久精品久久39 | www免费网站在线观看 | 五月婷婷综合网 | 在线观看色视频 | 婷婷在线观看视频 | 久久69av | 亚洲va欧洲va国产va不卡 | 久久少妇av| 久久99精品久久久久久三级 | 国产亚洲欧洲 | 免费观看av网站 | 久久高清免费观看 | 在线观看中文字幕网站 | 国产专区视频在线观看 | 国产亚洲激情视频在线 | 久操伊人 | 四虎免费在线观看视频 | 国产免费成人av | 超碰九九| 69国产精品视频 | 手机成人免费视频 | 欧美特一级片 | 欧美午夜性生活 | 99精品区| 久久久久免费网站 | 久久久久久久99 | 国产五月婷 | 色婷婷激情四射 | 亚洲欧美婷婷六月色综合 | 久久99久久久久 | 奇米影视四色8888 | 久久久久久久久久免费 | 亚洲国产美女久久久久 | 黄色成人在线网站 | 久久久 激情 | 亚洲一区精品二人人爽久久 | 在线视频专区 | 国产精品毛片久久久 | 国产999精品久久久影片官网 | 国产精选视频 | 一区二区三区免费在线 | 成人国产在线 | 91中文字幕在线视频 | 欧美日韩国语 | 综合色天天 | 国产二区精品 | 亚洲午夜久久久久久久久电影网 | 欧美日韩国产精品久久 | 欧美日韩久久不卡 | 国产98色在线 | 日韩 | 91精品久久久久久久久久入口 | 国产精品久久久久久久久大全 | 人人草在线视频 | 最近日韩中文字幕中文 | 色播六月天| 四虎国产 | 日日操网站 | 97在线视频免费 | 久久久久一区 | 亚洲欧洲国产日韩精品 | 九九久久精品 | 色噜噜色噜噜 | 成人午夜精品福利免费 | 欧美一二三在线 | 日韩av图片| 超碰人人在线 | 亚洲一区在线看 | 97人人射 | 在线有码中文 | 久久成人国产精品一区二区 | 99热999 | 国产午夜精品久久 | 免费久草视频 | 中文字幕在线日亚洲9 | 中日韩在线视频 | av黄色亚洲| 最近日本mv字幕免费观看 | 国产精品午夜久久 | 看国产黄色片 | 成人av免费播放 | 伊人成人激情 | 黄色影院在线免费观看 | 色偷偷网站视频 | av免费播放| 久久视频在线免费观看 | 99精品欧美一区二区三区黑人哦 | 色吊丝在线永久观看最新版本 | 色婷婷a | 99久久婷婷国产一区二区三区 | 国产精品久久久久久a | 国产在线a视频 | 最新国产福利 | 狠狠搞,com | 欧美黄在线| 日韩深夜在线观看 | 欧美另类69| 99久久久国产免费 | 国产精品久久婷婷六月丁香 | 中文字幕久久精品亚洲乱码 | 国产精品久久久久久久电影 | 97福利| 国产成人精品一区二区三区福利 | 亚洲欧美日韩精品久久奇米一区 | 日韩免费不卡视频 | 欧美日韩亚洲第一页 | 久草av在线播放 | 狠狠干狠狠艹 | 久久久久久久久免费视频 | 国产在线观看黄 | 视频在线观看99 | 91污在线观看 | 日本黄色免费网站 | 亚洲国产欧洲综合997久久, | 草久电影 | 日韩在线视频观看 | 久久人人精| 性色av免费看 | 国精产品满18岁在线 | 97精品国产| 99视频在线精品免费观看2 | 在线影院av | 中文字幕国产一区二区 | 六月丁香综合网 | 亚洲精品视频在线 | 私人av| 亚洲精品视频在线观看视频 | 久久免费视频这里只有精品 | 973理论片235影院9 | 黄色最新网址 | 亚洲国产小视频在线观看 | 最近高清中文字幕 | 中文国产成人精品久久一 | 国产精品成人自产拍在线观看 | www.成人久久 | 久久兔费看a级 | 亚洲极色 | 精品久久综合 | 国产一级在线看 | 亚洲免费激情 | 国产精品第7页 | 色资源在线 | 日韩精品欧美一区 | 久久久久久久久久久久久久电影 | av电影免费在线看 | 2023亚洲精品国偷拍自产在线 | 国产精品成人免费一区久久羞羞 | 日韩免费在线网站 | 在线观看av网 | 五月激情av | 国产69久久久 | 色小说在线| 久久久久国产精品一区二区 | 日韩免费一区二区三区 | 91污污视频在线观看 | 就要色综合 | 亚洲资源网| 免费在线激情电影 | 天天爱天天操天天干 | 欧美在线观看视频一区二区 | 国产精品观看在线亚洲人成网 | 国产成人精品在线播放 | 美女久久久 | 天天激情综合 | 亚洲国产精品激情在线观看 | 99久久99久久综合 | 亚洲天堂va| 日韩色爱 | 最近高清中文字幕 | 国内视频1区 | 99精品在线观看 | 九九精品无码 | av在线等| 91视频这里只有精品 | 在线观看aaa | 99视频精品免费观看, | 97品白浆高清久久久久久 | 又黄又刺激视频 | 日韩欧美精品一区二区三区经典 | 麻豆传媒电影在线观看 | 免费观看www小视频的软件 | 久久久久国产精品一区二区 | 人人爽人人爽人人片av免 | 久久精品看 | 制服丝袜在线91 | 国产精品 999| 99精品视频播放 | 欧美一级免费 | www.久久久.cum | www.黄色 | 狠狠干婷婷 | 日韩精品一区二区三区在线视频 | 午夜精品久久久久久久爽 | 黄色免费视频在线观看 | 久久草在线精品 | 亚洲va男人天堂 | 欧美人人爱 | 久久a v电影 | 亚洲精品乱码白浆高清久久久久久 | av在线影片 | 激情图片qvod | 综合精品久久久 | 亚洲欧洲精品一区 | www久久久| 91精品久久久久久久久久久久久 | 久久中文网 | 色在线中文字幕 | 中文字幕在线字幕中文 | 黄色特一级 | 激情久久一区二区三区 | 婷婷激情综合五月天 | 免费成人在线观看视频 | 日本少妇高清做爰视频 | 狠狠躁夜夜躁人人爽超碰97香蕉 | 日韩欧美网址 | 久99久在线 | 欧美少妇影院 | 婷婷爱五月天 | 亚洲国产操 | 91中文字幕在线 | 久久 国产一区 | www.国产高清 | 国产精品18久久久久久首页狼 | 狠狠干天天 | 亚洲男女精品 | 在线观看免费福利 | 在线导航av | 日韩在线免费 | 久久精品com | 中文字幕 婷婷 | 一区二区三区在线观看免费视频 | 激情久久婷婷 | 亚洲最大av在线播放 | 青青河边草观看完整版高清 | 日韩欧美在线视频一区二区 | 激情在线网 | 亚洲精品视频在线观看免费视频 | 香蕉视频色| 中文字幕国语官网在线视频 | 日韩99热| 91在线看片| 在线播放日韩av | 丁香六月中文字幕 | 国产极品尤物在线 | 国产一级性生活 | 一级片观看 | 91香蕉久久 | 欧美精品免费在线 | 狂野欧美激情性xxxx | 国产精品美 | 亚洲老妇xxxxxx | 手机看国产毛片 | 久久久久久久久毛片 | 黄色在线观看免费网站 | 97视频免费看 | 久久爱992xxoo| 91精品夜夜 | 亚洲精品高清视频 | 看片在线亚洲 | 91高清在线 | 欧美一二三区在线播放 | 青青草华人在线视频 | 成片免费观看视频 | 人人搞人人爽 | 亚洲精品午夜aaa久久久 | avav片 | 亚洲国产精品人久久电影 | 久久免费高清视频 | 永久免费看av | 日韩簧片在线观看 | 久久久91精品国产一区二区三区 | 亚洲国产精品久久久久 | 亚洲国产999 | 久草在线在线 | 在线草| 欧美成人精品欧美一级乱 | 一区中文字幕在线观看 | 亚洲永久字幕 | 久久综合丁香 | 日韩欧美一区二区三区在线 | 五月婷婷一区二区三区 | 999抗病毒口服液 | 成人av免费播放 | 欧美精品v国产精品v日韩精品 | 成人黄色大片在线观看 | 免费观看91视频 | av片免费播放| 91资源在线视频 | 亚洲欧美日韩在线看 | 国产一区二区网址 | 国产你懂的在线 | 国产香蕉97碰碰久久人人 | 天天操天天射天天舔 | a级国产乱理伦片在线播放 久久久久国产精品一区 | 五月婷婷一区二区三区 | 久久国产精品色av免费看 | 亚洲成人欧美 | 欧美日本三级 | 亚洲首页 | 国产精品女 | 亚洲精品国产精品久久99热 | 国产福利在线不卡 | 亚洲精品字幕 | 天天干天天插 | 欧美日一级片 | 国内综合精品午夜久久资源 | 久久a热6 | 色综合 久久精品 | 丁香六月在线观看 | 天天操天天色天天 | 人人澡视频 | 亚洲黄色片在线 | 在线免费性生活片 | 国产91精品看黄网站在线观看动漫 | 黄色在线观看免费网站 | 中文字幕亚洲综合久久五月天色无吗'' | 一二区av | 成人一级片免费看 | 亚洲国产精品成人综合 | 午夜在线免费观看视频 | 亚洲欧美成aⅴ人在线观看 四虎在线观看 | 奇米影视999 | 天天综合天天综合 | 婷婷在线观看视频 | 99久久精品无码一区二区毛片 | 三上悠亚一区二区在线观看 | 女人久久久久 | 成年人av在线播放 | 日韩一区二区三区在线观看 | 久久精品爱爱视频 | 91视频xxxx| 中日韩在线视频 | 久久99亚洲网美利坚合众国 | 97色噜噜| 天天草天天干天天 | 婷婷六月色 | 日本mv大片欧洲mv大片 | 在线a视频免费观看 | 久久久免费播放 | 亚洲天天综合网 | 国产一级在线 | 四虎在线观看 | 久久夜色精品亚洲噜噜国4 午夜视频在线观看欧美 | 亚洲精品国产精品国 | 91片网 | 午夜999| 免费精品视频在线 | 日韩精品一区二区三区水蜜桃 | www.com.日本一级 | 精品成人国产 | 国产不卡精品 | 2023av在线 | 欧美日韩中文在线 | 中文字幕一区二区三区四区久久 | 亚洲成人高清在线 | 欧美日产一区 | av成人免费在线观看 | 国产亚洲高清视频 | 99久久精品免费看国产免费软件 | 在线看小早川怜子av | 黄色国产区| 午夜久久久久久久久久影院 | 国产一级视频免费看 | 国产五月天婷婷 | 午夜久久久久 | 欧洲激情综合 | 欧美另类v| 久久新视频 | 美女网站免费福利视频 | 日韩天堂网 | 日韩精品国产一区 | 免费av成人在线 | 91精品办公室少妇高潮对白 | 色婷婷激情电影 | 激情综合五月网 | 天天操天天摸天天爽 | 国产精品国产亚洲精品看不卡 | 在线观看视频一区二区三区 | 深爱五月网 | 亚洲精品视频免费在线 | 国产精品 日韩 欧美 | 国产成人精品综合久久久久99 | 狠狠色丁香婷婷综合 | 久久久久久久久电影 | 玖玖玖在线| 麻豆传媒在线视频 | 日韩资源在线播放 | 中文字幕免费高清 | 黄色在线免费观看网址 | 98精品国产自产在线观看 | www婷婷| 日韩欧美视频在线免费观看 | 亚洲自拍自偷 | 亚洲精品乱码久久久久久久久久 | 天天操天天射天天插 | 日韩天天综合 | 婷婷丁香激情 | 伊人中文网 | 亚洲欧美国内爽妇网 | 麻豆免费看片 | 天天操天天综合网 | 91在线日本 | 精品国产一二三四区 | 欧美最猛性xxxx | 午夜精品久久久久久久99 | 伊人色综合网 | 免费观看www视频 | 成人av播放 | 丁香婷婷色综合亚洲电影 | 在线免费观看视频 | 成人av亚洲| 成人av免费在线播放 | 天堂av在线7 | 日韩在线色| 91亚色免费视频 | 波多野结衣在线视频免费观看 | 久久99视频精品 | 日韩大片在线 | 久久电影色 | 欧美日韩啪啪 | 久久久久久久久久久国产精品 | 国产露脸91国语对白 | 韩国精品一区二区三区六区色诱 | 天天射天天干 | 91av视频在线观看免费 | 99视频在线观看视频 | 97日日碰人人模人人澡分享吧 | 一级精品视频在线观看宜春院 | 色狠狠操 | 欧美日韩精品免费观看 | 色99色| 日韩精品在线看 | 欧美乱大交 | 欧美日韩精品影院 | 欧美精品成人在线 | 久久国产成人午夜av影院潦草 | 国色综合 | 欧美日韩一区三区 | 免费看一级黄色大全 | 99久久er热在这里只有精品15 | 欧美一区二区三区免费观看 | 狠狠色丁香婷婷综合久小说久 | 亚洲国产偷 | 日色在线视频 | 亚洲免费av在线 | 精品国产视频在线观看 | a午夜在线| 激情五月激情综合网 | 亚洲国产精品va在线看 | 人人爱人人爽 | 亚洲国产成人高清精品 | 国产五码一区 | 成人h视频 | 国产精品久久久久久久久久免费 | wwwwww黄 | 天天想夜夜操 | 亚洲精品国产精品乱码在线观看 | 日韩理论影院 | 日本最新一区二区三区 | 91亚洲国产 | 一区二区三区 亚洲 | 久久久91精品国产一区二区精品 | 成人午夜电影在线播放 | 国产又粗又长又硬免费视频 | 欧美亚洲一级片 | 最新国产精品久久精品 | 99热最新| 二区三区在线 | 成人网大片| 国产精品a成v人在线播放 | 9999在线观看 | 亚洲精品在线国产 | 成人av影院在线观看 | 91精彩视频在线观看 | 日本mv大片欧洲mv大片 | 中文字幕在线观看你懂的 | 婷婷国产v亚洲v欧美久久 | av一级片 | 国产手机精品视频 | 夜夜爽www | 亚洲高清91| 色久五月| 久久se视频 | 免费日韩一区 | 成人一级影视 | 热久久在线视频 | 黄色av成人在线 | 97国产小视频 | 狠狠干天天操 | 日日干天天插 | 精品v亚洲v欧美v高清v | 国产一级精品在线观看 | 99精品视频在线 | 国产精品久免费的黄网站 | 久久论理 | 久久精品国产成人精品 | 又湿又紧又大又爽a视频国产 | 高清久久久久久 | 激情综合网五月 | 91 在线视频播放 | 韩国一区二区av | 亚洲黄色影院 | 日本三级在线观看中文字 | 日韩国产精品毛片 | 一区二区三区在线不卡 | 精品国产人成亚洲区 | 99精品免费久久久久久日本 | 国产精品久久久一区二区三区网站 | 免费在线观看黄色网 | 天天射天天干天天插 | 亚洲在线视频播放 | 狠狠操综合 | 国产免费不卡av | 欧美日韩免费观看一区=区三区 | 天天搞天天干天天色 | 91.麻豆视频 | 中文字幕一区在线 | 国内视频一区二区 | 成人国产精品入口 | 国产成人精品av久久 | 亚洲精品资源 | 国产日韩欧美在线 | 国产黄色精品在线观看 | 中文字幕色网站 | 色综合久久五月天 | 久久www免费人成看片高清 | 丁香午夜 | 日韩黄色在线电影 | 日韩伦理一区二区三区av在线 | 亚洲国产高清在线观看视频 | 手机av在线网站 | 国产成人精品久久久久蜜臀 | 亚洲亚洲精品在线观看 | 久久久999| 美女黄视频免费 | 成人综合婷婷国产精品久久免费 | 日韩深夜在线观看 | 最近日本韩国中文字幕 | 亚洲最新av网站 | 婷婷网在线 | 青春草免费在线视频 | 国产丝袜制服在线 | 99精品视频观看 | 激情五月激情综合网 | 久久久亚洲国产精品麻豆综合天堂 | 国产精品久久久久久一区二区三区 | 国产一级一片免费播放放a 一区二区三区国产欧美 | 亚洲波多野结衣 | 国产色视频网站2 | 啪啪午夜免费 | 免费看片网页 | 国产午夜三级一区二区三 | 欧美做受xxx | 国产69精品久久久久久 | 日韩免费精品 | 一本一本久久a久久精品牛牛影视 | 99精品视频在线观看视频 | 99精品偷拍视频一区二区三区 | 精品久久五月天 | 99在线视频精品 | 一区二区理论片 | 久久都是精品 | 爱色av.com | 国产精品www | 久久亚洲美女 | 果冻av在线 | 久草在线免费资源站 | 射久久 | 久久99久久99精品 | 亚洲免费资源 | 玖玖精品在线 | 久草视频在线资源站 | 99久久久久久国产精品 | 麻豆视频成人 | 婷婷色综合色 | 又爽又黄又刺激的视频 | 精品久久1 | 日韩精品视频免费看 | 免费观看十分钟 | 91亚洲激情 | 久久国产精品第一页 | 国产一区二区三区免费观看视频 | 欧美精品成人在线 | 最近中文字幕大全中文字幕免费 | 大胆欧美gogo免费视频一二区 | 人人干人人草 | 91麻豆精品国产91久久久更新时间 | 日韩av在线高清 | 国产99久久久国产精品免费二区 | av九九| 久草在线看片 | 国产香蕉久久精品综合网 | 91一区二区三区在线观看 | 免费看的黄色片 | 中文字幕 国产视频 | www天天干| 免费在线观看av不卡 | 天天插夜夜操 | 久草视频在线新免费 | 久久精品播放 | 亚洲黑丝少妇 | 美女视频a美女大全免费下载蜜臀 | 国产99免费视频 | 少妇资源站 | 日本激情动作片免费看 | 狠狠操天天操 | 久久精视频 | 美女免费视频一区 | 国产亚洲欧美精品久久久久久 | 欧美久久久久 | 91精品啪啪 | 最新高清无码专区 | 日韩免费电影在线观看 | 久久综合日 | 一区二区av| 欧美孕妇与黑人孕交 | 99精品视频在线观看 | 天天天干夜夜夜操 | av高清一区二区三区 | 欧美日韩精品免费观看视频 | 一级黄色av | www色av| 中文字幕乱码在线播放 | 福利视频精品 | 91精品久久久久久 | 国产一区二区不卡视频 | 99久在线精品99re8热视频 | 成人国产网址 | 久久精品免费 | 97日日碰人人模人人澡分享吧 | 欧美视频日韩视频 | 免费在线激情视频 | 日本精品va在线观看 | 国产香蕉视频在线观看 | 精品国内自产拍在线观看视频 | 水蜜桃亚洲一二三四在线 | 精品视频9999 | 久久婷婷国产色一区二区三区 | 亚洲欧美日韩在线看 | 国产精品久久99综合免费观看尤物 | 高清久久久 | a色视频 | 成年人视频在线免费播放 | 在线免费黄色av | 久久综合五月 | 国产人成一区二区三区影院 | 五月天国产精品 | 美女在线观看网站 | 国产一区在线视频播放 | 日本免费久久高清视频 | 一级片免费在线 | 99热在|