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

從前端視角看 SwiftUI

開發 前端
從 UI 的角度來看,前端與手機開發會遇到問題是類似的,盡管使用的語言或是開發手法不盡相同,我們都需要打造一個易用的使用者介面。

前言

我對 iOS 開發、手機開發、SwiftUI 開發經驗有限,若有理解錯誤的部分歡迎指正。

從 UI 的角度來看,前端與手機開發會遇到問題是類似的,盡管使用的語言或是開發手法不盡相同,我們都需要打造一個易用的使用者介面。既然如此,彼此也會遇到類似的問題,元件化開發、狀態管理、資料流、管理副作用(API 或是IO)等等,對我來說是個很適合互相學習的領域。

從過往的經驗可以發現,像是 ReSwift[1](Redux 的中心思想)這樣的函式庫,或多或少也借鑒了前端不斷演進的開發手法,不難看出雙方會遇到的問題其實有類似的地方。

雖然這個時間點提起已經有點后話了,但還是想把我入門 SwiftUI 后的感想寫下。

SwiftUI 與 React 的類似之處

我們可以將前端框架歸納為幾個要素:

  • 元件化
  • 響應式機制
  • 狀態管理
  • 事件監聽
  • 生命周期

在下面的段落中,我們也會以這幾個主題為核心做討論。為了不模糊焦點,我會盡可能只用 React 當做舉例,但套用到其他前端框架原理應該也相同。

從 class 邁向 struct;從 class 邁向 function

在寫 SwiftUI 的時候總是讓我想到 React 的發展史。最初 React 建立元件的方式是透過 JavaScript 的 class 語法,每個 React 的元件都是一個類別。


class MyComponent extends React.Component {
constructor() {
this.state = {
name: 'kalan'
}
}

componentDidMount() {
console.log('component is mounted')
}

render() {
return <div>my name is {this.state.name}</div>
}
}

透過類別定義元件雖為前端元件化帶來了很大的影響,但也因為繁瑣的方法定義與 this 混淆,在 React16 hooks 出現之后,逐漸提倡使用 function component 與 hooks 的方式來建立元件。

省去了繼承與各種 OO 的花式設計模式,建構元件的心智負擔變得更小了。從 SwiftUI 當中我們也可以看到類似的演進,原本 ViewController 龐大的 class 以及職責,要負責 view 與 model 的互動,掌管生命周期,轉為更輕量的 struct,讓開發者可以更專注在 UI 互動上,減輕認知負擔。

元件狀態管理

React 16 采取了 hooks 來做元件的邏輯復用與狀態管理,例如 useState。

const MyComponent = () => {
const [name, setName] = useState({ name: 'kalan' })
useEffect(() => { console.log('component is mounted') }, [])

return <div>my name is {name}</div>
}

在 SwiftUI 當中,我們可以透過修飾符 @State 讓 View 也具有類似效果。兩者都具備響應式機制,當狀態變數發生改變時,React/Vue 會偵測改變并反映到畫面當中。雖然不知道 SwiftUI 背后的實作,但背后應該也有類似 diff 機制的東西來達到響應式機制與最小更新的效果。

然而 SwiftUI 的狀態管理與 React hooks 仍有差異。在 React 當中我們可以將 hook 拆成獨立的函數,并且在不同的元件當中使用,例如:

function useToggle(initialValue) {
const [toggle, set] = useState(initialValue)
const setToggle = useCallback(() => { set((state) => !state) }, [toggle])
useEffect(() => { console.log('toggle is set') }, [toggle])
return [toggle, setToggle]
}
const MyComponent = () => {
const [toggle, setToggle] = useToggle(false)
return <button onClick={() => setToggle()}>Click me</button>
}
const MyToggle = () => {
const [toggle, setToggle] = useToggle(true)
return <button onClick={() => setToggle()}>Toggle, but fancy one</button>
}

在 React 當中,我們可以將 toggle 的邏輯拆出,并在不同元件之間使用。由于 useToggle 是一個純函數,因此內部的狀態也不會互相影響。

