成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

10分鐘讓你快速上手Vue3

開發 前端
經過了漫長地迭代,Vue 3.0 終于在上 2020-09-18 發布了,帶了翻天覆地的變化,使用了 Typescript 進行了大規模的重構,帶來了 Composition API RFC 版本,類似 React Hook 一樣的寫 Vue,可以自定義自己的 hook ,讓使用者更加的靈活,接下來總結一下 vue 3.0 帶來的部分新特性。

經過了漫長地迭代,Vue 3.0 終于在上 2020-09-18 發布了,帶了翻天覆地的變化,使用了 Typescript 進行了大規模的重構,帶來了 Composition API RFC 版本,類似 React Hook 一樣的寫 Vue,可以自定義自己的 hook ,讓使用者更加的靈活,接下來總結一下 vue 3.0 帶來的部分新特性。

  1. setup()
  2. ref()
  3. reactive()
  4. isRef()
  5. toRefs()
  6. computed()
  7. watch()
  8. LifeCycle Hooks(新的生命周期)
  9. Template refs
  10. globalProperties
  11. Suspense

Vue2 與 Vue3 的對比

  • 對 TypeScript 支持不友好(所有屬性都放在了 this 對象上,難以推倒組件的數據類型)
  • 大量的 API 掛載在 Vue 對象的原型上,難以實現 TreeShaking。
  • 架構層面對跨平臺 dom 渲染開發支持不友好
  • CompositionAPI。愛 ReactHook 啟發
  • 更方便的支持了 jsx
  • Vue 3 的 Template 支持多個根標簽,Vue 2 不支持
  • 對虛擬 DOM 進行了重寫、對模板的編譯進行了優化操作...

一、setup 函數

setup() 函數是 vue3 中,專門為組件提供的新屬性。它為我們使用 vue3 的 Composition API 新特性提供了統一的入口, setup 函數會在 beforeCreate 之后、created 之前執行, vue3 也是取消了這兩個鉤子,統一用 setup 代替, 該函數相當于一個生命周期函數,vue 中過去的 data,methods,watch 等全部都用對應的新增 api 寫在 setup()函數中

 

  1. setup(props, context) { 
  2.     context.attrs 
  3.     context.slots 
  4.     context.parent 
  5.     context.root 
  6.     context.emit 
  7.     context.refs 
  8.  
  9.     return { 
  10.  
  11.     } 
  12.   } 
  • props: 用來接收 props 數據
  • context 用來定義上下文, 上下文對象中包含了一些有用的屬性,這些屬性在 vue 2.x 中需要通過 this 才能訪問到, 在 setup() 函數中無法訪問到 this,是個 undefined
  • 返回值: return {}, 返回響應式數據, 模版中需要使用的函數

二、reactive 函數

reactive() 函數接收一個普通對象,返回一個響應式的數據對象, 想要使用創建的響應式數據也很簡單,創建出來之后,在 setup 中 return 出去,直接在 template 中調用即可

  1. <template> 
  2.   {{name}} // test 
  3. <template> 
  4.  
  5. <script lang="ts"
  6. import { defineComponent, reactive, ref, toRefs } from 'vue'
  7. export default defineComponent({ 
  8.   setup(props, context) { 
  9.  
  10.     let state = reactive({ 
  11.       name'test' 
  12.     }); 
  13.  
  14.     return state 
  15.   } 
  16. }); 
  17. </script> 

三、ref() 函數

ref() 函數用來根據給定的值創建一個響應式的數據對象,ref() 函數調用的返回值是一個對象,這個對象上只包含一個 value 屬性, 只在 setup 函數內部訪問 ref 函數需要加.value

  1. <template> 
  2.     <div class="mine"
  3.         {{count}} // 10 
  4.     </div> 
  5. </template> 
  6.  
  7. <script lang="ts"
  8. import { defineComponent, ref } from 'vue'
  9. export default defineComponent({ 
  10.   setup() { 
  11.     const count = ref<number>(10) 
  12.     // 在js 中獲取ref 中定義的值, 需要通過value屬性 
  13.     console.log(count.value); 
  14.     return { 
  15.        count 
  16.     } 
  17.    } 
  18. }); 
  19. </script> 

