整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          萬字長文詳解 Vue JSX,帶你全面擁抱 JSX 特性!

          什么要使用 JSX

          前陣子在 Vue3 項目中封裝一個基礎組件的時候用到了 JSX 語法,使用下來的感受就是 —— 某些場景下,JSX 的靈活性對我們編寫代碼還是能夠帶來一定的幫助的。

          舉兩個常見的例子:

          遞歸調用組件時

          假設我們現在有如下數據,需要渲染其中的 name 字段:

          const data = [
            { 
              name: 'name1', 
              children: [{ name: 'name1-1' }]
            },
            { name: 'name2' }
          ]
          


          普通模板寫法

          如果使用普通模板寫法,為了遞歸我們可能不得不編寫兩個組件:

          父組件 parent.vue:

          // parent.vue 父組件
          <template>
            <div>我是父組件</div>
            <Children v-for="item in data" :subData="item" :key="item.name"></Children>
          </template>
          


          子組件 children.vue 遞歸調用自身:

          // children.vue 子組件
          <template>
            <span>{{ subData.name }}</span>
              // 遞歸調用
            <template v-if="subData.children">
              <Children v-for="item in subData.children" :subData="item" :key="item.name"></Children>
            </template>
          </template>
          


          JSX 寫法:

          而使用 JSX 則可以靈活地使用一個文件實現遞歸的邏輯:

          // name.jsx
          const renderChildren = (data: any) => {
            return data.map((item: any) => {
              if (item.children) {
                return renderChildren(item.children)
              } else {
                return <span>{ item.name }</span>
              }
            })
          }
          const render = () => (
            <>
              <div>我是父組件</div>
              {
                data.map((item: any) => {
                  return (
                    <>
                      <span>{ item.name }</span>
                      { item.children && renderChildren(item.children) }
                    </>
                  )
                })
              }
            </>
          )
          


          動態生成標簽名稱

          這是一個來自 vue 官網中的例子,如果你需要根據傳入的 level 動態生成 <h1></h1> 到 <h6></h6> 之間的標簽。

          普通模板寫法

          你可能會這樣寫:

          <template>
              <h1 v-if="level === 1"></h1>  
              <h2 v-else-if="level === 2"></h2>  
              <h3 v-else-if="level === 3"></h3>  
              <h4 v-else-if="level === 4"></h4>  
              <h5 v-else-if="level === 5"></h5>  
              <h6 v-else-if="level === 6"></h6>
          </template>
          


          JSX 寫法

          但是如果學會了 JSX 的寫法,就可以像這樣:

          const render = () => {
            const level = props.level
            const Tag = `h${level}`
            return (
                <Tag></Tag>
            )
          }
          


          是不是瞬間簡潔了許多!省下來的時間又可以用來愉快的摸魚啦。

          那么接下來我們就來一起看看,如何在 Vue 中使用 JSX吧!

          開啟 JSX 特性

          vue-cli 搭建

          如果是使用 vue-cli 搭建的項目,默認就是支持 JSX 語法的,直接使用就可以。

          webpack

          如果不是 vue-cli 搭建的 webpack 項目,需要按照如下步驟開啟:

          下載 babel 插件

          npm install @vue/babel-plugin-jsx -D
          


          添加配置

          在 babel 的配置文件中添加:

          {
            "plugins": ["@vue/babel-plugin-jsx"]
          }
          


          根據版本的不同,babel 配置文件可能是 .babelrc 或者 babel.config.js,注意區分。

          vite

          使用 vite 的項目,同樣需要先安裝插件:

          npm install @vitejs/plugin-vue-jsx -D
          


          然后在 vite.config.js 文件中添加以下配置:

          // vite.config.js
          import vueJsx from '@vitejs/plugin-vue-jsx'
          
          export default {
            plugins: [
              vueJsx({
                // options are passed on to @vue/babel-plugin-jsx
              }),
            ],
          }
          


          更多的配置請參考 babel-plugin-jsx。

          JSX 語法

          使用 JS 表達式

          在 JSX 語法中,可以通過一對大括號 {} 來使用 JS 表達式:

          const name = 'zhangsan'
          // 通過一對大括號 {} 來包裹 JS 表達式內容
          const list1 = <div>{name}</div>
          
          // 同樣可以通過大括號 {} 來給標簽傳遞動態屬性
          const id = 1
          const list2 = <div id={id}>{name}</div>
          


          或許你還看到過雙大括號 {{}} 這種令人迷惑的寫法,其實它表示 綁定的是個 JS 對象

          const name = 'zhangsan'
          // 雙大括號 {{}} 表示的是綁定的是個 JS 對象
          // 可以拆分成 {} 和 { width: '100px' } 來理解
          const list1 = <div style={{width:'100px'}}>{name}</div>
          


          Fragment

          Vue3 新增了新特性 Fragment,使得我們在模板語法中能夠返回多個根節點:

          <template>
            <div>Fragment</div>
            <span>yes</span>
          </template>
          


          Vue 的編譯器在編譯時,會把這種包含多個根節點的模板被表示為一個片段(Fragment)。

          但是在 JSX 中,一組元素必須被包裹在一個閉合標簽中返回;因此下面這種寫法是不允許的:

          // 錯誤寫法 ?
          const render = () => (
            <div>Fragment</div>
            <span>yes</span>
          )
          


          正確做法是用一對閉合標簽包裹:

          // 正確寫法 ?
          const render = () => (
            <div>
              <div>Fragment</div>
              <span>yes</span>
            </div>
          )
          


          那如果我們不想引入額外的標簽該怎么辦呢?可以用 <></> 來包裹我們想要返回的內容,如下:

          const render = () => (
            <>
              <div>Fragment</div>
              <span>yes</span>
            </>
          )
          


          乍一看,你是不是覺得 <></> 和我們在使用模板寫法時的 <template></template> 作用很相似?

          但是實際上,JSX 中被 <></> 標簽包裹的內容,會被當做 Fragment 來處理;并且針對 Fragment Vue 在編譯和渲染時會有特定的優化策略。

          而對于 <template></template>,Vue 只會將其作為一個普通的元素渲染;所以要注意別搞混咯。

          Vue2 JSX 傳遞屬性

          在 Vue2 的時代,使用 JSX 時傳遞屬性還是比較麻煩的。

          因為 Vue2 中將屬性又細分成了 組件屬性、HTML Attribute 以及 DOM Property 等等,不同的屬性寫法也大相徑庭,如下:

          const render = () => {
            return (
              <div
                // 傳遞一個 HTML Attribute,屬性名稱是 id 屬性值是 'foo'
                id="foo"
                // 傳遞 DOM Property 需要使用前綴 `domProps` 來表示,這里表示傳遞給 innerHTML 這個 DOM 屬性的值為 ‘bar’
                domPropsInnerHTML="bar"
                // 綁定原生事件需要以 `on` 或者 `nativeOn` 為前綴,相當于 @click.native
                onClick={this.clickHandler}
                nativeOnClick={this.nativeClickHandler}
                // 綁定自定義事件需要用 `props` + 事件名 的方式
                propsOnCustomEvent={this.customEventHandler}
                // class(類名)、style(樣式)、key、slot 和 ref 這些特殊屬性寫法
                class={{ foo: true, bar: false }}
                style={{ color: 'red', fontSize: '14px' }}
                slot="slot"
                key="key"
                ref="ref"
                // 如果是循環生成的 ref(相當于 v-for),那么需要添加 refInFor 這個標識
                // 用來告訴 Vue 將 ref 生成一個數組,否則只能獲取到最后一個
                refInFor>
              </div>
            )
          }
          


          而在 Vue3 的 JSX 中傳遞各種屬性的方式已經簡化了許多,下面會拆開細講,各位小伙伴們請接著往下看~

          Vue3 JSX 傳遞屬性

          DOM Property

          傳遞 DOM Property 時去掉了 domProps 前綴,可以直接書寫:

          const render = () => {
            return (
              <div innerHTML="bar"></div>
            )
          }
          


          HTML Attribute

          Vue3 JSX 傳遞 HTML Attribute 與 Vue2 JSX 相同,直接書寫就行:

          const render = () => {
            return (
              <div id="foo" type="email"></div>
            )
          }
          


          如果需要動態綁定

          const placeholderText = 'email';
          const render = () => {
            return (
              <input
                type="email"
                placeholder={placeholderText} 
               />
            )
          };
          


          class 與 style

          Vue3 JSX 傳遞類名與樣式的方法,與 Vue2 JSX 相同:

          const render = () => {
            return (
              <div
                class={{ foo: true, bar: false }}
                style={{ color: 'red', fontSize: '14px' }}
              >
              </div>
            )
          }
          


          ref

          定義好 ref 后用 JS 表達式綁定就行:

          const divRef = ref()
          
          const render = () => {
            return (
              <div ref={divRef}></div>
            )
          }
          


          綁定事件

          在 Vue 模板寫法中,綁定事件時我們使用 v-on 或者 @ 符號:

          <template>
            <div @click="handleClick">事件綁定</div>
          </template>
          


          而在 Vue3 的 JSX 中,會把以 on 開頭,并緊跟著大寫字母的屬性當作事件監聽器來解析;

          上面的模板寫法換成 JSX 就是:

          const render = (
           <div onClick={handleClick}>事件綁定</div>
          )
          


          注意:這里一定要以 on 開頭,并且緊跟著大寫字母

          錯誤寫法 ?:onclick、click;

          正確寫法 ?:onClick、onClickChange、onClick-change (雖然但是,不會真的有人這么寫吧?)

          如果你不喜歡這種寫法,還可以通過打開 babel 的 transformOn 配置,然后通過屬性 on 綁定一個對象,一次性傳遞多個事件:

          babel 配置:

          // babel 配置
          {
            "plugins": [
              [
                "@vue/babel-plugin-jsx",
                {
                  "transformOn": true
                }
              ]
            ]
          }
          


          JSX 寫法:

          // 通過屬性 on 綁定對象 批量傳遞多個事件
          const render = () => (
            <div on={{ click: handleClick, input: handleInput }}> 事件綁定 </div>
          )
          


          事件修飾符

          對于 .passive、.capture 和 .once 事件修飾符,可以使用駝峰寫法將他們拼接在事件名稱后面

          比如 onClick + Once,就代表監聽 click 事件觸發,且只觸發一次:

          const render = () => (
            <input
              onClickCapture={() => {}}
              onKeyupOnce={() => {}}
              onMouseoverOnceCapture={() => {}}
            />
          )
          


          而像其余的 .self、.prevent 等事件和按鍵修飾符,則需要使用 withModifiers 函數。

          withModifiers 函數

          withModifiers 函數接收兩個參數:

          1. 第一個是我們的回調函數;
          2. 第二個參數是修飾符組成的數組。
          import { withModifiers } from 'vue'
          
          const count = ref(0)
          const render = () => (
            <input
              onClick={
                withModifiers(
                  // 第一個參數是回調函數
                  () => count.value++, 
                  // 第二個參數是修飾符組成的數組
                  ['self', 'prevent']
                )
              }
            />
          )
          


          上面的寫法就相當于我們在 Vue 模板中這樣寫:

          <template>
            <input @click.stop.prevent="() => count++" />
          </template>
          


          v-for

          在 JSX 中是沒有 v-for 這個自定義指令的,我們需要用 map 方法來替代

          const render = () => (
           <ul> 
             {
               items.value.map(({ id, text }) => { 
                 return (
                   <li key={id}>{text}</li> 
                 )
               })
             } 
           </ul>
          )
          


          上面的寫法,其實就相當于我們在模板中這樣寫:

          <ul>
            <li v-for="{ id, text } in items" :key="id">
              {{ text }}
            </li>
          </ul>
          


          v-if

          同樣,在 JSX 中也是沒有 v-if 這個指令的~

          但是細想一下,其實 v-if 的功能就是做判斷嘛,比如我們的模板長這樣:

          <div>
            <div v-if="ok">yes</div>
            <span v-else>no</span>
          </div>
          


          那么換成用 JSX 就可以使用 三元表達式 或者 && 連接符 來實現這個功能,我們可以這樣寫:

          // 使用三元表達式
          const render = () => (
            <div>
              { ok.value ? <div>yes</div> : <span>no</span> }
            </div>
          )
          // 使用 && 連接符
          const render = () => (
            <div>
              { ok.value && <div>yes</div> }
              { !ok.value && <span>no</span> }
            </div>
          )
          


          v-show

          可以直接使用v-show 指令,也可以寫成 vShow 這種形式:

          const show = ref(false)
          // v-show
          const render = () => (
            <div v-show={show}></div>
          )
          // 或者 vShow
          const render = () => (
            <div vShow={show}></div>
          )
          


          v-model

          正常情況下與我們在模板中使用 v-model 無異:

          const value = ref('')
          const render = () => (
            <input v-model={value} />
          )
          


          const value = ref('')
          // 將默認的 arg 從 modelValue 修改為 childrenProp
          const render = () => (
            <input v-model:childrenProp={value} />
          )
          


          修飾符

          但如果你需要在 JSX 中使用 v-model 的內置修飾符,如.lazy、.trim、.number,那么你需要傳遞一個數組

          const render = () => (
            <input v-model={[value, ['trim']]} />
          )
          


          如果你想同時修改默認 arg,并且使用修飾符;那么傳遞的數組的第二個參數需要定義為你設置的 arg,且是個字符串

          const render = () => (
            <input v-model={[value, 'childrenProp', ['trim']]} />
          )
          


          上面的寫法相當于模板中:

          <input v-model:childrenProp.trim="value"></input>
          


          自定義指令

          JSX 中自定義指令的使用方法和 v-model 十分相似,只需要把 v-model 替換成你對應的自定義指令就可以啦:

          const App = {
            directives: { custom: customDirective },
            setup() {
              const value = ref()
              return () => <children v-custom:childrenProp={value} />;
            },
          };
          


          修飾符

          帶修飾符的自定義指令,寫法如下:

          const App = {
            directives: { custom: customDirective },
            setup() {
              const value = ref()
              return () => (
                <children v-custom={[value, 'childrenProp', ['a', 'b']]} />;
              )
            },
          };
          


          插槽

          在 Vue3 的 jsx 中,使用插槽同樣分為兩步走:

          預留插槽

          首先,在接收插槽的組件中,給插槽留個“座位”;我們可以從 setup 函數的第二個參數解構出 slots,拿到外部傳入的所有插槽:

          // 自定義組件 customComp.jsx
          export default {
            name: 'CustomComp',
            props: ['message'],
            // 外部傳入的插槽信息都在 slots 中
            setup(props, { slots }) {
              return () => (
                <>
                  // 傳入的 default 默認插槽會被展示這里,如果沒有傳入默認插槽,則展示文本 foo
                  <h1>{slots.default ? slots.default() : 'foo'}</h1>
                  // 傳入的具名插槽 bar 會被展示在這里
                  <h2>{slots.bar?.()}</h2>
                  // 作用域插槽 footer,外部可以通過作用域拿到 text 的值
                  <h2>{slots.footer?.({ text: props.message })}</h2>
                </>
              )
            }
          }
          


          傳入插槽

          在 Vue3 的 jsx 中傳入插槽時,需要使用 v-slots 代替 v-slot

          // 定義好我們需要的插槽
          const slots = {
            // 這部分內容會傳到具名插槽 bar 中
            bar: () => <span>B</span>,
            // 這部分內容會傳到作用域插槽 footer 中
            footer: ({ text }) => <span>{text}</span> 
          };
          const render = () => (
            // 使用 v-slots 將定義好的插槽 slots 傳入自定義組件 CustomComp
            <CustomComp v-slots={slots}>
               // 這部分內容,會傳入組件 CustomComp 的默認插槽中
              <div>A</div>
            </CustomComp>
          );
          


          或者還可以直接用一個對象同時定義好默認插槽和具名插槽:

          export default {
            setup() {
              // 將默認插槽和具名插槽用對象的形式定義好:
              const slots = {
                default: () => <div>A</div>,
                bar: () => <span>B</span>,
                // 作用域插槽,能夠拿到對應的信息 text
                footer: ({ text }) => <span>{text}</span> 
              };
              // 直接使用 v-slots 將整個插槽對象傳遞給自定義組件 CustomComp
              return () => <CustomComp v-slots={slots} />
            }
          }
          


          另外,如果 babel 的配置項 enableObjectSlots 不為 false 時,傳入多個插槽還可以寫成對象的形式,對象的 key 為插槽名稱, value 為一個函數,函數的返回就是插槽的默認占位

          修改 babel 配置:

          {
            "plugins": [
              [
                "@vue/babel-plugin-jsx",
                {
                  "enableObjectSlots": true
                }
              ]
            ]
          }
          


          jsx 具體寫法:

          const render = () => (
            <>
              <CustomComp>
                {{
                  // 給自定義組件 CustomComp 傳入一個默認插槽,內容是 <div>A</div>
                  default: () => <div>A</div>, 
                  // 給自定義組件 CustomComp 傳入一個具名插槽 bar,內容是 <span>B</span>
                  bar: () => <span>B</span>,
                  // 給自定義組件 CustomComp 傳入一個具名插槽 footer,內容是 <span>B</span>
                  footer: ({ text }) => <span>{ text }</span>,
                }}
              </CustomComp>
              // 相當于: {{ default: () => 'foo' }},給自定義組件 CustomComp 傳入了一個默認插槽
              <CustomComp>{() => 'foo'}</CustomComp>
            </>
          )
          


          以函數的形式傳遞插槽,子組件就可以懶調用這些插槽了。

          在 Vue3 中使用 JSX

          在函數式組件中使用

          在函數式組件中使用 JSX 十分簡單,直接返回相關內容就行:

          const App = () => <div></div>;
          


          在 SFC 中使用

          我們知道 Vue3 中的 setup 函數如果 返回的是個函數,那么這個函數的返回值會被作為模板內容渲染,并且會忽略 template 的內容。

          因此在普通的單文件組件中,我們可以直接在 setup 函數中返回我們的 JSX 內容:

          import { defineComponent } from 'vue';
          
          const App = defineComponent({
            setup() {
              const count = ref(0);
          
              return () => (
                <div>{count.value}</div>
              );
            },
          });
          


          以上就是 Vue3 中使用 JSX 的全部內容啦!如果文章對你有幫助的話,還希望各位小伙伴不要吝嗇你的贊~

          另外,如果文章有紕漏 or 你有任何疑惑,都歡迎在評論區討論。


          作者:hprep
          鏈接:https://juejin.cn/post/7272308621710213161

          文:https://www.cnblogs.com/dadouF4/p/10032888.html

          JavaScript:

          基本概念:

          JavaScript一種直譯式腳本語言,是一種動態類型、弱類型、基于原型的語言,內置支持類型。它的解釋器被稱為JavaScript引擎,為瀏覽器的一部分,廣泛用于瀏覽器客戶端的腳本語言。

          組成部分

          ECMAScript,描述了該語言的語法和基本對象。

          文檔對象模型(DOM),描述處理網頁內容的方法和接口。

          瀏覽器對象模型(BOM),描述與瀏覽器進行交互的方法和接口。

          基本特點

          JavaScript是一種屬于網絡的腳本語言,已經被廣泛用于Web應用開發,常用來為網頁添加各式各樣的動態功能,為用戶提供更流暢美觀的瀏覽效果。通常JavaScript腳本是通過嵌入在HTML中來實現自身的功能的。

          是一種解釋性腳本語言(代碼不進行預編譯)。

          主要用來向HTML(標準通用標記語言下的一個應用)頁面添加交互行為。

          可以直接嵌入HTML頁面,但寫成單獨的js文件有利于結構和行為的分離。

          跨平臺特性,在絕大多數瀏覽器的支持下,可以在多種平臺下運行(如Windows、Linux、Mac、Android、iOS等)。

          Javascript腳本語言同其他語言一樣,有它自身的基本數據類型,表達式和算術運算符及程序的基本程序框架。Javascript提供了四種基本的數據類型和兩種特殊數據類型用來處理數據和文字。而變量提供存放信息的地方,表達式則可以完成較復雜的信息處理。

          日常用途

          嵌入動態文本于HTML頁面。

          對瀏覽器事件做出響應。

          讀寫HTML元素。

          在數據被提交到服務器之前驗證數據。

          檢測訪客的瀏覽器信息。

          控制cookies,包括創建和修改等。

          基于Node.js技術進行服務器端編程。

          TypeScript:

          基本概念:

          TypeScript是一種由微軟開發的自由和開源的編程語言。它是JavaScript的一個超集,而且本質上向這個語言添加了可選的靜態類型和基于類的面向對象編程。安德斯·海爾斯伯格,C#的首席架構師,已工作于TypeScript的開發。

          TypeScript擴展了JavaScript的語法,所以任何現有的JavaScript程序可以不加改變的在TypeScript下工作。TypeScript是為大型應用之開發而設計,而編譯時它產生 JavaScript 以確保兼容性。

          TypeScript 支持為已存在的 JavaScript 庫添加類型信息的頭文件,擴展了它對于流行的庫如 jQuery,MongoDB,Node.js 和 D3.js 的好處。

          特性

          類 Classes

          接口 Interfaces

          模塊 Modules

          類型注解 Type annotations

          編譯時類型檢查 Compile time type checking

          Arrow 函數 (類似 C# 的 Lambda 表達式)

          JavaScript 與 TypeScript 的區別

          TypeScript 是 JavaScript 的超集,擴展了 JavaScript 的語法,因此現有的 JavaScript 代碼可與 TypeScript 一起工作無需任何修改,TypeScript 通過類型注解提供編譯時的靜態類型檢查。

          TypeScript 可處理已有的 JavaScript 代碼,并只對其中的 TypeScript 代碼進行編譯。

          JSX:

          JSX就是Javascript和XML結合的一種格式。React發明了JSX,利用HTML語法來創建虛擬DOM。當遇到<,JSX就當HTML解析,遇到{就當JavaScript解析。

          jsx常用語法:

          • 在 { },內寫js表達式
          • 代碼注釋寫法: { /* 注釋內容 */ }
          • HTML顯示: 空格顯示: 可以使用Unicode轉碼
          • HTML顯示: <div dangerouslySetInnerHTML={{__html: html}} />
          • 樣式綁定:通過style屬性來定義,但和真實DOM不同的是,屬性值不能是字符串而必須為對象。<div style={{color: '#ff0000', fontSize: '14px'}}>Hello World.</div>
          • 事件綁定:JSX采用駝峰寫法來描述事件名稱,大括號中是標準的JavaScript表達式,返回一個事件處理函數。<button onClick={this.checkAndSubmit.bind(this)}>Submit</button>

          擊上方藍字關注“小鄭搞碼事”,每天都能學到知識,搞懂一個問題!

          從寫React項目開始,我們熟悉了一種語法,叫JSX,它很好的將邏輯和模板融合在一起。當然,有一點我們應該很清楚,在React項目開發的時候,我們可以使用JSX來編寫代碼,也可以使用純JavaScript來編寫代碼,這樣的話,即使不學JSX也可以正常開發React項目。

          然而,facebook官方推薦我們使用JSX來寫React代碼。為什么呢?下面從四個方面介紹,帶你學會使用JSX。

          一、JSX如何區分React組件和HTML標簽

          HTML類型的標簽第一個字母用小寫來表示,React組件標簽第一個字母用大寫來表示。

          比如:

          上面代碼是一個HTML類型的標簽定義,需要知道兩點:

          第一,當一個標簽里面內容為空的時候,可以直接使用自閉和標簽;

          第二,因為JSX本身是JavaScript語法,所以一些JavaScript中的保留字要用其他的方式書寫,就像上面class要寫成className。

          這里寫的是一個React組件,注意名字第一個字母大寫。

          二、JSX中JavaScript表達式如何定義

          標簽對標簽(或組件名),{}對JS代碼,無屬性默認為true

          什么意思了?就是說在JSX語法中,當遇到標簽的時候就解釋成組件或HTML標簽,當遇到{}包裹的時候就當成JavaScript代碼來執行。

          比如:

          上面代碼中,{}內會當表達式處理,isLoggIn為true時輸出組件<Nav/>否則輸出<LoginForm/>

          當省略一個屬性的值的時候,如<Nav isDisable/>。JSX會自動把它的值認為是true(isDisable=true)。

          三、JSX注釋如何寫

          在子組件中寫注釋的時候要用{}

          比如:

          四、多屬性如何定義

          用“三點”操作符來簡化多個屬性的編寫。舉個例子:

          顯然,上面這種寫法,當出現更多屬性的時候,會顯得很難看。下面看一個更優雅的寫法。


          主站蜘蛛池模板: 亚洲香蕉久久一区二区| 变态拳头交视频一区二区| 日韩一区二区三区在线观看| 国产精品丝袜一区二区三区| 男人的天堂精品国产一区| 精品少妇ay一区二区三区| av无码人妻一区二区三区牛牛| 国产在线一区二区三区av| 亚洲一区二区三区国产精华液| 鲁丝片一区二区三区免费| 一区二区不卡视频在线观看| 欧洲精品一区二区三区| 亚洲欧美日韩国产精品一区 | 亚洲av无码不卡一区二区三区 | 高清一区二区三区免费视频| 精品一区二区三区高清免费观看| 日韩一区二区三区电影在线观看 | 日韩动漫av在线播放一区| 男人的天堂av亚洲一区2区| 亚洲一区二区三区免费观看| 色偷偷av一区二区三区| 亚洲成AV人片一区二区| 高清国产AV一区二区三区| 国产熟女一区二区三区四区五区| 国产精品一区二区三区免费| 国产一区高清视频| 日本精品一区二区三区四区| 国产福利电影一区二区三区,日韩伦理电影在线福 | 99精品国产一区二区三区2021 | 视频一区在线播放| 日本一区二区三区免费高清在线| 精品91一区二区三区| 日本免费精品一区二区三区| 亚洲一区精品伊人久久伊人| 狠狠综合久久AV一区二区三区| 国产视频一区二区在线播放| 亚洲国产高清在线精品一区| 麻豆AV天堂一区二区香蕉| 国产一区二区三区电影| 国产亚洲欧洲Aⅴ综合一区| 久久久综合亚洲色一区二区三区|