然而在 SwiftUI 當中 @State 只能作用在 struct 的 private var 當中,不能進一步拆出。如果想要將重復的邏輯抽出,需要另外使用 @Observable 與 @StateObject 這樣的修飾符,另外建立一個類別來處理。

class ToggleUtil: ObservableObject {
@Published var toggle = false

func setToggle() {
self.toggle = !self.toggle
}
}
struct ContentView: View {
@StateObject var toggleUtil = ToggleUtil()
var body: some View {
Button("Text") {
toggleUtil.setToggle()
}
if toggleUtil.toggle {
Text("Show me!")
}
}
}

在這個例子當中把 toggle 的邏輯拆成一個 class 似乎有點小題大作了,不過仔細想想像 React 提供的 hook 功能,讓輕量的邏輯共用就算單獨拆成 hook 也不會覺得過于冗長,若要封裝更復雜的邏輯也可以再拆分成更多 hooks,從這點來看 hook 的確是一個相當優秀的機制。后來看到了 SwiftUI-Hooks[2],不知道實際使用的效果如何。

以 React 來說,在還沒有出現 hooks 之前,主要有三個方式來實作邏輯共用:

  • HOC(Higher Order Component)[3]:將共同邏輯包裝成函數后返回全新的 class,避免直接修改元件內部的實作。例如早期 react-redux 中的 connect。
  • render props[4]:將實際渲染的元件當作屬性(props)傳入,并提供必要的參數供實作端使用。
  • children function:children 只傳入必要的參數,由實作端自行決定要渲染的元件。

盡管 hooks 用更優雅的方式解決邏輯共用的問題,我認為上面的開發手法演變也很值得參考。

Redux 與 TCA

受到 Redux 的影響,在 Swift 當中也有部分開發者使用了采用了類似手法,甚至也有相對應的實作 ReSwift的說明文。從說明文可以看到主要原因。傳統的 ViewController 職責曖昧,容易變得肥大導致難以維護,透過 Reducer、Action、Store 訂閱來確保單向資料流,所有的操作都是向 store dispatch 一個action,而資料的改動(mutation)則在 reducer 處理。

而最近的趨勢似乎從 Redux 演變成了 TCA(The Composable Architecture),跟 Redux 的中心思想類似,更容易與 SwiftUI 整合,比較不一樣的地方在于以往涉及 side effect 的操作在 Redux 當中會統一由 middleware 處理,而在 TCA 的架構中 reducer 可以回傳一個 Effect,代表接收 action 時所要執行的 IO 操作或是 API 呼叫。

既然采用了類似 redux 的手法,不知道 SwiftUI 是否會遇到與前端開發類似的問題,例如 immutability 確保更新可以被感知;透過優化 subscribe 機制確保 store 更新時只有對應的元件會更新;reducer 與 action 帶來的 boilerplate 問題。

雖然 Redux 在前端仍然具有一定地位,也仍然有許多公司正在導入,然而在前端也越來越多棄用 Redux 的聲音,主要因為 redux 對 pure function 的追求以及 reducer、action 的重復性極高,在應用沒有到一定復雜程度之前很難看出帶來的好處,甚至連 Redux 作者本人也開始棄坑 redux 了 4。與此同時,react-redux 仍然有在持續更新,也推出了 redux-toolkit 來試圖解決導入 redux 時常見的問題。

取而代之的是更加輕量的狀態管理機制,在前端也衍生出了幾個流派:

  • GraphQL → 使用 apollo[5] 或是 relay[6]
  • react-query[7]
  • react-swr[8]
  • recoil[9]
  • jotai[10]

全域狀態管理

在全域狀態管理上,SwiftUI 也有內建機制叫做 @EnvrionmentObject,其運作機制很像 React 的 context,讓元件可以跨階層存取變數,當 context 改變時也會更新元件。

