亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > JavaScript > 正文

詳解Vue3.0 前的 TypeScript 最佳入門實踐

2019-11-19 11:19:10
字體:
來源:轉載
供稿:網友

前言

我個人對更嚴格類型限制沒有積極的看法,畢竟各類轉類型的騷寫法寫習慣了。

然鵝最近的一個項目中,是 TypeScript + Vue ,毛計喇,學之...…真香!

注意此篇標題的“前”,本文旨在講Ts混入框架的使用,不講Class API

1. 使用官方腳手架構建

npm install -g @vue/cli# ORyarn global add @vue/cli

新的 Vue CLI 工具允許開發者 使用 TypeScript 集成環境 創建新項目。

只需運行 vue create my-app 。

然后,命令行會要求選擇預設。使用箭頭鍵選擇 Manually select features 。

接下來,只需確保選擇了 TypeScriptBabel 選項,如下圖:

完成此操作后,它會詢問你是否要使用 class-style component syntax 。

然后配置其余設置,使其看起來如下圖所示。

Vue CLI工具現在將安裝所有依賴項并設置項目。

接下來就跑項目喇。

總之,先跑起來再說。

2. 項目目錄解析

通過 tree 指令查看目錄結構后可發現其結構和正常構建的大有不同。

這里主要關注 shims-tsx.d.tsshims-vue.d.ts 兩個文件

兩句話概括:

  • shims-tsx.d.ts ,允許你以 .tsx 結尾的文件,在 Vue 項目中編寫 jsx 代碼
  • shims-vue.d.ts 主要用于 TypeScript 識別 .vue 文件, Ts 默認并不支持導入 vue 文件,這個文件告訴 ts 導入 .vue 文件都按 VueConstructor<Vue> 處理。

此時我們打開親切的 src/components/HelloWorld.vue ,將會發現寫法已大有不同

<template> <div class="hello"> <h1>{{ msg }}</h1> <!-- 省略 --> </div></template><script lang="ts">import { Component, Prop, Vue } from 'vue-property-decorator';@Componentexport default class HelloWorld extends Vue { @Prop() private msg!: string;}</script><!-- Add "scoped" attribute to limit CSS to this component only --><style scoped></style>

至此,準備開啟新的篇章 TypeScript 極速入門 和 vue-property-decorator

3. TypeScript 極速入門

3.1 基本類型和擴展類型

TypescriptJavascript 共享相同的基本類型,但有一些額外的類型。

  • 元組 Tuple
  • 枚舉 enum
  • AnyVoid

1. 基本類型合集

// 數字,二、八、十六進制都支持let decLiteral: number = 6;let hexLiteral: number = 0xf00d;// 字符串,單雙引都行let name: string = "bob";let sentence: string = `Hello, my name is ${ name }.// 數組,第二種方式是使用數組泛型,Array<元素類型>:let list: number[] = [1, 2, 3];let list: Array<number> = [1, 2, 3];let u: undefined = undefined;let n: null = null;

2. 特殊類型

1. 元組 Tuple

想象 元組 作為有組織的數組,你需要以正確的順序預定義數據類型。

const messyArray = [' something', 2, true, undefined, null];const tuple: [number, string, string] = [24, "Indrek" , "Lasn"]

如果不遵循 為元組 預設排序的索引規則,那么 Typescript 會警告。

​ ( tuple 第一項應為 number 類型)

2. 枚舉 enum *

enum 類型是對JavaScript標準數據類型的一個補充。 像C#等其它語言一樣,使用枚舉類型可以為一組數值賦予友好的名字。

// 默認情況從0開始為元素編號,也可手動為1開始enum Color {Red = 1, Green = 2, Blue = 4}let c: Color = Color.Green;let colorName: string = Color[2];console.log(colorName); // 輸出'Green'因為上面代碼里它的值是2

另一個很好的例子是使用枚舉來存儲應用程序狀態。

3. Void

Typescript 中, 你必須在函數中定義返回類型 。像這樣:

若沒有返回值,則會報錯:

我們可以將其返回值定義為 void :

此時將無法 return