在 reactive 對象中訪問 ref 創建的響應式數據

  1. <template> 
  2.     <div class="mine"
  3.         {{count}} -{{t}} // 10 -100 
  4.     </div> 
  5. </template> 
  6.  
  7. <script lang="ts"
  8. import { defineComponent, reactive, ref, toRefs } from 'vue'
  9. export default defineComponent({ 
  10.   setup() { 
  11.     const count = ref<number>(10) 
  12.     const obj = reactive({ 
  13.       t: 100, 
  14.       count 
  15.     }) 
  16.     // 通過reactive 來獲取ref 的值時,不需要使用.value屬性 
  17.     console.log(obj.count); 
  18.     return { 
  19.        ...toRefs(obj) 
  20.     } 
  21.    } 
  22. }); 
  23. </script> 

四、isRef() 函數

isRef() 用來判斷某個值是否為 ref() 創建出來的對象

  1. <script lang="ts"
  2. import { defineComponent, isRef, ref } from 'vue'
  3. export default defineComponent({ 
  4.   setup(props, context) { 
  5.     const name: string = 'vue' 
  6.     const age = ref<number>(18) 
  7.     console.log(isRef(age)); // true 
  8.     console.log(isRef(name)); // false 
  9.  
  10.     return { 
  11.       age, 
  12.       name 
  13.     } 
  14.   } 
  15. }); 
  16. </script> 

五、toRefs() 函數

toRefs() 函數可以將 reactive() 創建出來的響應式對象,轉換為普通的對象,只不過,這個對象上的每個屬性節點,都是 ref() 類型的響應式數據

 

  1. <template> 
  2.   <div class="mine"
  3.     {{name}} // test 
  4.     {{age}} // 18 
  5.   </div> 
  6. </template> 
  7.  
  8. <script lang="ts"
  9. import { defineComponent, reactive, ref, toRefs } from 'vue'
  10. export default defineComponent({ 
  11.   setup(props, context) { 
  12.     let state = reactive({ 
  13.       name'test' 
  14.     }); 
  15.  
  16.     const age = ref(18) 
  17.  
  18.     return { 
  19.       ...toRefs(state), 
  20.       age 
  21.     } 
  22.   } 
  23. }); 
  24. </script> 

六、computed()

該函數用來創造計算屬性,和過去一樣,它返回的值是一個 ref 對象。里面可以傳方法,或者一個對象,對象中包含 set()、get()方法

6.1 創建只讀的計算屬性

 

  1. import { computed, defineComponent, ref } from 'vue'
  2. export default defineComponent({ 
  3.   setup(props, context) { 
  4.     const age = ref(18) 
  5.  
  6.     // 根據 age 的值,創建一個響應式的計算屬性 readOnlyAge,它會根據依賴的 ref 自動計算并返回一個新的 ref 
  7.     const readOnlyAge = computed(() => age.value++) // 19 
  8.  
  9.     return { 
  10.       age, 
  11.       readOnlyAge 
  12.     } 
  13.   } 
  14. }); 
  15. </script> 

6.2 通過 set()、get()方法創建一個可讀可寫的計算屬性

  1. <script lang="ts"
  2. import { computed, defineComponent, ref } from 'vue'
  3. export default defineComponent({ 
  4.   setup(props, context) { 
  5.     const age = ref<number>(18) 
  6.  
  7.     const computedAge = computed({ 
  8.       get: () => age.value + 1, 
  9.       set: value => age.value + value 
  10.     }) 
  11.     // 為計算屬性賦值的操作,會觸發 set 函數, 觸發 set 函數后,age 的值會被更新 
  12.     age.value = 100 
  13.     return { 
  14.       age, 
  15.       computedAge 
  16.     } 
  17.   } 
  18. }); 
  19. </script> 

七、 watch() 函數

watch 函數用來偵聽特定的數據源,并在回調函數中執行副作用。默認情況是懶執行的,也就是說僅在偵聽的源數據變更時才執行回調。