class User: ObservableObject {
@Published var name = "kalan"
@Published var age = 20
}
struct UserInfo: View {
@EnvironmentObject var user: User
var body: some View {
Text(user.name)
Text(String(user.age))
}
}
struct ContentView: View {
var body: some View {
UserInfo()
}
}
ContentView().envrionmentObject(User())

從上面這個范例可以發現,我們不需要另外傳入 user 給 UserInfo,透過 @EnvrionmentObject 可以拿到當前的 context。轉換成 React 的話會像這樣:

const userContext = createContext({})
const UserInfo = () => {
const { name, age } = useContext(userContext)
return <>
<p>{name}</p>
<p>{age}</p>
</>
}
const App = () => {
<userContext.Provider value={{ user: 'kalan', age: 20 }}>
<UserInfo />
</userContext.Provider>
}

React 的 context 可讓元件跨階層存取變數,當 context 改變時也會更新元件。雖然有效避免了 prop drilling 的問題,然而 context 的存在會讓測試比較麻煩一些,因為使用 context 時代表了某種程度的耦合。

響應機制

在 React 當中,狀態或是 props 有變動時都會觸發元件更新,透過框架實作的 diff 機制比較后反映到畫面上。在 SwfitUI 中也可以看到類似的機制:

struct MyView: View {
var name: String
@State private var isHidden = false

var body: some View {
Toggle(isOn: $isHidden) {
Text("Hidden")
}
Text("Hello world")

if !isHidden {
Text("Show me \(name)")
}
}
}

一個典型的 SwiftUI 元件是一個 struct,透過定義 body 變數來決定 UI。跟 React 相同,他們都只是對 UI 的抽象描述,透過比對資料結構計算最小差異后,再更新到畫面上。

我還蠻想了解 SwiftUI 背后是怎么計算 diff 的,希望之后有類似的文章出現

@State 修飾符可用來定義元件內部狀態,當狀態改變時會更新并反映到畫面中。

在 SwiftUI 當中,屬性(MyView 當中的 name)可以由外部傳入,跟 React 當中的屬性(props)類似。

// 在其他 View 當中使用 MyView
struct ContentView: View {
var body: some View {
MyView(name: "kalan")
}
}

用 React 改寫這個元件的話會像這樣:

const MyView = ({ name }) => {
const [isHidden, setIsHidden] = useState(false)
return <div>
<button onClick={() => setIsHidden(state => !state)}>hidden</button>
<p>Hello world</p>
{isHidden ? null : `show me ${name}`}
</div>
}

在撰寫 SwiftUI 時會發現這跟以往用 UIKit、UIController 的開發方式不太一樣。

列表

SwiftUI 與 React 當中都可以渲染列表,而撰寫的方式也有雷同之處。在 SwiftUI 當中可以這樣寫:

struct TextListView: View {
var body: some View {
List {
ForEach([
"iPhone",
"Android",
"Mac"
], id: \.self) { value in
Text(value)
}
}
}
}

轉成 React 大概會像這樣子:

const TextList = () => {
const list = ['iPhone', 'Android', 'Mac']

return list.map(item => <p key={item}>{item}</p>)
}

在渲染列表時為了確保效能,減少不必要的比對,React 會要求開發者提供 key,而在 SwiftUI 當中也有類似的機制,開發者必須使用叫做 Identifiable[11] 的 protocol,或是顯式地傳入 id。

Binding

除了將變數綁定到畫面之外,我們也可以將互動綁定到變數之中。例如在 SwiftUI 當中我們可以這樣寫:

struct MyInput: View {
@State private var text = ""
var body: some View {
TextField("Please type something", text: $text)
}
}

在這個范例當中,就算不監聽輸入事件,使用 $text 也可以直接改變 text 變數,當使用 @State 時會加入 property wrapper,會自動加入一個前綴 $,型別為 Binding[12]。

React 并沒有雙向綁定機制,必須要顯式監聽輸入事件確保單向資料流。不過像 Vue、Svelte 都有雙向綁定機制,節省開發者手動監聽事件的成本。

