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

一篇非常 Nice 的 UmiJS 教程

開發 前端
網上的umi教程是真的少,很多人都只寫了一點點,很多水文,所以打算自己寫一篇,自己搭建umi,并封裝了一下常用的功能,并用到公司實際項目中。

[[437884]]

 前言

網上的umi教程是真的少,很多人都只寫了一點點,很多水文,所以打算自己寫一篇,自己搭建umi,并封裝了一下常用的功能,并用到公司實際項目中.

umi介紹

Umi 是什么?

Umi,中文可發音為烏米,是可擴展的企業級前端應用框架。Umi 以路由為基礎的,同時支持配置式路由和約定式路由,保證路由的功能完備,并以此進行功能擴展。然后配以生命周期完善的插件體系,覆蓋從源碼到構建產物的每個生命周期,支持各種功能擴展和業務需求。

Umi 是螞蟻金服的底層前端框架,已直接或間接地服務了 3000+ 應用,包括 java、node、H5 無線、離線(Hybrid)應用、純前端 assets 應用、CMS 應用等。他已經很好地服務了我們的內部用戶,同時希望他也能服務好外部用戶。

它主要具備以下功能:

  •   🎉 可擴展,Umi 實現了完整的生命周期,并使其插件化,Umi 內部功能也全由插件完成。此外還支持插件和插件集,以滿足功能和垂直域的分層需求。
  •   📦 開箱即用,Umi 內置了路由、構建、部署、測試等,僅需一個依賴即可上手開發。并且還提供針對 React 的集成插件集,內涵豐富的功能,可滿足日常 80% 的開發需求。
  •   🐠 企業級,經螞蟻內部 3000+ 項目以及阿里、優酷、網易、飛豬、口碑等公司項目的驗證,值得信賴。
  •   🚀 大量自研,包含微前端、組件打包、文檔工具、請求庫、hooks 庫、數據流等,滿足日常項目的周邊需求。
  •   🌴 完備路由,同時支持配置式路由和約定式路由,同時保持功能的完備性,比如動態路由、嵌套路由、權限路由等等。
  •   🚄 面向未來,在滿足需求的同時,我們也不會停止對新技術的探索。比如 dll 提速、modern mode、webpack@5、自動化 external、bundler less 等等。

什么時候不用 umi?

如果你,

  •   需要支持 IE 8 或更低版本的瀏覽器
  •   需要支持 React 16.8.0 以下的 React
  •   需要跑在 Node 10 以下的環境中
  •   有很強的 webpack 自定義需求和主觀意愿
  •   需要選擇不同的路由方案

Umi 可能不適合你。

為什么不是?

create-react-app

create-react-app 是基于 webpack 的打包層方案,包含 build、dev、lint 等,他在打包層把體驗做到了極致,但是不包含路由,不是框架,也不支持配置。所以,如果大家想基于他修改部分配置,或者希望在打包層之外也做技術收斂時,就會遇到困難。

next.js

next.js 是個很好的選擇,Umi 很多功能是參考 next.js 做的。要說有哪些地方不如 Umi,我覺得可能是不夠貼近業務,不夠接地氣。比如 antd、dva 的深度整合,比如國際化、權限、數據流、配置式路由、補丁方案、自動化 external 方面等等一線開發者才會遇到的問題。

umi3項目初始化

環境準備

首先得有 node,并確保 node 版本是 10.13 或以上。

推薦使用 yarn 管理 npm 依賴

本項目使用的版本為 node v14.17.5  yarn 1.22.15

腳手架

桌面新建umi3文件夾, 用vscode打開, 打開vscode終端,

執行 yarn create @umijs/umi-app 創建項目

安裝依賴 yarn

啟動項目 yarn start

配置 prettier,eslint, stylelint

umi 維護了一個 prettier,eslint,stylelint 的配置文件合集 umi-fabric 

  1. yarn add @umijs/fabric -D 

根目錄新建下面三個文件,刪除.prettierrc文件

.eslintrc.js、.prettierrc.js、.stylelintrc.js