4. Any

Emmm...就是什么類型都行,當你無法確認在處理什么類型時可以用這個。

但要慎重使用,用多了就失去使用Ts的意義。

let person: any = "前端勸退師"person = 25person = true

主要應用場景有:

  • 接入第三方庫
  • Ts菜逼前期都用

5. Never

用很粗淺的話來描述就是:" Never 是你永遠得不到的爸爸。"

具體的行為是:

throw new Error(message)return error("Something failed")while (true) {} // 存在無法達到的終點

3. 類型斷言

簡略的定義是:可以用來手動指定一個值的類型。

有兩種寫法,尖括號和 as :

let someValue: any = "this is a string";let strLength: number = (<string>someValue).length;let strLength: number = (someValue as string).length;

使用例子有:

當 TypeScript 不確定一個聯合類型的變量到底是哪個類型的時候,我們只能訪問此聯合類型的所有類型里共有的屬性或方法:

function getLength(something: string | number): number { return something.length;}// index.ts(2,22): error TS2339: Property 'length' does not exist on type 'string | number'.// Property 'length' does not exist on type 'number'.

如果你訪問長度將會報錯,而有時候,我們確實需要在還不確定類型的時候就訪問其中一個類型的屬性或方法,此時需要斷言才不會報錯:

function getLength(something: string | number): number { if ((<string>something).length) { return (<string>something).length; } else { return something.toString().length; }}

3.2 泛型: Generics

軟件工程的一個主要部分就是構建組件,構建的組件不僅需要具有明確的定義和統一的接口,同時也需要組件可復用。支持現有的數據類型和將來添加的數據類型的組件為大型軟件系統的開發過程提供很好的靈活性。

C#Java 中,可以使用"泛型"來創建可復用的組件,并且組件可支持多種數據類型。這樣便可以讓用戶根據自己的數據類型來使用組件。

1. 泛型方法

在TypeScript里, 聲明泛型方法 有以下兩種方式:

function gen_func1<T>(arg: T): T { return arg;}// 或者let gen_func2: <T>(arg: T) => T = function (arg) { return arg;}

調用方式也有兩種:

gen_func1<string>('Hello world');gen_func2('Hello world'); // 第二種調用方式可省略類型參數,因為編譯器會根據傳入參數來自動識別對應的類型。

2. 泛型與 Any

Ts 的特殊類型 Any 在具體使用時,可以代替任意類型,咋一看兩者好像沒啥區別,其實不然:

// 方法一:帶有any參數的方法function any_func(arg: any): any { console.log(arg.length);		return arg;}// 方法二:Array泛型方法function array_func<T>(arg: Array<T>): Array<T> {	 console.log(arg.length);		return arg;}

方法一,打印了 arg 參數的 length 屬性。因為 any 可以代替任意類型,所以該方法在傳入參數不是數組或者帶有 length 屬性對象時,會拋出異常。

方法二,定義了參數類型是 Array 的泛型類型,肯定會有 length 屬性,所以不會拋出異常。

3. 泛型類型

泛型接口:

interface Generics_interface<T> { (arg: T): T;} function func_demo<T>(arg: T): T { return arg;}let func1: Generics_interface<number> = func_demo;func1(123); // 正確類型的實際參數func1('123'); // 錯誤類型的實際參數

3.3 自定義類型: Interface vs Type alias

Interface ,國內翻譯成接口。

Type alias ,類型別名。

以下內容來自:

Typescript 中的 interface 和 type 到底有什么區別

1. 相同點 都可以用來描述一個對象或函數:

interface User { name: string age: number}type User = { name: string age: number};interface SetUser { (name: string, age: number): void;}type SetUser = (name: string, age: number): void;

都允許拓展(extends):

interfacetype 都可以拓展,并且兩者并不是相互獨立的,也就是說 interface 可以 extends type , type 也可以 extends interface 。 雖然效果差不多,但是兩者語法不同 。

interface extends interface

interface Name {  name: string; }interface User extends Name {  age: number; }

type extends type

type Name = {  name: string; }type User = Name & { age: number };

interface extends type