Combine 的出現

雖然我對 Combine 還不夠熟悉,但從官方文件與影片看起來,很像RxJS 的 Swift 特化版,提供的 API 與操作符大幅度地簡化了復雜資料流。這讓我想起了以前研究 RxJS 與 redux-observable 各種花式操作的時光,真令人懷念。

本質上的差異

前面提到那么多,然而網頁與手機開發仍然有相當大的差異,其中對我來說最顯著的一點是靜態編譯與動態執行。動態執行可以說是網頁最大的特色之一。

只要有瀏覽器,JavaScript、HTML、CSS,不管在任何裝置上都可以成功執行,網頁不需要事先下載 1xMB ~ 幾百 MB 的內容,可以動態執行腳本,根據瀏覽的頁面動態載入內容。

由于不需要事先編譯,任何人都可以看到網頁的內容與執行腳本,加上 HTML 可以 streaming 的特性,可以一邊渲染一邊讀取內容。難能可貴的一點是,網頁是去中心化的,只要有伺服器、ip 位址與網域,任何人都可以存取網站內容;而 App 如果要上架必須事先通過審查。

不過兩者的生態圈與開發手法有很大的不同,仍然建議參考一下彼此的發展,就算平時不會碰也沒關系,從不同的角度看往往可以發現不同的事情,也可以培養對技術的敏銳度。

參考資料

[1] ReSwift: https://github.com/ReSwift/ReSwift

[2] SwiftUI-Hooks: https://github.com/ra1028/SwiftUI-Hooks

[3] HOC(Higher Order Component): https://zh-hant.reactjs.org/docs/higher-order-components.html

[4] render props: https://zh-hant.reactjs.org/docs/render-props.html

[5] apollo: https://github.com/apollographql/apollo-client

[6] relay: https://relay.dev/

[7] react-query: https://react-query.tanstack.com/

[8] react-swr: https://swr.vercel.app/zh-CN

[9] recoil: https://recoiljs.org/

[10] jotai: https://github.com/pmndrs/jotai

[11] Identifiable: https://developer.apple.com/documentation/swift/identifiable

[12] Binding: https://developer.apple.com/documentation/swiftui/binding

責任編輯:姜華 來源: Swift社區
相關推薦

2022-11-01 09:02:04

前端售后業務

2024-02-28 08:38:07

Rust前端效率

2023-03-31 09:02:37

前端客服通信

2011-01-21 17:09:06

Zimbra

2021-05-07 10:25:04

技術開發低代碼無代碼

2024-02-27 13:03:38

前端視頻合成FFmpeg

2024-06-18 13:36:29

2025-03-26 09:41:19

2024-01-08 20:05:32

2017-10-27 15:48:06

JavaScript前端全端

2021-03-15 06:24:22

Nacos集群搭建微服務

2022-01-13 10:19:34

軟件汽車 技術

2021-05-07 09:00:02

Go項目標準

2011-12-29 09:24:54

iOS應用下載排行榜

2011-07-15 15:18:06

微博Twitter

2021-03-07 17:17:07

Java內存閉包

2019-05-07 09:17:51

AWS西云數據IaaS

2020-05-13 08:48:16

JavaScript前端技術

2020-11-11 09:19:37

前端優化面試

2021-07-30 19:07:27

大數據云計算云原生化
點贊
收藏

51CTO技術棧公眾號