7.1 監聽用 reactive 聲明的數據源

  1. <script lang="ts"
  2. import { computed, defineComponent, reactive, toRefs, watch } from 'vue'
  3. interface Person { 
  4.   name: string, 
  5.   age: number 
  6. export default defineComponent({ 
  7.   setup(props, context) { 
  8.     const state = reactive<Person>({ name'vue', age: 10 }) 
  9.  
  10.     watch( 
  11.       () => state.age, 
  12.       (age, preAge) => { 
  13.         console.log(age); // 100 
  14.         console.log(preAge); // 10 
  15.       } 
  16.     ) 
  17.     // 修改age 時會觸發watch 的回調, 打印變更前后的值 
  18.     state.age = 100 
  19.     return { 
  20.       ...toRefs(state) 
  21.     } 
  22.   } 
  23. }); 
  24. </script> 

7.2 監聽用 ref 聲明的數據源

  1. <script lang="ts"
  2. import { defineComponent, ref, watch } from 'vue'
  3. interface Person { 
  4.   name: string, 
  5.   age: number 
  6. export default defineComponent({ 
  7.   setup(props, context) { 
  8.     const age = ref<number>(10); 
  9.  
  10.     watch(age, () => console.log(age.value)); // 100 
  11.  
  12.     // 修改age 時會觸發watch 的回調, 打印變更后的值 
  13.     age.value = 100 
  14.     return { 
  15.       age 
  16.     } 
  17.   } 
  18. }); 
  19. </script> 

7.3 同時監聽多個值

  1. <script lang="ts"
  2. import { computed, defineComponent, reactive, toRefs, watch } from 'vue'
  3. interface Person { 
  4.   name: string, 
  5.   age: number 
  6. export default defineComponent({ 
  7.   setup(props, context) { 
  8.     const state = reactive<Person>({ name'vue', age: 10 }) 
  9.  
  10.     watch( 
  11.       [() => state.age, () => state.name], 
  12.       ([newName, newAge], [oldName, oldAge]) => { 
  13.         console.log(newName); 
  14.         console.log(newAge); 
  15.  
  16.         console.log(oldName); 
  17.         console.log(oldAge); 
  18.       } 
  19.     ) 
  20.     // 修改age 時會觸發watch 的回調, 打印變更前后的值, 此時需要注意, 更改其中一個值, 都會執行watch的回調 
  21.     state.age = 100 
  22.     state.name = 'vue3' 
  23.     return { 
  24.       ...toRefs(state) 
  25.     } 
  26.   } 
  27. }); 
  28. </script> 

7.4 stop 停止監聽

在 setup() 函數內創建的 watch 監視,會在當前組件被銷毀的時候自動停止。如果想要明確地停止某個監視,可以調用 watch() 函數的返回值即可,語法如下:

  1. <script lang="ts"
  2. import { set } from 'lodash'
  3. import { computed, defineComponent, reactive, toRefs, watch } from 'vue'
  4. interface Person { 
  5.   name: string, 
  6.   age: number 
  7. export default defineComponent({ 
  8.   setup(props, context) { 
  9.     const state = reactive<Person>({ name'vue', age: 10 }) 
  10.  
  11.     const stop =  watch( 
  12.       [() => state.age, () => state.name], 
  13.       ([newName, newAge], [oldName, oldAge]) => { 
  14.         console.log(newName); 
  15.         console.log(newAge); 
  16.  
  17.         console.log(oldName); 
  18.         console.log(oldAge); 
  19.       } 
  20.     ) 
  21.     // 修改age 時會觸發watch 的回調, 打印變更前后的值, 此時需要注意, 更改其中一個值, 都會執行watch的回調 
  22.     state.age = 100 
  23.     state.name = 'vue3' 
  24.  
  25.     setTimeout(()=> { 
  26.       stop() 
  27.       // 此時修改時, 不會觸發watch 回調 
  28.       state.age = 1000 
  29.       state.name = 'vue3-' 
  30.     }, 1000) // 1秒之后講取消watch的監聽 
  31.  
  32.     return { 
  33.       ...toRefs(state) 
  34.     } 
  35.   } 
  36. }); 
  37. </script> 

八、LifeCycle Hooks(新的生命后期)

新版的生命周期函數,可以按需導入到組件中,且只能在 setup() 函數中使用, 但是也可以在 setup 自定義, 在 setup 中使用

  1. <script lang="ts"
  2. import { set } from 'lodash'
  3. import { defineComponent, onBeforeMount, onBeforeUnmount, onBeforeUpdate, onErrorCaptured, onMounted, onUnmounted, onUpdated } from 'vue'
  4. export default defineComponent({ 
  5.   setup(props, context) { 
  6.     onBeforeMount(()=> { 
  7.       console.log('beformounted!'
  8.     }) 
  9.     onMounted(() => { 
  10.       console.log('mounted!'
  11.     }) 
  12.  
  13.     onBeforeUpdate(()=> { 
  14.       console.log('beforupdated!'
  15.     }) 
  16.     onUpdated(() => { 
  17.       console.log('updated!'
  18.     }) 
  19.  
  20.     onBeforeUnmount(()=> { 
  21.       console.log('beforunmounted!'
  22.     }) 
  23.     onUnmounted(() => { 
  24.       console.log('unmounted!'
  25.     }) 
  26.  
  27.     onErrorCaptured(()=> { 
  28.       console.log('errorCaptured!'
  29.     }) 
  30.  
  31.     return {} 
  32.   } 
  33. }); 
  34. </script> 

九、Template refs

通過 refs 來回去真實 dom 元素, 這個和 react 的用法一樣,為了獲得對模板內元素或組件實例的引用,我們可以像往常一樣在 setup()中聲明一個 ref 并返回它

  • 還是跟往常一樣,在 html 中寫入 ref 的名稱
  • 在steup 中定義一個 ref
  • steup 中返回 ref的實例
  • onMounted 中可以得到 ref的RefImpl的對象, 通過.value 獲取真實dom
  1. <template> 
  2.   <!--第一步:還是跟往常一樣,在 html 中寫入 ref 的名稱--> 
  3.   <div class="mine" ref="elmRefs"
  4.     <span>1111</span> 
  5.   </div> 
  6. </template> 
  7.  
  8. <script lang="ts"
  9. import { set } from 'lodash'
  10. import { defineComponent, onMounted, ref } from 'vue'
  11. export default defineComponent({ 
  12.   setup(props, context) { 
  13.     // 獲取真實dom 
  14.     const elmRefs = ref<null | HTMLElement>(null); 
  15.     onMounted (() => { 
  16.       console.log(elmRefs.value); // 得到一個 RefImpl 的對象, 通過 .value 訪問到數據 
  17.     }) 
  18.  
  19.     return { 
  20.       elmRefs 
  21.     } 
  22.   } 
  23. }); 
  24. </script> 

十、vue 的全局配置

通過 vue 實例上 config 的配置,包含 Vue 應用程序全局配置的對象。您可以在掛載應用程序之前修改下面列出的屬性:

 

  1. const app = Vue.createApp({})  
  2. app.config = {...} 

為組件渲染功能和觀察程序期間的未捕獲錯誤分配處理程序。錯誤和應用程序實例將調用處理程序

  1. app.config.errorHandler = (err, vm, info) => {} 

可以在應用程序內的任何組件實例中訪問的全局屬性,組件的屬性將具有優先權。這可以代替 Vue 2.xVue.prototype 擴展:

 

  1. const app = Vue.createApp({})  
  2. app.config.globalProperties.$http = 'xxxxxxxxs' 

可以在組件用通過 getCurrentInstance() 來獲取全局 globalProperties 中配置的信息,getCurrentInstance 方法獲取當前組件的實例,然后通過 ctx 屬性獲得當前上下文,這樣我們就能在 setup 中使用 router 和 vuex, 通過這個屬性我們就可以操作變量、全局屬性、組件屬性等等

 

  1. setup( ) { 
  2.   const { ctx } = getCurrentInstance(); 
  3.   ctx.$http 

十一、Suspense 組件

在開始介紹 Vue 的 Suspense 組件之前,我們有必要先了解一下 React 的 Suspense 組件,因為他們的功能類似。

React.lazy 接受一個函數,這個函數需要動態調用 import()。它必須返回一個 Promise,該 Promise 需要 resolve 一個 default export 的 React 組件。

 

  1. import React, { Suspense } from 'react'
  2.  
  3.  
  4. const myComponent = React.lazy(() => import('./Component')); 
  5.  
  6.  
  7. function MyComponent() { 
  8.   return ( 
  9.     <div> 
  10.       <Suspense fallback={<div>Loading...</div>}> 
  11.         <myComponent /> 
  12.       </Suspense> 
  13.     </div> 
  14.   ); 

Vue3 也新增了 React.lazy 類似功能的 defineAsyncComponent 函數,處理動態引入(的組件)。defineAsyncComponent 可以接受返回承諾的工廠函數。當您從服務器檢索到組件定義時,應該調用 Promise 的解析回調。您還可以調用 reject(reason)來指示負載已經失敗

 

  1. import { defineAsyncComponent } from 'vue' 
  2.  
  3. const AsyncComp = defineAsyncComponent(() => 
  4.   import('./components/AsyncComponent.vue'
  5.  
  6. app.component('async-component', AsyncComp) 

Vue3 也新增了 Suspense 組件:

  1. <template> 
  2.   <Suspense> 
  3.     <template #default
  4.       <my-component /> 
  5.     </template> 
  6.     <template #fallback> 
  7.       Loading ... 
  8.     </template> 
  9.   </Suspense> 
  10. </template> 
  11.  
  12. <script lang='ts'
  13.  import { defineComponent, defineAsyncComponent } from "vue"
  14.  const MyComponent = defineAsyncComponent(() => import('./Component')); 
  15.  
  16. export default defineComponent({ 
  17.    components: { 
  18.      MyComponent 
  19.    }, 
  20.    setup() { 
  21.      return {} 
  22.    } 
  23. }) 
  24.  
  25.  
  26. </script> 

十二、vue 3.x 完整組件模版結構

一個完成的 vue 3.x 完整組件模版結構包含了:組件名稱、 props、components、setup(hooks、computed、watch、methods 等)

 

  1. <template> 
  2.   <div class="mine" ref="elmRefs"
  3.     <span>{{name}}</span> 
  4.     <br> 
  5.     <span>{{count}}</span> 
  6.     <div> 
  7.       <button @click="handleClick">測試按鈕</button> 
  8.     </div> 
  9.  
  10.     <ul> 
  11.       <li v-for="item in list" :key="item.id">{{item.name}}</li> 
  12.     </ul> 
  13.   </div> 
  14. </template> 
  15.  
  16. <script lang="ts"
  17. import { computed, defineComponent, getCurrentInstance, onMounted, PropType, reactive, ref, toRefs } from 'vue'
  18.  
  19. interface IState { 
  20.   count: 0, 
  21.   name: string, 
  22.   list: Array<object> 
  23.  
  24. export default defineComponent({ 
  25.   name'demo'
  26.   // 父組件傳子組件參數 
  27.   props: { 
  28.     name: { 
  29.       type: String as PropType<null | ''>, 
  30.       default'vue3.x' 
  31.     }, 
  32.     list: { 
  33.       type: Array as PropType<object[]>, 
  34.       default: () => [] 
  35.     } 
  36.   }, 
  37.   components: { 
  38.     /// TODO 組件注冊 
  39.   }, 
  40.   emits: ["emits-name"], // 為了提示作用 
  41.   setup (props, context) { 
  42.     console.log(props.name
  43.     console.log(props.list) 
  44.  
  45.  
  46.     const state = reactive<IState>({ 
  47.       name'vue 3.0 組件'
  48.       count: 0, 
  49.       list: [ 
  50.         { 
  51.           name'vue'
  52.           id: 1 
  53.         }, 
  54.         { 
  55.           name'vuex'
  56.           id: 2 
  57.         } 
  58.       ] 
  59.     }) 
  60.  
  61.     const a = computed(() => state.name
  62.  
  63.     onMounted(() => { 
  64.  
  65.     }) 
  66.  
  67.     function handleClick () { 
  68.       state.count ++ 
  69.       // 調用父組件的方法 
  70.       context.emit('emits-name', state.count
  71.     } 
  72.  
  73.     return { 
  74.       ...toRefs(state), 
  75.       handleClick 
  76.     } 
  77.   } 
  78. }); 
  79. </script> 
  80.  
  81. <template> 
  82.   <div class="mine" ref="elmRefs"
  83.     <span>{{name}}</span> 
  84.     <br> 
  85.     <span>{{count}}</span> 
  86.     <div> 
  87.       <button @click="handleClick">測試按鈕</button> 
  88.     </div> 
  89.  
  90.     <ul> 
  91.       <li v-for="item in list" :key="item.id">{{item.name}}</li> 
  92.     </ul> 
  93.   </div> 
  94. </template> 
  95.  
  96. <script lang="ts"
  97. import { computed, defineComponent, getCurrentInstance, onMounted, PropType, reactive, ref, toRefs } from 'vue'
  98.  
  99. interface IState { 
  100.   count: 0, 
  101.   name: string, 
  102.   list: Array<object> 
  103.  
  104. export default defineComponent({ 
  105.   name'demo'
  106.   // 父組件傳子組件參數 
  107.   props: { 
  108.     name: { 
  109.       type: String as PropType<null | ''>, 
  110.       default'vue3.x' 
  111.     }, 
  112.     list: { 
  113.       type: Array as PropType<object[]>, 
  114.       default: () => [] 
  115.     } 
  116.   }, 
  117.   components: { 
  118.     /// TODO 組件注冊 
  119.   }, 
  120.   emits: ["emits-name"], // 為了提示作用 
  121.   setup (props, context) { 
  122.     console.log(props.name
  123.     console.log(props.list) 
  124.  
  125.  
  126.     const state = reactive<IState>({ 
  127.       name'vue 3.0 組件'
  128.       count: 0, 
  129.       list: [ 
  130.         { 
  131.           name'vue'
  132.           id: 1 
  133.         }, 
  134.         { 
  135.           name'vuex'
  136.           id: 2 
  137.         } 
  138.       ] 
  139.     }) 
  140.  
  141.     const a = computed(() => state.name
  142.  
  143.     onMounted(() => { 
  144.  
  145.     }) 
  146.  
  147.     function handleClick () { 
  148.       state.count ++ 
  149.       // 調用父組件的方法 
  150.       context.emit('emits-name', state.count
  151.     } 
  152.  
  153.     return { 
  154.       ...toRefs(state), 
  155.       handleClick 
  156.     } 
  157.   } 
  158. }); 
  159. </script> 

vue 3 的生態

  • 官網
  • 源碼
  • vite 構建器
  • 腳手架:https://cli.vuejs.org/
  • vue-router-next
  • vuex4.0

UI 組件庫

  • vant2.x
  • Ant Design of Vue 2.x
  • element-plus

 

10分鐘讓你快速上手Vue3

 

 

責任編輯:未麗燕 來源: 今日頭條
相關推薦

2023-09-08 07:54:01

TkinterPython

2023-09-11 08:25:57

PythonPyQt

2025-05-22 10:00:00

DockerRedis容器

2021-04-23 09:50:41

topLinux命令

2014-11-10 12:29:52

客服網站

2022-02-23 20:38:32

云原生集群Postgres

2024-08-07 10:16:00

2021-03-04 09:26:57

微服務架構數據

2021-01-07 08:05:20

JenkinsDevOps

2017-11-20 10:25:20

數據庫MySQL索引

2023-08-15 15:50:42

2017-06-07 18:40:33

PromiseJavascript前端

2009-11-05 10:56:31

WCF通訊

2009-11-25 09:02:12

2021-08-02 15:40:20

Java日志工具

2023-02-16 08:26:41

2022-03-04 16:06:33

數據庫HarmonyOS鴻蒙

2011-06-10 14:19:49

SEO百度收錄

2023-07-15 18:26:51

LinuxABI

2015-11-12 10:32:40

GitHub控制系統分布式
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 久操亚洲 | 国产精品久久久久久久久大全 | 2018天天干天天操 | 亚洲国产精品久久 | 亚洲一区综合 | 亚洲天堂av在线 | 日本精品久久久久久久 | 日韩激情在线 | 国产精品免费视频一区 | 秋霞电影院午夜伦 | 黄色大全免费看 | 国产精品91视频 | 成人av网站在线观看 | 久久久久久久久久久爱 | 精品伊人 | 男女下面一进一出网站 | 国产精品免费一区二区三区四区 | 一级爱爱片 | 欧美精品一区二区三区四区五区 | 日日操网站 | 亚洲国产精品一区 | 在线成人免费视频 | 国产视频一区在线 | 久久久精品久久 | 日韩中文字幕av | 亚洲 欧美 精品 | 国产欧美一区二区三区日本久久久 | 国产精品日产欧美久久久久 | 天天看天天爽 | 黄色在线| 国产亚洲精品久久情网 | 欧洲免费视频 | 日韩欧美在线视频 | 欧美日韩国产中文 | 中文字幕在线观看www | 亚洲精品日日夜夜 | 国产一区二区三区在线 | 99精品视频在线 | 黑人巨大精品欧美一区二区免费 | 国产美女永久免费无遮挡 | 午夜免费视频观看 |