type Name = {  name: string; }interface User extends Name {  age: number; }

type extends interface

interface Name {  name: string; }type User = Name & {  age: number; }

2. 不同點

type 可以而 interface 不行

type 可以聲明基本類型別名,聯合類型,元組等類型

// 基本類型別名type Name = string// 聯合類型interface Dog { wong();}interface Cat { miao();}type Pet = Dog | Cat// 具體定義數組每個位置的類型type PetList = [Dog, Pet]

type 語句中還可以使用 typeof 獲取實例的 類型進行賦值

// 當你想獲取一個變量的類型時,使用 typeoflet div = document.createElement('div');type B = typeof div

其他騷操作

type StringOrNumber = string | number; type Text = string | { text: string }; type NameLookup = Dictionary<string, Person>; type Callback<T> = (data: T) => void; type Pair<T> = [T, T]; type Coordinates = Pair<number>; type Tree<T> = T | { left: Tree<T>, right: Tree<T> };

interface 可以而 type 不行

interface 能夠聲明合并

interface User { name: string age: number}interface User { sex: string}/*User 接口為 { name: string age: number sex: string }*/

interface 有可選屬性和只讀屬性

可選屬性

接口里的屬性不全都是必需的。 有些是只在某些條件下存在,或者根本不存在。 例如給函數傳入的參數對象中只有部分屬性賦值了。帶有可選屬性的接口與普通的接口定義差不多,只是在可選屬性名字定義的后面加一個 ? 符號。如下所示

interface Person { name: string; age?: number; gender?: number;}

只讀屬性

顧名思義就是這個屬性是不可寫的,對象屬性只能在對象剛剛創建的時候修改其值。 你可以在屬性名前用 readonly 來指定只讀屬性,如下所示:

interface User { readonly loginName: string; password: string;}

上面的例子說明,當完成User對象的初始化后loginName就不可以修改了。

3.4 實現與繼承: implements vs extends

extends 很明顯就是ES6里面的類繼承,那么 implement 又是做什么的呢?它和 extends 有什么不同?

implement ,實現。與C#或Java里接口的基本作用一樣, TypeScript 也能夠用它來明確的強制一個類去符合某種契約

implement基本用法:

interface IDeveloper { name: string; age?: number;}// OKclass dev implements IDeveloper { name = 'Alex'; age = 20;}// OKclass dev2 implements IDeveloper { name = 'Alex';}// Errorclass dev3 implements IDeveloper { name = 'Alex'; age = '9';}

extends 是繼承父類,兩者其實可以混著用:

 class A extends B implements C,D,E

搭配 interfacetype 的用法有:

3.5 聲明文件與命名空間: declarenamespace

前面我們講到Vue項目中的 shims-tsx.d.tsshims-vue.d.ts ,其初始內容是這樣的:

// shims-tsx.d.tsimport Vue, { VNode } from 'vue';declare global { namespace JSX { // tslint:disable no-empty-interface interface Element extends VNode {} // tslint:disable no-empty-interface interface ElementClass extends Vue {} interface IntrinsicElements { [elem: string]: any; } }}// shims-vue.d.tsdeclare module '*.vue' { import Vue from 'vue'; export default Vue;}

declare :當使用第三方庫時,我們需要引用它的聲明文件,才能獲得對應的代碼補全、接口提示等功能。

這里列舉出幾個常用的:

  • declare var 聲明全局變量
  • declare function 聲明全局方法
  • declare class 聲明全局類
  • declare enum 聲明全局枚舉類型
  • declare global 擴展全局變量
  • declare module 擴展模塊

namespace :“內部模塊”現在稱做“命名空間”

module X { 相當于現在推薦的寫法 namespace X { )

跟其他 JS 庫協同

類似模塊,同樣也可以通過為其他 JS 庫使用了命名空間的庫創建 .d.ts 文件的聲明文件,如為 D3 JS 庫,可以創建這樣的聲明文件:

declare namespace D3{ export interface Selectors { ... }}declare var d3: D3.Base;

所以上述兩個文件:

  • shims-tsx.d.ts , 在全局變量 global 中批量命名了數個內部模塊。 shims-vue.d.ts ,意思是告訴 TypeScript *.vue 后綴的文件可以交給 vue 模塊來處理。

3.6 訪問修飾符: private 、 publicprotected

其實很好理解:

  1. 默認為 public
  2. 當成員被標記為 private 時,它就不能在聲明它的類的外部訪問,比如:
class Animal { private name: string; constructor(theName: string) { this.name = theName; }}let a = new Animal('Cat').name; //錯誤,‘name'是私有的

protectedprivate 類似,但是, protected 成員在派生類中可以訪問

class Animal { protected name: string; constructor(theName: string) { this.name = theName; }}class Rhino extends Animal { constructor() { super('Rhino'); }   getName() { console.log(this.name) //此處的name就是Animal類中的name }} 

3.7 可選參數 ( ?: )和非空斷言操作符(!.)

可選參數

function buildName(firstName: string, lastName?: string) { return firstName + ' ' + lastName}// 錯誤演示buildName("firstName", "lastName", "lastName")// 正確演示buildName("firstName")// 正確演示buildName("firstName", "lastName")

非空斷言操作符:

能確定變量值一定不為空時使用。

與可選參數 不同的是,非空斷言操作符不會防止出現 null 或 undefined。

let s = e!.name; // 斷言e是非空并訪問name屬性

4. Vue 組件的 Ts 寫法

從 vue2.5 之后,vue 對 ts 有更好的支持。根據官方文檔,vue 結合 typescript ,有兩種書寫方式:

**Vue.extend **