中国老女人av| 国产精品99导航| 久久久久9999| **国产精品| 午夜影视日本亚洲欧洲精品| 视频一区二区三区免费观看| 亚洲精品成人电影| 日本视频免费一区| 久久全国免费视频| 男人的午夜天堂| 日日天天久久| 日韩视频在线永久播放| 久久久久久香蕉| 波多野结衣在线观看| 国产劲爆久久| 99这里有精品| 久久精品国产2020观看福利| 天堂www中文在线资源| 国产福利亚洲| 欧美午夜激情在线| 免费一级淫片aaa片毛片a级| av大片在线观看| av在线不卡电影| 亚洲影院在线看| 最近中文字幕免费观看| 国产农村妇女精品一二区| 久久艹在线视频| 免费黄在线观看| 国产ts一区| 91精品国产一区二区三区蜜臀| 苍井空浴缸大战猛男120分钟| 成年人视频免费在线播放| 中文字幕一区二区三区不卡在线 | 特级毛片www| 欧美精品午夜| 欧美成人免费网| 欧美一区免费观看| 欧美hd在线| 在线观看亚洲区| 1024在线看片| jizzjizz欧美69巨大| 亚洲日本中文字幕免费在线不卡| 中文字幕一区三区久久女搜查官| 高清日韩欧美| 亚洲国产99精品国自产| 亚洲精品激情视频| 999国产精品一区| 欧美哺乳videos| 韩国一区二区三区四区| 91久久精品无嫩草影院| 日韩欧美综合一区| 成人做爰www看视频软件| 波多野结衣欧美| 欧美大片拔萝卜| 欧美一级大片免费看| 亚洲精品高潮| 亚洲国产日韩欧美在线动漫| 久久久老熟女一区二区三区91| 亚洲国产aⅴ精品一区二区| 日韩午夜小视频| 亚洲美女精品视频| 国产精品tv| 日韩精品一区二区视频| 国产jjizz一区二区三区视频| 不卡在线一区二区| 日韩三级成人av网| 久久国产精品波多野结衣av| 亚洲东热激情| 欧美专区国产专区| 中文有码在线播放| 国产美女在线精品| 国产美女精品久久久| 日韩一区av| 国产三级一区二区三区| 国产成年人在线观看| 18视频在线观看| 第一福利永久视频精品| 日韩大片一区二区| 欧美经典影片视频网站| 国产视频欧美视频| 国产又粗又猛又爽又黄的视频四季| 欧美国产美女| 久久久久久久网站| 这里只有精品999| 国产精品影视天天线| 国产一区喷水| 四虎久久免费| 亚洲3atv精品一区二区三区| www.99在线| 一级毛片精品毛片| 亚洲欧洲偷拍精品| 亚洲熟女www一区二区三区| 影音先锋久久| 成人av电影天堂| 性感美女福利视频| 亚洲三级免费电影| wwwxxx黄色片| 777久久精品| 最好看的2019年中文视频 | jizz在线免费观看| 亚洲狠狠爱一区二区三区| 日本老熟妇毛茸茸| 国产精品国产| 久久精品亚洲热| 欧美男人亚洲天堂| 国产999精品久久久久久绿帽| 日本亚洲导航| 国产调教在线| 日韩精品一区二区三区视频播放 | 欧美吞精做爰啪啪高潮| 成人在线视频免费播放| 一区二区三区网站| 国产精品久久久久久av下载红粉 | 欧美成人一区二区三区电影| 国产成人麻豆免费观看| jizz一区二区| 黑人巨茎大战欧美白妇| 欧美一区二区三区婷婷| 亚洲日本成人女熟在线观看| 国产精品黄色大片| 国产91精品久久久久久久网曝门| 一区二区精品在线观看| 欧美成人a交片免费看| 精品国产一区二区三区不卡| 日本精品在线免费观看| 免费观看在线色综合| 免费观看成人高| 九色porny丨首页入口在线| 日韩欧美国产一二三区| 久久精品视频免费在线观看| 久久丁香综合五月国产三级网站| 日本最新一区二区三区视频观看| 麻豆mv在线看| 日韩国产精品视频| 亚欧视频在线观看| 成人国产精品免费观看视频| 天天做天天躁天天躁| 精品视频一区二区三区| 久久国产精品久久精品| 久久99精品久久久久久青青91| 久久久美女视频| 国产精品性做久久久久久| 一本色道久久综合亚洲二区三区| 欧美日韩亚洲国产| 中文字幕9999| 91在线视频国产| 亚洲欧美视频一区| 性生活在线视频| 午夜国产精品视频| av一区观看| av中文字幕在线观看第一页 | 国产精品视频中文字幕91| av免费观看一区二区| 欧美日韩不卡视频| 日韩a级片在线观看| 国产91色综合久久免费分享| 久久久久久www| 全球av集中精品导航福利| 欧美综合在线第二页| 成人免费视频| 91精品国产综合久久蜜臀| 九九热精彩视频| aa级大片欧美| 日韩一级片播放| 91成人看片| 国产一区二区三区四区五区在线 | 国产免费无遮挡吸奶头视频| 蜜桃精品视频在线观看| 男女爱爱视频网站| 国产欧美自拍一区| 国产精品久久久久久av下载红粉| 麻豆网站在线看| 精品国产免费一区二区三区四区| 国产成人在线视频观看| 国产精品网友自拍| 中文在线字幕观看| 久久婷婷丁香| 国产日韩欧美大片| 沈樵精品国产成av片| 国产中文欧美精品| 福利在线免费视频| 色偷偷综合社区| 肥臀熟女一区二区三区| 日本高清不卡在线观看| 国产乱国产乱老熟300| 97精品久久久午夜一区二区三区| 国产精品久久a| 亚洲精品国产日韩| 亚洲资源视频| 色愁久久久久久| 成人在线视频网| 欧美男人天堂| 免费不卡在线观看av| 精品av中文字幕在线毛片| 91精品国产综合久久香蕉麻豆| 欧美精品亚洲精品日韩精品| 自拍偷拍欧美激情| 国产精品20p| 成人免费高清在线观看| 日韩欧美国产片| 国产亚洲精品v| 九一免费在线观看| 精品国精品国产自在久国产应用 | 在线观看视频你懂得| 老司机午夜精品视频在线观看| 日韩不卡视频一区二区| 国产精品欧美日韩一区| 国产精品日韩欧美一区二区三区| 91精品国产色综合久久不卡粉嫩| 55夜色66夜色国产精品视频| 欧美aaa免费| 久久中国妇女中文字幕| 国产69久久| 日韩www在线| 国内爆初菊对白视频| 337p亚洲精品色噜噜噜| 中文字幕日本视频| 91久久免费观看| 国产三级av片| 亚洲成在人线免费| 久久久精品99| 亚洲天堂网中文字| 色偷偷男人天堂| 中文字幕不卡在线| 免费看91的网站| 国产午夜亚洲精品理论片色戒| 日韩精品视频一区二区| 国产suv精品一区二区6| 波多野结衣三级视频| 国内外成人在线| 国内自拍第二页| 麻豆91在线播放免费| 另类小说第一页| 日韩黄色片在线观看| 久草在在线视频| 三级久久三级久久| 91看片就是不一样| 三级欧美在线一区| 久久久国产欧美| 日本aⅴ亚洲精品中文乱码| 熟女人妇 成熟妇女系列视频| 先锋影音久久久| 国产精品免费观看久久| 久久xxxx精品视频| 粉嫩虎白女毛片人体| 日韩精彩视频在线观看| 黄色av免费在线播放| 国产亚洲激情| 欧美日韩怡红院| 免费成人在线观看视频| 精品亚洲视频在线| 国产成人精品免费一区二区| 久久久久99人妻一区二区三区| 不卡一区二区在线| 日韩乱码人妻无码中文字幕久久 | 精品无码久久久久| 精品国产91久久久久久| 亚洲 欧美 日韩 在线| 欧美性xxxxxx少妇| 国产深喉视频一区二区| 精品国产乱码久久久久久夜甘婷婷| 人妻va精品va欧美va| 亚洲天堂色网站| 日本韩国在线视频爽| 欧美大片欧美激情性色a∨久久| 91白丝在线| 国产精品久久久久影院日本| 9999精品| 久久久水蜜桃| 日本一区二区在线看| 麻豆映画在线观看| 麻豆成人精品| 一级片免费在线观看视频| 99久久久免费精品国产一区二区| 37p粉嫩大胆色噜噜噜| 亚洲欧洲日本在线| 久草国产精品视频| 欧美日韩国产免费一区二区 | 国产欧美一二三区| 中文字幕另类日韩欧美亚洲嫩草| 五月天一区二区三区| 影音先锋国产资源| 亚洲国产精品久久久久| 92国产在线视频| 97在线观看免费高清| 精品亚洲a∨| 精品国产免费一区二区三区| 成人在线视频免费观看| 国产一区二区三区小说| 青青国产91久久久久久| 亚洲香蕉中文网| 国产精品成人免费| 欧美一区二区三区四| 日韩欧美中文字幕制服| www.黄在线观看| 91精品国产高清自在线看超| vam成人资源在线观看| 免费看国产精品一二区视频| 欧美日韩亚洲一区在线观看| www.99av.com| 久久众筹精品私拍模特| 九九热精彩视频| 欧美疯狂做受xxxx富婆| 欧美女优在线| 久久免费高清视频| 精品一区二区三区在线观看视频| 欧洲av一区| 国产精品亚洲综合久久| 日韩大尺度视频| 亚洲欧美综合在线精品| 国产精品尤物视频| 日韩av一区二区在线| 天堂8中文在线| 国产在线精品成人一区二区三区| 九九热线有精品视频99| 国产av麻豆mag剧集| 国产大陆a不卡| 91禁男男在线观看| 在线观看亚洲专区| 日韩欧美亚洲系列| 97人人做人人爱| 国产精品黄网站| 国产日本在线播放| 成人免费视频播放| 精品少妇爆乳无码av无码专区| 日韩一区二区精品在线观看| 337p日本欧洲亚洲大胆鲁鲁| 国产精品高清网站| heyzo久久| 伊人国产在线视频| 亚洲国产精品成人综合| 日韩av免费播放| 国产一区二区久久精品| 日韩高清在线| 亚洲二区三区四区| 久久精品国产秦先生| 久久久久久成人网| 欧美日本一道本在线视频| 3d成人动漫在线| 91九色视频导航| 欧美精品91| 日本一级大毛片a一| 性感美女极品91精品| 黄色www视频| 91成人免费观看网站| 嫩草一区二区三区| 性生交免费视频| 国产精品久久久久婷婷| 97超碰国产在线| 久久久久久97| 亚洲永久精品唐人导航网址| 老司机午夜av| 成人欧美一区二区三区黑人麻豆| 国产绿帽刺激高潮对白| 欧美成人在线影院| 久久综合五月婷婷| 十八禁视频网站在线观看| 国产欧美日韩在线看| 国产日产亚洲系列最新| 欧美激情影音先锋| 香蕉国产成人午夜av影院| 嫩草影院国产精品| 亚洲另类春色国产| 天天干天天爽天天操| 国产精品激情av电影在线观看| 欧美gayvideo| 久久久久久久人妻无码中文字幕爆| 欧美日韩一区二区精品| seseavlu视频在线| 99久久99| 狂野欧美一区| 日韩一级片av| 亚洲欧美激情一区| 亚洲一区导航| www国产精品内射老熟女| 欧美激情一区在线| 2023国产精品| 亚洲成人黄色网| 国产精品国精产品一二| 美日韩免费视频| 极品销魂美女一区二区三区| 久久久久久久国产精品毛片| 精品小视频在线| 国产成年精品| 国产91对白刺激露脸在线观看| 亚洲国产精品精华液ab| 刘亦菲久久免费一区二区| 国产成人在线视频| 欧美日韩三区| 四季av中文字幕| 亚洲精美色品网站| 日韩色性视频| 国产l精品国产亚洲区久久| 亚洲日本va在线观看| 涩爱av在线播放一区二区| 91亚洲精品一区二区| 久久综合狠狠| 黄网在线观看视频| 欧美激情第6页| 久久久久国产|