配置如下 

  1. //.eslintrc.js 配置  
  2. module.exports = {  
  3.   extends: [require.resolve('@umijs/fabric/dist/eslint')],  
  4.   // in antd-design-pro  
  5.   globals: {  
  6.     ANT_DESIGN_PRO_ONLY_DO_NOT_USE_IN_YOUR_PRODUCTION: true,  
  7.     page: true,  
  8.   }, 
  9.   rules: {  
  10.     // your rules  
  11.     'prefer-const': 0,  
  12.   },  
  13. };  
  14. //.prettierrc.js 配置  
  15. const fabric = require('@umijs/fabric')  
  16. module.exports = {  
  17.   ...fabric.prettier,  
  18.   semi: false,  
  19.  
  20. //.stylelintrc.js 配置  
  21. const fabric = require('@umijs/fabric')  
  22. module.exports = {  
  23.   ...fabric.stylelint,  

根目錄新建eslint忽略文件  .eslintignore 

  1. .eslintrc.js  
  2. node_modules 

在package.json 里面的lint-staged 新增 "eslint --fix"

最后你的 vscode 要安裝這三個同名擴展插件,這時候分別去更改 js、less 文件,會發現已經有風格校驗了。

驗證

修改src/paegs文件夾下的index.tsx文件,新增一個a變量,有eslint錯誤提示,說明eslint生效了

然后再單獨提交index.tsx這一個文件

會提示有錯誤,無法提交,說明pre-commmit 鉤子生效

保存時自動格式化代碼

在vscode設置 文本編輯器的格式化里面  勾選Format on Save

我的eslint,或者prettier 不生效?

去到終端里的輸出,找到eslint或者prettier 看他們的輸出日志,是否正常。如果有報錯,根據報錯信息處理問題

檢查步驟:

  •  確保安裝umi-fabric
  •  檢查配置文件是否存在
  •  vscode 得eslint 和prettier 插件是否下載
  •  確認輸出日志,是否有報錯

pre-commit時的lint-staged 不生效

在package.json中 我們配置了如下得代碼

意思是 在代碼commit之前 執行prettier格式化代碼和eslint fix 如果你在提交代碼的時候沒有生效,請執行

  1. yarn install --force 

執行這個命令重新拉取依賴

不生效的原因?

自己剛開始也是各種google,查看文檔,也沒有找出原因,最后在umi2的一個issue里面,自己找到了答案。

原因在于我們初始化git倉庫的順序,如果我們先初始化git倉庫 然后再創建項目,再拉取依賴。是沒有任何問題的。

如果我們先創建了umi項目,拉去依賴,最后初始化git,提交代碼到git倉庫,當我們拉去依賴時, 這是就還沒有.git 就沒有生成相關的pre-commit,所以就沒有生效。所以這時我們就只需要在重新拉取下依賴就可以了。

配置css初始化代碼

為什么要初始化css

建站老手都知道,這是為了考慮到瀏覽器的兼容問題,其實不同瀏覽器對有些標簽的默認值是不同的,如果沒對CSS初始化往往會出現瀏覽器之間的頁面差異。當然,初始化樣式會對SEO有一定的影響,但魚和熊掌不可兼得,但力求影響最小的情況下初始化。

最簡單的初始化方法就是:* {padding: 0; margin: 0;} 。有很多人也是這樣寫的。這確實很簡單,但有人就會感到疑問:*號這樣一個通用符在編寫代碼的時候是快,但如果網站很大,CSS樣式表文件很大,這樣寫的話,他會把所有的標簽都初始化一遍,這樣就大大的加強了網站運行的負載,會使網站加載的時候需要很長一段時間。

CSS初始化是指重設瀏覽器的樣式。不同的瀏覽器默認的樣式可能不盡相同,所以開發時的第一件事可能就是如何把它們統一。如果沒對CSS初始化往往會出現瀏覽器之間的頁面差異。每次新開發網站或新網頁時候通過初始化CSS樣式的屬性,為我們將用到的CSS或html標簽更加方便準確,使得我們開發網頁內容時更加方便簡潔,同時減少CSS代碼量,節約網頁下載時間。

Umi 中約定 src/global.css 為全局樣式,如果存在此文件,會被自動引入到入口文件最前面。

src下面新建global.css,代碼如下 

  1. body,  
  2. ol,  
  3. ul,  
  4. h1,  
  5. h2,  
  6. h3,  
  7. h4,  
  8. h5,  
  9. h6,  
  10. p,  
  11. th,  
  12. td,  
  13. dl,  
  14. dd,  
  15. form,  
  16. fieldset,  
  17. legend,  
  18. input,  
  19. textarea,  
  20. select,  
  21. figure,  
  22. figcaption {  
  23.   margin: 0;  
  24.   padding: 0;  
  25. li {  
  26.   list-style-type: none;  
  27.  
  28. a {  
  29.   text-decoration: none;  
  30.  
  31. a:hover {  
  32.   text-decoration: underline;  
  33.  
  34. img {  
  35.   border: none;  
  36.  
  37. input {  
  38.   outline: none;  

配置文件

Umi 在 .umirc.ts 或 config/config.ts 中配置項目和插件,支持 es6。

如果項目的配置不復雜,推薦在 .umirc.ts 中寫配置;如果項目的配置比較復雜,可以將配置寫在 config/config.ts 中,并把配置的一部分拆分出去,比如路由配置可以拆分成單獨的 routes.ts

推薦兩種配置方式二選一,.umirc.ts 優先級更高。

我們采用config的方式,刪除.umirc.ts,根目錄新建config文件夾, 在里面新建config.ts

默認內容如下 

  1. import { defineConfig } from 'umi';  
  2. export default defineConfig({ 
  3.   nodeModulesTransform: {  
  4.     type: 'none',  
  5.   },  
  6.   routes: [  
  7.     { path: '/', component: '@/pages/index' },  
  8.   ],  
  9.   fastRefresh: {},  
  10. }); 

多環境多配置文件

可以通過環境變量 UMI_ENV 區分不同環境來指定配置。

為了兼容性,可借助三方工具 cross-env來設置環境變量 

  1. yarn add cross-env --dev 

在package.json中的script中   

  1. "start": "cross-env UMI_ENV=dev umi dev",  
  2.    "start:test": "cross-env UMI_ENV=test umi dev",  
  3.    "start:prd": "cross-env UMI_ENV=prd umi dev",  
  4.    "build": "cross-env UMI_ENV=dev umi build",  
  5.    "build:test": "cross-env UMI_ENV=test umi build",  
  6.    "build:prd": "cross-env UMI_ENV=prd umi build", 

然后再config文件夾下 新建

config.dev.ts,config.test.ts,config.prd.ts

代表開發環境,測試環境,生產環境的配置文件.

config.dev.ts 

  1. import { defineConfig } from 'umi';  
  2. export default defineConfig({ 
  3.   define: {  
  4.     CurrentEnvironment: 'dev',  
  5.   }, 
  6. }); 

config.test.ts 

  1. import { defineConfig } from 'umi';  
  2. export default defineConfig({  
  3.   define: {  
  4.     CurrentEnvironment: 'test',  
  5.   },  
  6. }); 

config.prd.ts 

  1. import { defineConfig } from 'umi';  
  2. export default defineConfig({  
  3.   define: {  
  4.     CurrentEnvironment: 'prd',  
  5.   },  
  6. }); 

CurrentEnvironment 變量代表當前的環境,后面根據不同的環境配置不同的請求地址會用到

用于提供給代碼中可用的變量,定義的變量可以全局拿到

這時 執行 yarn start:prd,然后去到pages的index.tsx打印CurrentEnvironment.

這時需要去到根目錄的 typings.d.ts 添加 

  1. // 聲明當前的環境  
  2. declare const CurrentEnvironment: 'dev' | 'test' | 'prd';  

然后報錯消失 控制臺打印如下

這時 重新執行yanr start:test 控制臺打印如下

環境變量和多環境多配置 成功

**注意點**:

config.ts作為配置文件時,記得刪除.umirc.ts 不然config.ts不會生效。

自定義環境變量

如果我們想自定義一個環境變量,REACT_APP_ENV. 同樣我們可以在package.json里面設置

然后我們要這樣拿到這個變量呢?

首先 我們要在config.ts 的 define 配置 

  1. define: {  
  2.     REACT_APP_ENV: process.env.REACT_APP_ENV,  
  3. }, 

然后再在根目錄的 typings.d.ts 定義

  1. declare const REACT_APP_ENV: string; 

這樣就可以以在全局中拿到和使用 REACT_APP_ENV這個環境變量了.

可以在任意組件 直接打印

  1. console.log('自定義環境變量', REACT_APP_ENV); 

系統自帶的環境變量

官方提供的環境變量

怎么使用?

在根目錄新建.env 環境變量配置文件

然后寫入 

  1. PORT=3000  // 表示啟動的端口號為3000  
  2. COMPRESS = none  // 不壓縮 CSS 和 JS 

還有一些環境變量 不能配在 .env 中,只能在命令行里添加

比如 FORK_TS_CHECKER 默認不開啟 TypeScript 類型檢查,值為 1 時啟用。 

  1. "start": "cross-env FORK_TS_CHECKER=1 UMI_ENV=dev umi dev", 

請求的封裝

src文件夾下新建 request文件夾 新建request.ts

request.ts 

  1. /**  
  2.  * 網絡請求工具 封裝umi-request  
  3.  * 更詳細的 api 文檔: https://github.com/umijs/umi-request  
  4.  */  
  5. import { extend } from 'umi-request';  
  6. import type { RequestOptionsInit } from 'umi-request';  
  7. import { notification } from 'antd';  
  8. // codeMessage僅供參考 具體根據和后端協商,在詳細定義.  
  9. const codeMessage = {  
  10.   200: '服務器成功返回請求的數據。',  
  11.   400: '發出的請求有錯誤,服務器沒有進行新建或修改數據的操作。',  
  12.   500: '服務器發生錯誤,請檢查服務器。',  
  13. };  
  14. type mapCode = 200 | 400 | 500;   
  15. /**  
  16.  * 錯誤異常處理程序  
  17.  */  
  18. const errorHandler = (error: { response: Response }): Response => {  
  19.   const { response } = error;  
  20.   if (response && response.status) {  
  21.     let errorText = codeMessage[response.status as mapCode] || response.statusText;  
  22.     const { status, url } = response;  
  23.     response  
  24.       ?.clone()  
  25.       ?.json()  
  26.       ?.then((res) => {  
  27.         // 后端返回錯誤信息,就用后端傳回的  
  28.         errorText = res.msg ? res.msg : errorText;  
  29.         notification.error({  
  30.           message: `請求錯誤 ${status}: ${url}`,  
  31.           description: errorText,  
  32.         });  
  33.       });  
  34.   } else if (!response) {  
  35.     notification.error({  
  36.       description: '您的網絡發生異常,無法連接服務器', 
  37.       message: '網絡異常',  
  38.     });  
  39.   }  
  40.   return response;  
  41. };  
  42. /**  
  43.  * 配置request請求時的默認參數  
  44.  */  
  45. const request = extend({  
  46.   errorHandler, // 默認錯誤處理  
  47.   credentials: 'include', // 默認請求是否帶上cookie  
  48. });  
  49. // 根據不同的開發環境,配置請求前綴  
  50. interface ApiPrefix {  
  51.   dev: string;  
  52.   test: string;  
  53.   prd: string;  
  54.  
  55. const apiPreFix: ApiPrefix = {  
  56.   dev: 'http://120.55.193.14:3030/',  
  57.   test: 'http://120.55.193.14:3030/',  
  58.   prd: 'http://120.55.193.14:3030/',  
  59. };  
  60. // request攔截器, 攜帶token,以及根據環境,配置不同的請求前綴  
  61. request.interceptors.request.use((url: string, options: RequestOptionsInit) => {  
  62.   // 不攜帶token的請求數組  
  63.   let notCarryTokenArr: string[] = [];  
  64.   if (notCarryTokenArr.includes(url)) {  
  65.     return {  
  66.       url: `${apiPreFix[CurrentEnvironment]}${url}`,  
  67.       options,  
  68.     };  
  69.   }  
  70.   // 給每個請求帶上token  
  71.   let token = localStorage.getItem('tokens') || '';  
  72.   let headers = {  
  73.     Authorization: `Bearer ${token}`,  
  74.   };  
  75.   return {  
  76.     url: `${apiPreFix[CurrentEnvironment]}${url}`,  
  77.     options: { ...options, interceptors: true, headers },  
  78.   };  
  79. });  
  80. /**  
  81.  * @url 請求的url  
  82.  * @parameter 上傳的參數  
  83.  */  
  84. // 封裝的get,post.put,delete請求  
  85. const get = async (url: string, parameter?: Record<string, unknown>): Promise<any> => {  
  86.   try { 
  87.     const res = await request(url, { method: 'get', params: parameter });  
  88.     return res;  
  89.   } catch (error) {  
  90.     console.error(error);  
  91.   }  
  92. };  
  93. const deletes = async (url: string, parameter?: Record<string, unknown>): Promise<any> => {  
  94.   try {  
  95.     const res = await request(url, { method: 'delete', params: parameter });  
  96.     return res;  
  97.   } catch (error) {  
  98.     console.error(error);  
  99.   }  
  100. };  
  101. const post = async (url: string, parameter?: Record<string, unknown>): Promise<any> => {  
  102.   try {  
  103.     const res = await request(url, { method: 'post', data: parameter });  
  104.     return res;  
  105.   } catch (error) {  
  106.     console.error(error);  
  107.   }  
  108. };  
  109. const put = async (url: string, parameter?: Record<string, unknown>): Promise<any> => {  
  110.   try {  
  111.     const res = await request(url, { method: 'put', data: parameter });  
  112.     return res;  
  113.   } catch (error) {  
  114.     console.error(error);  
  115.   }  
  116. };  
  117. export default {  
  118.   get,  
  119.   post,  
  120.   put,  
  121.   deletes,  
  122. }; 

這里封裝了umi-request,統一處理了接口錯誤,請求攔截器攜帶token等.最后在配合useRequest 非常的好用.

umi中使用dva

介紹

包含以下功能,

  •  內置 dva,默認版本是 ^2.6.0-beta.20,如果項目中有依賴,會優先使用項目中依賴的版本。
  •  約定式的 model 組織方式,不用手動注冊 model
  •  文件名即 namespace,model 內如果沒有聲明 namespace,會以文件名作為 namespace
  •  內置 dva-loading,直接 connect loading 字段使用即可
  •  支持 immer,通過配置 immer 開啟

約定式的 model 組織方式

符合以下規則的文件會被認為是 model 文件,

  •  src/models 下的文件
  •  src/pages 下,子目錄中 models 目錄下的文件
  •  src/pages 下,所有 model.ts 文件(不區分任何字母大小寫)

實際使用

比如在src下新建 models文件夾,里面新建test.ts

test.ts 

  1. import type { Effect, Reducer, Subscription } from 'umi'; // 映入umi 定義好的ts類型  
  2. import axios from '../request/request'; // 引入封裝好的網絡請求  
  3. // state 接口  
  4. export interface TextModelState { 
  5.   name?: string;  
  6.   testData?: string;  
  7. // test model接口  
  8. export interface TextModelType {  
  9.   namespace: 'testModel';  
  10.   state: TextModelState;  
  11.   effects: {  
  12.     query: Effect;  
  13.   };  
  14.   reducers: {  
  15.     save: Reducer<TextModelState> 
  16.     msg: Reducer<TextModelState> 
  17.   };  
  18.   subscriptions?: { setup: Subscription };  
  19.  
  20. const IndexModel: TextModelType = {  
  21.   namespace: 'testModel',  
  22.   state: {  
  23.     name: '初始名字',  
  24.     testData: '初始testData',  
  25.   },  
  26.   effects: {  
  27.     *query(action, { call, put }) {  
  28.       const getDataTest = async () => {  
  29.         const data = await axios.get('test'); 
  30.         return data;  
  31.       };  
  32.       let testData = yield call(getDataTest); 
  33.       yield put({  
  34.         type: 'msg',  
  35.         data: { testData: testData?.msg },  
  36.       });  
  37.     },  
  38.   },  
  39.   reducers: {  
  40.     save(state) {  
  41.       return {  
  42.         ...state,  
  43.         name: 'jimmy',  
  44.       };  
  45.     },  
  46.     msg(state, action) {  
  47.       return {  
  48.         ...state,  
  49.         testData: action?.data?.testData,  
  50.         testData2: action?.data?.testData2,  
  51.       };  
  52.     },  
  53.   },  
  54. };  
  55. export default IndexModel; 

在src/pages下的index.tsx中使用

index.tsx 

  1. import type { Effect, Reducer, Subscription } from 'umi'; // 引入umi 定義好的ts類型  
  2. import axios from '../request/request'; // 引入封裝好的網絡請求  
  3. // state 接口  
  4. export interface TextModelState {  
  5.   name?: string;  
  6.   testData?: string;  
  7.  
  8. // test model接口  
  9. export interface TextModelType {  
  10.   namespace: 'testModel';  
  11.   state: TextModelState;  
  12.   effects: {  
  13.     query: Effect;  
  14.   };  
  15.   reducers: {  
  16.     save: Reducer<TextModelState> 
  17.     msg: Reducer<TextModelState> 
  18.   };  
  19.   subscriptions?: { setup: Subscription };  
  20.  
  21. const IndexModel: TextModelType = {  
  22.   namespace: 'testModel',  
  23.   state: {  
  24.     name: '初始名字',  
  25.     testData: '初始testData',  
  26.   },  
  27.   effects: {  
  28.     *query(action, { call, put }) {  
  29.       const getDataTest = async () => {  
  30.         const data = await axios.get('test');  
  31.         return data;  
  32.       };  
  33.       let testData = yield call(getDataTest); 
  34.       yield put({  
  35.         type: 'msg',  
  36.         data: { testData: testData?.msg },  
  37.       });  
  38.     },  
  39.   },  
  40.   reducers: {  
  41.     save(state) {  
  42.       return {  
  43.         ...state,  
  44.         name: 'jimmy',  
  45.       };  
  46.     },  
  47.     msg(state, action) {  
  48.       return {  
  49.         ...state,  
  50.         testData: action?.data?.testData,  
  51.         testData2: action?.data?.testData2,  
  52.       };  
  53.     },  
  54.   },  
  55. };  
  56. export default IndexModel; 

mfsu

啟用 mfsu 后,熱啟動得到 **10 倍** 提升;熱更新提升 **50%** 以上!

如何啟用

在 config/config.ts 中添加 mfsu:{}

項目源代碼

請點擊我

和兩個小伙伴一起,會根據實際運用中出現的問題或者沒有考慮完善的地方,持續的更新迭代.如有問題,歡迎提Issue或者在評論區留言

FAQ

umi 不是內部或外部命令

解決辦法

執行 yarn global bin 拿到 bin 路徑。然后把這個路徑添加到環境變量里面的系統變量的path里面

如果還是不行,執行 

  1. yarn global add umi 

如遇到更多問題,請查考

官方FAQ

官方倉庫的issue 

 

責任編輯:龐桂玉 來源: 前端大全
相關推薦

2022-07-06 07:57:37

Zookeeper分布式服務框架

2018-11-01 13:20:05

Python爬蟲編程語言

2020-01-13 13:10:29

技術研發運維

2021-05-11 09:31:31

kustomizeoperator kubernetes

2021-05-08 09:02:48

KubeBuilderOperatork8s

2021-09-18 07:43:33

ApolloJava配置中心

2021-10-14 09:58:24

消息中間件ActiveMQ Java

2025-11-18 08:46:00

大模型強化學習Meta

2021-09-15 19:05:16

數據開源項目

2021-07-12 06:11:14

SkyWalking 儀表板UI篇

2022-10-26 07:39:36

MVCC數據庫RR

2022-01-02 08:43:46

Python

2022-12-19 08:14:30

注解開發配置

2021-05-20 06:57:16

RabbitMQ開源消息

2022-02-07 11:01:23

ZooKeeper

2023-04-20 08:00:00

ES搜索引擎MySQL

2022-06-30 22:53:18

數據結構算法

2021-08-01 07:19:16

語言OpenrestyNginx

2021-08-11 07:02:21

npm包管理器工具

2023-10-30 07:12:04

點贊
收藏

51CTO技術棧公眾號

欧美午夜激情在线| 成人激情视频网站| 久久久av网站| 欧美大片免费播放器| 午夜精品成人av| 亚洲视频在线观看三级| 成人在线观看网址| 亚洲精品国产精品乱码视色| 欧美激情五月| 国产亚洲精品久久久久久牛牛| 天天久久综合网| jizz内谢中国亚洲jizz| 一区二区三区中文在线| 蜜桃导航-精品导航| 精品人妻一区二区三区麻豆91| 亚洲资源av| 操人视频在线观看欧美| 日本xxxxxxxxx18| 91成人福利| 欧美久久一二区| 日韩网址在线观看| 福利小视频在线| 国产精品美女久久久久久| 久久99精品久久久久久青青日本| 国产精品美女一区| 日本中文一区二区三区| 91国产美女在线观看| 国产精品白丝喷水在线观看| 日本一区二区高清不卡| 日韩福利在线播放| 亚洲色图欧美日韩| 亚洲一区二区电影| 欧美一区二区三区四区久久| 九色porny自拍| 亚洲综合在线电影| 丁香五六月婷婷久久激情| 欧美国产综合在线| 丝袜综合欧美| 亚洲蜜臀av乱码久久精品蜜桃| 亚洲精品影院| www.亚洲.com| 国产日韩欧美一区二区三区乱码| 玛丽玛丽电影原版免费观看1977 | 久久爱.com| 91福利小视频| 国产精品入口免费软件| 成人午夜视屏| 欧日韩精品视频| 97公开免费视频| 亚洲精品粉嫩美女一区| 在线看国产一区二区| 成人在线激情网| 日韩精品专区| 欧美在线观看视频一区二区 | 成人性生交大片免费看96| 日韩视频免费观看高清完整版在线观看| 天堂在线中文在线| 国产亚洲久久| 欧美精品一区二区久久婷婷| 久久久高清视频| 天海翼亚洲一区二区三区| 日韩久久精品电影| 成人黄色免费网址| 色综合咪咪久久网| 欧美成人午夜影院| 久久精品亚洲无码| 国产精品美女久久久| 日本亚洲欧洲色| 日本欧美www| 激情综合色综合久久| 99久久精品免费看国产一区二区三区| 成人午夜福利视频| 91丨porny丨最新| 亚洲国产高清国产精品| 成人三级网址| 婷婷六月综合网| 中文字幕永久视频| 韩国三级成人在线| 亚洲成年网站在线观看| 免费毛片视频网站| 久久在线免费| 欧美激情精品久久久| www.日本精品| 精品一区二区三区欧美| 91精品啪在线观看麻豆免费| 国产小视频一区| 国产色产综合色产在线视频| 三级网在线观看| av漫画网站在线观看| 欧美午夜精品理论片a级按摩| 日本中文字幕在线不卡| 亚洲老女人视频免费| 日韩视频一区在线| 日韩 欧美 综合| 亚洲精品高清国产一线久久| 女人18毛片一区二区三区| 97精品久久久午夜一区二区三区| 色噜噜狠狠一区二区三区| 成人在线观看亚洲| 日本国产一区二区| 国产精品99久久久精品无码| 精品国产一区二区三区| 欧美肥臀大乳一区二区免费视频| 国产91国语对白在线| 国产成人啪免费观看软件| 欧美性xxxx69| 超碰97国产精品人人cao| 欧美日韩精品系列| 中文字幕乱码一区| 亚洲国产一成人久久精品| 日韩av123| 高清一区二区三区四区| 中文字幕中文字幕中文字幕亚洲无线| 九色在线视频观看| 香港久久久电影| 日韩中文字幕精品| 人人爽人人爽人人片av| 国产sm精品调教视频网站| 91精品久久久久久久91蜜桃| 成人高清在线观看视频| 欧美日韩激情| 日本视频久久久| 午夜国产在线视频| 一区二区高清免费观看影视大全| 奇米影音第四色| 中文有码一区| 45www国产精品网站| 免费av一级片| 亚洲一区视频在线| 青娱乐精品在线| 首页国产精品| 国产精品欧美一区二区| 国产高清免费av在线| 欧美性极品xxxx做受| 日韩www视频| 亚洲天堂久久| 国产免费高清一区| heyzo在线欧美播放| 欧美va在线播放| 久久黄色免费视频| 国产成人午夜99999| a级片一区二区| 秋霞影院一区| 欧美大成色www永久网站婷| 国产精品一区二区三区在线免费观看| 中文字幕巨乱亚洲| 日本人69视频| 午夜激情久久| 91在线免费看网站| av文字幕在线观看| 日韩一区二区高清| 久久香蕉精品视频| 成人精品在线视频观看| 9久久9毛片又大又硬又粗| 欧美精品中文| 日韩av免费看| 91啦中文在线| 5月丁香婷婷综合| 真实国产乱子伦对白在线| 精品一区二区三区日韩| 300部国产真实乱| www.国产精品一区| 2019亚洲日韩新视频| 国产在线一在线二| 制服.丝袜.亚洲.另类.中文| www青青草原| 不卡电影免费在线播放一区| 国产青青在线视频| 国产探花一区| 91九色综合久久| 黄色大片在线| 亚洲视频在线视频| 国产又粗又猛又爽| 亚洲一区二区三区中文字幕| 黄色性生活一级片| 日本美女一区二区| 国产在线拍揄自揄拍无码| 视频免费一区二区| 欧美中文在线视频| 香蕉视频免费在线播放| 欧美成va人片在线观看| 久久国产黄色片| 国产精品成人午夜| 久久精品女同亚洲女同13| 日韩国产高清影视| 特级西西人体www高清大胆| 日韩美女毛片| 92裸体在线视频网站| 精品人人视频| 久久综合免费视频影院| 熟妇高潮一区二区高潮| 欧美日韩午夜在线| 五月天婷婷丁香| 国产精品免费久久| 无码人妻aⅴ一区二区三区| 激情综合色播激情啊| 成人在线免费在线观看| 国产韩日影视精品| 久久久久久艹| 日韩成人精品| 国产女人精品视频| 麻豆理论在线观看| 美女性感视频久久久| 激情在线视频| 亚洲黄一区二区| 国产精品视频第一页| 色av成人天堂桃色av| 国产无遮挡又黄又爽又色| 国产精品天干天干在线综合| 男生裸体视频网站| 国产99久久久国产精品潘金 | 日韩电影在线一区二区三区| 成人精品视频在线播放| 91超碰成人| 亚洲精品乱码久久久久久蜜桃91| 日韩欧美ww| 国产无套精品一区二区| 美女精品久久| 国产在线观看不卡| 欧美free嫩15| 欧美在线www| 乱人伦视频在线| 久久久中精品2020中文| 在线免费观看的av| 日韩在线观看免费全| 国产视频第一页在线观看| 亚洲精品电影久久久| 丰满人妻一区二区三区无码av| 欧美日本乱大交xxxxx| 免费视频网站在线观看入口| 欧美日韩在线免费| 日韩精品人妻中文字幕| 亚洲最大成人网4388xx| www青青草原| 一区二区三区不卡在线观看| 九九精品在线观看视频| 一区二区三区四区在线播放| 伊人在线视频观看| 自拍偷在线精品自拍偷无码专区| 国产精品18在线| 国产精品久久久久久久第一福利 | 人妻巨大乳一二三区| 国内精品久久久久影院薰衣草| www.com黄色片| 日本欧美大码aⅴ在线播放| 中文久久久久久| 美女免费视频一区| 亚洲小视频网站| 国产一区二区三区免费看| 在线视频日韩欧美| 国产a区久久久| 国产69视频在线观看| 99视频超级精品| 欧美特黄一区二区三区| 国产三级欧美三级| 精品在线观看一区| 亚洲天堂中文字幕| 久久久久成人精品无码| 亚洲不卡av一区二区三区| 中文字幕超碰在线| 欧美性猛交xxxx偷拍洗澡| 亚洲精品久久久久久久蜜桃| 欧美伦理视频网站| 精品国产999久久久免费| 欧美精品一区二区三区蜜桃 | 久久6精品影院| 久草在线视频网站| 欧美在线观看日本一区| 成人高清一区| 99伊人久久| 天天久久夜夜| 亚洲在线不卡| 国内精品久久久久久久影视麻豆 | 亚洲欧美一区二区三区| 国产精品久久久久av免费| 99精品女人在线观看免费视频 | 午夜国产在线视频| 中文字幕日韩欧美| 在线看一级片| 日韩免费在线看| 国产精品亚洲四区在线观看| 九色综合日本| 五月久久久综合一区二区小说| 色综合久久久久无码专区| 免费在线视频一区| 日本久久久久久久久久| 欧美激情自拍偷拍| 精品午夜福利视频| 欧美视频在线播放| 人妻夜夜爽天天爽| 日韩中文在线不卡| 国产白浆在线免费观看| 成人免费淫片视频软件| 亚洲精品456| 特大黑人娇小亚洲女mp4| 久久久久一区| 在线中文字日产幕| 中文字幕在线观看一区二区| 九一国产在线观看| 欧美日韩国产综合视频在线观看| 污污的视频网站在线观看| 日韩亚洲一区二区| 伊人久久在线| 成人资源视频网站免费| 日韩亚洲一区在线| 亚洲精品无码久久久久久| 福利一区福利二区| 日本免费网站视频| 欧美综合在线视频| 人妻中文字幕一区| 亚洲黄色av一区| a级片在线观看视频| 中文字幕av在线一区二区三区| 久久久久成人精品无码| 欧美日本视频在线| 免费在线性爱视频| 国内精品久久久久影院 日本资源 国内精品久久久久伊人av | 伊人中文字幕在线观看| 精品国产伦理网| 在线xxxx| 91夜夜未满十八勿入爽爽影院| 成人同人动漫免费观看| 超碰影院在线观看| 99精品在线免费| 日韩av在线播| 亚洲电影天堂av| 黄网av在线| 成人午夜电影在线播放| 欧美99久久| 日本少妇一区二区三区| 亚洲欧美经典视频| 97caocao| xx视频.9999.com| **精品中文字幕一区二区三区| 亚洲欧美日产图| 久久国产三级精品| www.黄色com| 91精品国产综合久久蜜臀| 日本成a人片在线观看| 成人h猎奇视频网站| 999久久久免费精品国产| 日韩在线一区视频| 综合久久久久久久| www.色婷婷.com| 久久久久久尹人网香蕉| 久久夜色精品国产噜噜av小说| 男人插女人视频在线观看| 成人91在线观看| 在线观看中文字幕视频| 亚洲欧美在线免费观看| 精品国模一区二区三区| 亚洲女人毛片| 国产精品伊人色| avove在线播放| 精品国产免费一区二区三区香蕉| av在线私库| 欧美一区二区三区四区夜夜大片 | 久久综合电影| 无码人妻aⅴ一区二区三区玉蒲团| 亚洲国产精品久久不卡毛片| 桃花色综合影院| 国产高清在线不卡| 羞羞答答成人影院www| 国产精品无码自拍| 欧美午夜精品久久久久久浪潮| 极品美乳网红视频免费在线观看| 成人乱人伦精品视频在线观看| 欧美激情91| 变态另类丨国产精品| 精品视频一区二区不卡| 性直播体位视频在线观看| 国精产品99永久一区一区| 日韩av一区二区在线影视| 国产黄色小视频网站| 精品成人一区二区三区四区| 中文在线免费二区三区| 中文字幕欧美日韩一区二区三区| 成人综合婷婷国产精品久久蜜臀| 蜜臀精品一区二区三区| 色青青草原桃花久久综合| 福利在线一区| 在线观看免费的av| 午夜精品一区二区三区免费视频| 国产污视频在线| 国产精品国产精品国产专区蜜臀ah | 97超碰蝌蚪网人人做人人爽| 日韩在线二区| 国产不卡一二三| 欧美精品久久99| 中文字幕在线直播| 裸体裸乳免费看| 久久精品视频一区| 成 人 免费 黄 色| 国产精品久久久久91| 亚洲激情影院| 黑鬼狂亚洲人videos| 亚洲香蕉av在线一区二区三区| av一级亚洲| 国产3p在线播放| 日本二三区不卡|