 import Vue from 'vue' const Component = Vue.extend({ 	// type inference enabled })

vue-class-component

import { Component, Vue, Prop } from 'vue-property-decorator'@Componentexport default class Test extends Vue { @Prop({ type: Object }) private test: { value: string }}

理想情況下, Vue.extend 的書寫方式,是學習成本最低的。在現有寫法的基礎上,幾乎 0 成本的遷移。

但是 Vue.extend 模式,需要與 mixins 結合使用。在 mixin 中定義的方法,不會被 typescript 識別到

,這就意味著會出現 丟失代碼提示、類型檢查、編譯報錯等問題。

菜鳥才做選擇,大佬都挑最好的。直接講第二種吧:

4.1 vue-class-component

我們回到 src/components/HelloWorld.vue

<template> <div class="hello"> <h1>{{ msg }}</h1> <!-- 省略 --> </div></template><script lang="ts">import { Component, Prop, Vue } from 'vue-property-decorator';@Componentexport default class HelloWorld extends Vue { @Prop() private msg!: string;}</script><!-- Add "scoped" attribute to limit CSS to this component only --><style scoped></style>

有寫過 python 的同學應該會發現似曾相識:

vue-property-decorator 這個官方支持的庫里,提供了函數 **裝飾器(修飾符)**語法

1. 函數修飾符 @

“@”,與其說是修飾函數倒不如說是引用、調用它修飾的函數。

或者用句大白話描述: @ : "下面的被我包圍了。"

舉個栗子,下面的一段代碼,里面兩個函數,沒有被調用,也會有輸出結果:

test(f){ console.log("before ..."); f()		console.log("after ..."); }@testfunc(){	console.log("func was called");}

直接運行,輸出結果:

before ...
func was called
after ...

上面代碼可以看出來:

  1. 只定義了兩個函數: testfunc ,沒有調用它們。
  2. 如果沒有“@test”,運行應該是沒有任何輸出的。

但是,解釋器讀到函數修飾符“@”的時候,后面步驟會是這樣:

  1. 去調用 test 函數, test 函數的入口參數就是那個叫“ func ”的函數;
  2. test 函數被執行,入口參數的(也就是 func 函數)會被調用(執行);

換言之,修飾符帶的那個函數的入口參數,就是下面的那個整個的函數。有點兒類似 JavaScrip t里面的 function a (function () { ... });

2. vue-property-decoratorvuex-class 提供的裝飾器

vue-property-decorator 的裝飾器:

vuex-class 的裝飾器:

  • @State
  • @Getter
  • @Action
  • @Mutation

我們拿原始Vue組件模版來看:

import {componentA,componentB} from '@/components';export default {	components: { componentA, componentB},	props: { propA: { type: Number }, propB: { default: 'default value' }, propC: { type: [String, Boolean] }, } // 組件數據 data () { return { message: 'Hello' } }, // 計算屬性 computed: { reversedMessage () { return this.message.split('').reverse().join('') } // Vuex數據 step() { 	return this.$store.state.count } }, methods: { changeMessage () { this.message = "Good bye" }, getName() { 	let name = this.$store.getters['person/name'] 	return name } }, // 生命周期 created () { }, mounted () { }, updated () { }, destroyed () { }}

以上模版替換成修飾符寫法則是:

import { Component, Vue, Prop } from 'vue-property-decorator';import { State, Getter } from 'vuex-class';import { count, name } from '@/person'import { componentA, componentB } from '@/components';@Component({ components:{ componentA, componentB},})export default class HelloWorld extends Vue{	@Prop(Number) readonly propA!: number | undefined @Prop({ default: 'default value' }) readonly propB!: string @Prop([String, Boolean]) readonly propC!: string | boolean | undefined  // 原data message = 'Hello'  // 計算屬性	private get reversedMessage (): string[] { 	return this.message.split('').reverse().join('') } // Vuex 數據 @State((state: IRootState) => state . booking. currentStep) step!: number	@Getter( 'person/name') name!: name  // method public changeMessage (): void { this.message = 'Good bye' }, public getName(): string { let storeName = name return storeName }	// 生命周期 private created ():void { }, private mounted ():void { }, private updated ():void { }, private destroyed ():void { }}

正如你所看到的,我們在生命周期 列表那都添加 private XXXX 方法,因為這不應該公開給其他組件。

而不對 method 做私有約束的原因是,可能會用到 @Emit 來向父組件傳遞信息。

4.2 添加全局工具

引入全局模塊,需要改 main.ts :

import Vue from 'vue';import App from './App.vue';import router from './router';import store from './store';Vue.config.productionTip = false;new Vue({ router, store, render: (h) => h(App),}).$mount('#app');

npm i VueI18n

import Vue from 'vue';import App from './App.vue';import router from './router';import store from './store';// 新模塊import i18n from './i18n';Vue.config.productionTip = false;new Vue({ router,  store,  i18n, // 新模塊 render: (h) => h(App),}).$mount('#app');

但僅僅這樣,還不夠。你需要動 src/vue-shim.d.ts

// 聲明全局方法declare module 'vue/types/vue' { interface Vue { readonly $i18n: VueI18Next; $t: TranslationFunction; }}

之后使用 this.$i18n() 的話就不會報錯了。

4.3 Axios 使用與封裝

Axios的封裝千人千面

如果只是想簡單在Ts里體驗使用Axios,可以安裝vue-axios

簡單使用Axios

$ npm i axios vue-axios

main.ts添加:

import Vue from 'vue'import axios from 'axios'import VueAxios from 'vue-axios'Vue.use(VueAxios, axios)

然后在組件內使用:

Vue.axios.get(api).then((response) => { console.log(response.data)})this.axios.get(api).then((response) => { console.log(response.data)})this.$http.get(api).then((response) => { console.log(response.data)})

1. 新建文件 request.ts

文件目錄:

-api - main.ts // 實際調用-utils - request.ts // 接口封裝

2. request.ts 文件解析

import * as axios from 'axios';import store from '@/store';// 這里可根據具體使用的UI組件庫進行替換import { Toast } from 'vant';import { AxiosResponse, AxiosRequestConfig } from 'axios';  /* baseURL 按實際項目來定義 */const baseURL = process.env.VUE_APP_URL; /* 創建axios實例 */const service = axios.default.create({ baseURL, timeout: 0, // 請求超時時間 maxContentLength: 4000,});service.interceptors.request.use((config: AxiosRequestConfig) => { return config;}, (error: any) => { Promise.reject(error);});service.interceptors.response.use( (response: AxiosResponse) => { if (response.status !== 200) {  Toast.fail('請求錯誤!'); } else {  return response.data; } }, (error: any) => { return Promise.reject(error); }); export default service;

為了方便,我們還需要定義一套固定的 axios 返回的格式,新建 ajax.ts

export interface AjaxResponse { code: number; data: any; message: string;}

3. main.ts 接口調用:

// api/main.tsimport request from '../utils/request';// getexport function getSomeThings(params:any) { return request({ url: '/api/getSomethings', });}// postexport function postSomeThings(params:any) { return request({ url: '/api/postSomethings', methods: 'post', data: params });}

5. 編寫一個組件

為了減少時間,我們來替換掉 src/components/HelloWorld.vue ,做一個博客帖子組件:

<template>	<div class="blogpost">		<h2>{{ post.title }}</h2>		<p>{{ post.body }}</p>		<p class="meta">Written by {{ post.author }} on {{ date }}</p>	</div></template><script lang="ts">import { Component, Prop, Vue } from 'vue-property-decorator';// 在這里對數據進行類型約束export interface Post {	title: string;	body: string;	author: string;	datePosted: Date;}@Componentexport default class HelloWorld extends Vue {	@Prop() private post!: Post;	get date() {		return `${this.post.datePosted.getDate()}/${this.post.datePosted.getMonth()}/${this.post.datePosted.getFullYear()}`;	}}</script><style scoped>h2 { text-decoration: underline;}p.meta { font-style: italic;}</style>

然后在 Home.vue 中使用:

<template> <div class="home"> <img alt="Vue logo" src="../assets/logo.png"> 	<HelloWorld v-for="blogPost in blogPosts" :post="blogPost" :key="blogPost.title" /> </div></template><script lang="ts">import { Component, Vue } from 'vue-property-decorator';import HelloWorld, { Post } from '@/components/HelloWorld.vue'; // @ is an alias to /src@Component({ components: { HelloWorld, },})export default class Home extends Vue { private blogPosts: Post[] = [ {  title: 'My first blogpost ever!',  body: 'Lorem ipsum dolor sit amet.',  author: 'Elke',  datePosted: new Date(2019, 1, 18), }, {  title: 'Look I am blogging!',  body: 'Hurray for me, this is my second post!',  author: 'Elke',  datePosted: new Date(2019, 1, 19), }, {  title: 'Another one?!',  body: 'Another one!',  author: 'Elke',  datePosted: new Date(2019, 1, 20), }, ];}</script>

這時候運行項目:

這就是簡單的父子組件

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美孕妇毛茸茸xxxx| 亚洲女成人图区| 亚洲一级黄色片| 欧美日韩黄色大片| 亚洲欧美中文字幕在线一区| 欧美伊久线香蕉线新在线| 91av视频导航| 日本欧美黄网站| 欧洲精品毛片网站| 亚洲国产私拍精品国模在线观看| 国产精品福利久久久| 国产成人久久精品| 久久久久国产视频| 欧美专区在线播放| 久久偷看各类女兵18女厕嘘嘘| 亚洲欧美在线播放| 久久久久久久网站| 欧美成人黄色小视频| 久久久久久一区二区三区| 久久久国产精品亚洲一区| 欧美午夜丰满在线18影院| 久久精品亚洲94久久精品| 日韩精品久久久久久久玫瑰园| 精品小视频在线| 丝袜一区二区三区| 国产69久久精品成人| 97精品国产aⅴ7777| 亚洲最新av在线| 欧美日韩在线视频一区| 亚洲www在线| 亚洲国产精品成人va在线观看| 国产ts人妖一区二区三区| 欧美老女人在线视频| 国产一区av在线| 欧美香蕉大胸在线视频观看| 国产精品美女久久久久久免费| 亚洲精品日韩在线| 在线观看免费高清视频97| 久色乳综合思思在线视频| 亚洲精品在线不卡| 久久久视频免费观看| 欧美日韩加勒比精品一区| 国产91精品在线播放| 精品国产一区二区三区久久久狼| 国产日韩综合一区二区性色av| 久久久久九九九九| 亚洲欧美变态国产另类| 97在线视频免费| 国产精自产拍久久久久久蜜| 欧亚精品在线观看| 久久久精品一区二区| 日韩国产激情在线| 亚洲色图激情小说| 欧美一性一乱一交一视频| 国产一区二区激情| 中文字幕亚洲国产| 日韩欧美在线视频观看| 91欧美精品成人综合在线观看| 国产精品成人品| 中文字幕av一区中文字幕天堂| 久久久久国色av免费观看性色| 国产精品色视频| 亚洲高清免费观看高清完整版| 欧洲美女7788成人免费视频| 中文字幕亚洲综合久久筱田步美| 91在线观看免费高清| 色综合久久88| 国产精品扒开腿做爽爽爽男男| 欧洲成人免费视频| 日本成人精品在线| 日韩在线观看精品| 91免费人成网站在线观看18| 国产亚洲成av人片在线观看桃| 亚洲国产精品嫩草影院久久| 国产精品无码专区在线观看| 狠狠做深爱婷婷久久综合一区| 78色国产精品| 亚洲国产福利在线| 国产精品一香蕉国产线看观看| 日韩电影免费在线观看| 97热在线精品视频在线观看| 欧美裸身视频免费观看| 欧美中文字幕视频| 欧美精品精品精品精品免费| 懂色aⅴ精品一区二区三区蜜月| 日韩电影在线观看免费| 91国产视频在线播放| 高清欧美电影在线| 在线亚洲国产精品网| 九九久久久久99精品| 不卡av电影在线观看| 精品视频—区二区三区免费| 91在线看www| 午夜免费日韩视频| www.亚洲一二| 亚洲成人av片在线观看| 97久久精品在线| 国语自产偷拍精品视频偷| 国产视频久久久久| 欧美一级片在线播放| 国产裸体写真av一区二区| 青草青草久热精品视频在线观看| 中文字幕亚洲欧美在线| 日韩在线www| 欧美性受xxxx黑人猛交| 国产精品一区二区久久久| 日本三级韩国三级久久| 亚洲精品国产品国语在线| 亚洲色无码播放| 日韩在线小视频| 亚洲人成电影网站色| 国产精品日韩欧美大师| 国产欧美精品日韩精品| 中文字幕日本欧美| 91日本视频在线| 色一区av在线| 欧美日韩另类在线| 亚洲精品国产精品乱码不99按摩| 国产乱肥老妇国产一区二| 一本久久综合亚洲鲁鲁| 国产亚洲精品久久久| 亚洲国产精品久久久久久| 亚洲高清福利视频| 久久精品国产清自在天天线| 2019中文字幕在线| 久久成人人人人精品欧| 国产精品高潮视频| 91chinesevideo永久地址| 欧美性生交xxxxx久久久| 日韩黄色在线免费观看| 欧美一级黑人aaaaaaa做受| 久久亚洲精品视频| 精品久久中文字幕久久av| 日韩在线资源网| 欧美国产欧美亚洲国产日韩mv天天看完整| 久久久免费精品视频| 97精品国产aⅴ7777| 综合欧美国产视频二区| 欧美国产亚洲精品久久久8v| 最近2019好看的中文字幕免费| 欧美成人免费网| 91精品国产综合久久久久久蜜臀| 九九热这里只有在线精品视| 日韩在线视频网| 亚洲欧美另类人妖| 国产精品男女猛烈高潮激情| 日本精品一区二区三区在线播放视频| 欧美激情aaaa| 中文字幕免费国产精品| 日本欧美黄网站| 日本久久久a级免费| 久久久精品美女| 亚洲视频在线观看免费| 午夜免费在线观看精品视频| 国产精品日韩电影| 2019中文字幕在线观看| 欧美日韩爱爱视频| 欧美大尺度激情区在线播放| 欧美成人精品激情在线观看| 亚洲香蕉av在线一区二区三区| 久久综合免费视频影院| 欧美丝袜第一区| www欧美xxxx| 亚洲国产欧美一区二区丝袜黑人|