日韩精品一区二区三区在线视频放-无码中文字幕V?一区二区-成年片免费观看视频-国内少妇人妻丰满av-国产精品中文字幕免费观看-亚洲成人久久一区二区三区-国内少妇偷人精品视频无缓冲-一区二区国产精品日本一区二区三区在线网

ARTICLE DETAIL

資訊詳情

深耕商務建站與企業(yè)官網運營的一線實戰(zhàn)洞察。

Undo Manager 實現(xiàn)原理:操作建模、雙棧調度與狀態(tài)快照

Undo Manager 實現(xiàn)原理:操作建模、雙棧調度與狀態(tài)快照 簡介本資源是一套面向C桌面應用開發(fā)者的撤銷/重做Undo/Redo功能完整實現(xiàn)方案適用于文本編輯器、富文本處理工具等需狀態(tài)回溯能力的中高級項目。壓縮包共61個文件含28個.cpp源文件如UndoManager.cpp、RETypingAction.cpp、REDropAction.cpp等承載核心操作封裝與狀態(tài)管理邏輯、31個.h頭文件定義Action基類、視圖接口、文本范圍與樣式結構等另含1個說明文檔和1個資源腳本整體僅70KB輕量但結構嚴謹。目前已有155人學習下載適合希望深入理解命令模式、棧式歷史管理、細粒度操作建模打字、替換、拖放、插入對象等的開發(fā)者。代碼采用模塊化設計支持RichEdit與BetterEdit雙視圖體系涵蓋多步菜單交互MultipleUndoRedoMenu.cpp與變更日志記錄Change Log.txt可直接集成或作為教學范例剖析撤銷系統(tǒng)架構與事件協(xié)同機制。1. Undo Manager 是什么一個被低估的“操作后悔藥”不是 UI 組件而是狀態(tài)變更的底層契約你寫了個表單編輯器用戶改了 5 行數(shù)據(jù)、刪了 2 個字段、又拖拽重排了順序——然后猛按 CtrlZ結果只撤回了最后一次拖拽前面的修改全丟了或者更糟撤回后界面沒刷新但內部狀態(tài)已回滾下一次提交直接把臟數(shù)據(jù)發(fā)了出去。這不是前端框架的鍋是 Undo Manager 沒立住契約。Undo Manager 不是某個 React 庫里的 Hook也不是 Vue 的插件它是一套對狀態(tài)變更行為建模、封裝、可追溯、可原子回滾的通用機制。它的核心價值不在“能撤銷”而在“知道誰在什么時候以什么方式改了什么并且能精準還原到那個瞬間”。它適用于任何需要操作歷史、多級回退、協(xié)同編輯、調試回放或狀態(tài)快照的場景——從代碼編輯器、圖形設計工具到工業(yè) HMI 系統(tǒng)、低代碼平臺的邏輯編排畫布。如果你正在手寫history.push()或靠useState 數(shù)組堆棧硬扛撤銷邏輯那說明你還沒真正接入 Undo Manager 的抽象層它不關心 UI 怎么渲染只負責把“變更”變成可序列化、可比較、可執(zhí)行的 Operation 對象。下面我們就從零搭起這個“后悔藥”的骨架不依賴任何框架封裝直擊底層實現(xiàn)邏輯。2. 從零實現(xiàn)一個最小可用 Undo Manager用 Operation 建模變更用 Stack 管理歷史Undo Manager 的本質是把“用戶的一次操作”翻譯成一段可逆的、帶元信息的狀態(tài)變更指令。它不能只存舊值和新值太粗暴也不能只存函數(shù)引用不可序列化、難調試。我們采用經典的Operation 模式每個操作是一個對象包含execute()正向執(zhí)行、undo()反向回滾、redo()重做三個方法以及timestamp、label、source等元數(shù)據(jù)。所有 Operation 實例由一個雙棧undoStack redoStack統(tǒng)一調度。2.1 定義 Operation 接口與基礎實現(xiàn)類我們先定義 Operation 的 TypeScript 接口再給出一個通用基類BaseOperation它提供默認的redo()實現(xiàn)即再次調用execute()并強制子類實現(xiàn)execute()和undo()// types.ts export interface Operation { execute(): void; undo(): void; redo(): void; timestamp: number; label: string; source?: string; // 標識操作來源如 keyboard | mouse | api } // base-operation.ts export abstract class BaseOperation implements Operation { timestamp Date.now(); abstract execute(): void; abstract undo(): void; redo(): void { this.execute(); // 默認重做 再執(zhí)行一次 } }提示redo()默認復用execute()是常見做法但某些場景如異步操作需重載。此處保持簡潔后續(xù)會說明如何擴展。2.2 構建 UndoManager 核心類雙棧調度與邊界控制UndoManager類不持有任何業(yè)務狀態(tài)只管理 Operation 實例的生命周期。它維護兩個數(shù)組棧undoStack待撤銷的操作和redoStack已撤銷、待重做的操作。關鍵約束有三最大歷史深度限制避免內存爆炸合并連續(xù)操作如連打 10 個字符應合并為一個“輸入文本”操作而非 10 個禁止空操作入棧execute()后若狀態(tài)未變不記錄。// undo-manager.ts export class UndoManager { private undoStack: Operation[] []; private redoStack: Operation[] []; private maxHistory 200; constructor(options: { maxHistory?: number } {}) { this.maxHistory options.maxHistory ?? 200; } // 執(zhí)行操作先運行再入 undoStack清空 redoStack execute(op: Operation): void { op.execute(); this.undoStack.push(op); this.redoStack []; // 一旦新操作發(fā)生重做歷史失效 this.trimStacks(); } // 撤銷彈出 undoStack 頂部執(zhí)行 undo()推入 redoStack undo(): void { if (this.undoStack.length 0) return; const op this.undoStack.pop()!; op.undo(); this.redoStack.push(op); } // 重做彈出 redoStack 頂部執(zhí)行 redo()推入 undoStack redo(): void { if (this.redoStack.length 0) return; const op this.redoStack.pop()!; op.redo(); this.undoStack.push(op); } // 合并最近操作用于連續(xù)輸入等場景 mergeLast(operation: Operation): void { if (this.undoStack.length 0) return; const last this.undoStack[this.undoStack.length - 1]; // 此處需業(yè)務判斷是否可合并例如同 label、同 source、時間間隔 300ms if ( last.label operation.label last.source operation.source Date.now() - last.timestamp 300 ) { // 調用業(yè)務自定義的 merge 方法需 Operation 子類實現(xiàn) if (typeof (last as any).merge function) { (last as any).merge(operation); } } } // 清理棧保持長度不超過 maxHistory private trimStacks(): void { if (this.undoStack.length this.maxHistory) { this.undoStack this.undoStack.slice(-this.maxHistory); } if (this.redoStack.length this.maxHistory) { this.redoStack this.redoStack.slice(-this.maxHistory); } } // 獲取當前可撤銷/重做數(shù)量供 UI 顯示按鈕狀態(tài) get canUndo(): boolean { return this.undoStack.length 0; } get canRedo(): boolean { return this.redoStack.length 0; } get historySize(): number { return this.undoStack.length; } }這段代碼實現(xiàn)了 Undo Manager 的骨架。注意mergeLast()并未強制要求所有 Operation 都實現(xiàn)merge()而是用typeof安全檢查——這是為了保持基類輕量把合并邏輯下沉到具體業(yè)務 Operation 中。trimStacks()在每次execute()后調用確保內存可控canUndo/canRedo是典型的 UI 友好屬性方便綁定按鈕禁用狀態(tài)。2.3 實戰(zhàn)為表單字段創(chuàng)建 TextChangeOperation現(xiàn)在我們寫一個真實可用的 Operation 子類TextChangeOperation用于處理輸入框內容變更。它需記錄字段名、舊值、新值并支持合并連續(xù)輸入時將多次setValue(a) → setValue(ab) → setValue(abc)合并為一次setValue(abc)。// operations/text-change-operation.ts import { BaseOperation } from ../base-operation; export interface TextChangePayload { field: string; oldValue: string; newValue: string; } export class TextChangeOperation extends BaseOperation { constructor( public payload: TextChangePayload, public label 修改文本, public source keyboard ) { super(); } execute(): void { // 注意execute 不直接改 DOM而是調用業(yè)務 setter // 這里假設有一個全局 store 或 context 提供 updateField 方法 updateField(this.payload.field, this.payload.newValue); } undo(): void { updateField(this.payload.field, this.payload.oldValue); } // 合并邏輯僅當同字段、且新值以舊值開頭時擴展 newValue merge(other: TextChangeOperation): void { if (this.payload.field ! other.payload.field) return; if (other.payload.newValue.startsWith(this.payload.newValue)) { this.payload.newValue other.payload.newValue; this.timestamp other.timestamp; // 更新時間戳為最新 } } } // 模擬業(yè)務 setter實際項目中應注入 function updateField(field: string, value: string): void { // 例如document.getElementById(field)?.value value; // 或 dispatch({ type: UPDATE_FIELD, payload: { field, value } }); }邏輯說明TextChangeOperation的execute()和undo()都調用同一個updateField()但傳入不同值。這保證了正向/反向行為完全對稱。merge()方法判斷other.newValue是否以當前newValue開頭——這是連續(xù)輸入的典型特征a → ab → abc滿足則更新newValue和timestamp實現(xiàn)視覺上的“一次輸入”效果。參數(shù)說明field是字段唯一標識如user_nameoldValue/newValue是字符串快照label和source用于 UI 展示和審計。3. 與 React 深度集成用自定義 Hook 封裝狀態(tài)聯(lián)動避免 useEffect 嵌套陷阱Undo Manager 本身是框架無關的但落地時必須與 UI 框架的狀態(tài)更新機制對齊。在 React 中常見錯誤是在useEffect里監(jiān)聽輸入事件并execute()但execute()觸發(fā)的updateField()又導致組件重渲染進而再次觸發(fā)useEffect形成無限循環(huán)。正確解法是分離“操作捕獲”與“狀態(tài)更新”用 ref 緩存當前值用useCallback固化操作創(chuàng)建邏輯讓 UndoManager 成為純命令總線。3.1 創(chuàng)建 useUndoableState Hook接管 useState 并注入 Undo 能力我們不替換useState而是在其之上疊加一層“可撤銷狀態(tài)”。該 Hook 返回[value, setValue, undo, redo, canUndo, canRedo]其中setValue是增強版自動記錄 Operation。// hooks/use-undoable-state.ts import { useState, useRef, useCallback } from react; import { UndoManager } from ../undo-manager; import { TextChangeOperation } from ../operations/text-change-operation; export function useUndoableStateT( initialValue: T, options: { manager?: UndoManager; maxHistory?: number } {} ) { const [value, setValue] useStateT(initialValue); const currentValueRef useRefT(initialValue); const manager options.manager || new UndoManager({ maxHistory: options.maxHistory }); // 增強版 setValue生成 Operation 并執(zhí)行 const undoableSetValue useCallback( (newValue: T | ((prev: T) T), source: string user) { const resolvedValue typeof newValue function ? (newValue as (prev: T) T)(currentValueRef.current) : newValue; // 僅當值真正改變時才記錄操作防抖 避免空操作 if (Object.is(resolvedValue, currentValueRef.current)) return; const payload { field: root, // 單值場景用 root 標識 oldValue: currentValueRef.current as unknown as string, newValue: resolvedValue as unknown as string, }; const op new TextChangeOperation(payload, 設置值, source); manager.execute(op); // 同步更新本地 ref 和 state currentValueRef.current resolvedValue; setValue(resolvedValue); }, [manager] ); // 撤銷/重做方法直接代理給 manager const undo useCallback(() manager.undo(), [manager]); const redo useCallback(() manager.redo(), [manager]); return [ value, undoableSetValue, undo, redo, manager.canUndo, manager.canRedo, ] as const; }參數(shù)說明initialValue是初始狀態(tài)options.manager允許復用外部 UndoManager 實例如跨多個表單項共享歷史source參數(shù)用于區(qū)分操作來源鍵盤輸入、API 回填、程序初始化等便于后續(xù)審計或條件過濾。關鍵點在于currentValueRef它始終保存最新值undoableSetValue比較的是 ref 值而非 state 值避免因setState異步性導致的誤判。Object.is()用于嚴格相等判斷支持 NaN、Object 等。3.2 在組件中使用一個可撤銷的搜索框現(xiàn)在我們寫一個真實組件展示如何用useUndoableState構建帶撤銷能力的輸入框// components/SearchInput.tsx import React, { KeyboardEvent } from react; import { useUndoableState } from ../hooks/use-undoable-state; export function SearchInput() { const [query, setQuery, undo, redo, canUndo, canRedo] useUndoableStatestring(); const handleKeyDown (e: KeyboardEventHTMLInputElement) { if (e.key Enter) { // 模擬搜索提交 console.log(Search:, query); // 提交后可選擇清空 redoStack防止用戶誤重做搜索 // manager.redoStack []; } }; return ( div classNamesearch-container input typetext value{query} onChange{(e) setQuery(e.target.value, keyboard)} onKeyDown{handleKeyDown} placeholder輸入搜索關鍵詞... / div classNamecontrols button onClick{undo} disabled{!canUndo} 撤銷 (CtrlZ) /button button onClick{redo} disabled{!canRedo} 重做 (CtrlY) /button span classNamehistory-count 歷史: {canUndo ? ● : ○} {canRedo ? ● : ○} /span /div /div ); }邏輯說明onChange事件中調用setQuery(value, keyboard)自動觸發(fā)TextChangeOperation創(chuàng)建與執(zhí)行onKeyDown捕獲 Enter 提交此時query是最新值可安全用于 API 調用。按鈕disabled屬性直連canUndo/canRedoUI 狀態(tài)與 Manager 內部棧完全同步。這里沒有useEffect沒有競態(tài)所有狀態(tài)流轉都由setQuery這一個入口驅動。3.3 處理復雜狀態(tài)用 ObjectChangeOperation 管理嵌套對象單值夠用但表單常是對象結構如{ name: , email: }。我們擴展一個ObjectChangeOperation它記錄整個對象的深拷貝快照并支持按路徑更新// operations/object-change-operation.ts import { BaseOperation } from ../base-operation; import { deepClone, setByPath, getByPath } from ../utils; export interface ObjectChangePayload { path: string; // 如 user.profile.name oldValue: unknown; newValue: unknown; snapshotBefore: Recordstring, unknown; snapshotAfter: Recordstring, unknown; } export class ObjectChangeOperation extends BaseOperation { constructor( public payload: ObjectChangePayload, public label 修改對象字段, public source user ) { super(); } execute(): void { // 更新全局狀態(tài)樹假設存在 updateStateTree 函數(shù) updateStateTree(this.payload.path, this.payload.newValue); } undo(): void { // 恢復整個快照更安全避免路徑更新遺漏 restoreStateTree(this.payload.snapshotBefore); } merge(other: ObjectChangeOperation): void { // 同路徑、時間相近則更新 newValue 和快照 if ( this.payload.path other.payload.path Date.now() - this.timestamp 300 ) { this.payload.newValue other.payload.newValue; this.payload.snapshotAfter other.payload.snapshotAfter; this.timestamp other.timestamp; } } } // 輔助函數(shù)簡化版 function updateStateTree(path: string, value: unknown): void { // 實際項目中對接 Zustand / Redux / Jotai 等 } function restoreStateTree(snapshot: Recordstring, unknown): void { // 用 snapshot 替換整個狀態(tài)樹 }使用提示ObjectChangeOperation通過snapshotBefore/After記錄完整狀態(tài)比單字段更新更魯棒尤其當字段間有聯(lián)動計算時。path支持點號分隔user.address.citysetByPath和getByPath是標準工具函數(shù)。合并邏輯同樣基于路徑和時間窗口確保同一字段的連續(xù)修改被聚合。4. 避坑指南Undo Manager 實戰(zhàn)中 4 個高頻翻車點與血淚修復方案Undo Manager 看似簡單但落地時極易因狀態(tài)耦合、時機錯位、邊界遺漏而集體翻車。以下是某跨平臺低代碼平臺在灰度階段踩過的 4 個真實坑每條都附帶可立即復用的修復代碼。4.1 現(xiàn)象撤銷后 UI 未更新但內部狀態(tài)已回滾 → “界面黑匣子”原因undo()執(zhí)行了op.undo()但該方法只修改了業(yè)務狀態(tài)如 Redux store未觸發(fā) React 組件重新渲染。常見于op.undo()直接修改了ref.current或全局變量卻忘了通知 UI。解決所有undo()和execute()方法內必須顯式觸發(fā)狀態(tài)更新。不要依賴“狀態(tài)變了 UI 自動更新”的幻覺。修復方案是在undo()中調用setValue()或setState就像execute()一樣// ? 錯誤只改 ref不觸發(fā)渲染 undo(): void { this.payload.fieldRef.current this.payload.oldValue; // UI 不知道 } // ? 正確調用狀態(tài) setter保證 UI 同步 undo(): void { // 假設我們有注入的 setter this.setter(this.payload.field, this.payload.oldValue); }血淚經驗在BaseOperation基類中預留setter屬性構造時傳入強制子類使用統(tǒng)一更新通道。避免任何 Operation 直接操作 DOM 或 ref。4.2 現(xiàn)象連續(xù)快速輸入如粘貼長文本導致撤銷粒度太細一次 CtrlZ 只刪一個字符原因TextChangeOperation的合并閾值300ms在粘貼場景下失效——粘貼是單次事件但內部觸發(fā)了多次input事件每次input都生成獨立 Operation且時間戳相同無法合并。解決增加“批量操作標記”。在粘貼開始前用manager.beginBatch(paste)標記批次結束時manager.endBatch()期間所有 Operation 自動合并為一個// undo-manager.ts 新增方法 beginBatch(label: string): void { this.batchLabel label; this.batchStartTimestamp Date.now(); } endBatch(): void { if (!this.batchLabel) return; // 將 batch 期間所有操作合并為一個 CompositeOperation const batchOps this.undoStack.splice(-this.batchOpCount); if (batchOps.length 0) { const composite new CompositeOperation(batchOps, this.batchLabel); this.undoStack.push(composite); } this.batchLabel undefined; this.batchOpCount 0; }然后在輸入框onPaste事件中調用input onPaste{() { manager.beginBatch(paste); setTimeout(() manager.endBatch(), 0); // 微任務等待 input 事件完成 }} /提示setTimeout(..., 0)確保endBatch()在所有input事件處理完畢后執(zhí)行捕獲全部操作。4.3 現(xiàn)象異步操作如 API 保存后撤銷狀態(tài)回滾但服務器數(shù)據(jù)未回退 → “數(shù)據(jù)不一致”原因execute()中調用了saveToServer()但undo()只回滾本地狀態(tài)未調用revertOnServer()。Undo Manager 默認不處理副作用需業(yè)務顯式聲明。解決擴展 Operation 接口增加asyncUndo()方法并在UndoManager.undo()中優(yōu)先調用它export interface AsyncOperation extends Operation { asyncUndo?(): Promisevoid; // 可選僅異步操作需實現(xiàn) } // 在 UndoManager.undo() 中 async undo(): Promisevoid { if (this.undoStack.length 0) return; const op this.undoStack.pop()!; if (asyncUndo in op typeof op.asyncUndo function) { await op.asyncUndo(); // 等待服務端回滾 } op.undo(); // 再回滾本地 this.redoStack.push(op); }對應地創(chuàng)建ApiSaveOperationclass ApiSaveOperation extends BaseOperation { constructor(public apiCall: () Promisevoid) { super(); } asyncUndo(): Promisevoid { // 調用反向 API如 DELETE /drafts/{id} await fetch(/api/drafts/${this.id}, { method: DELETE }); } execute(): void { this.apiCall(); // 保存 } undo(): void { // 本地回滾如恢復草稿緩存 } }4.4 現(xiàn)象頁面刷新后 Undo 歷史丟失用戶抱怨“剛做的修改全沒了”原因UndoManager 實例是內存對象刷新即銷毀。需持久化歷史棧到localStorage或 IndexedDB。解決在UndoManager構造時加載歷史并在每次execute()后自動保存。為防序列化失敗只存 Operation 的可序列化部分label,payload,timestamp重建時動態(tài)實例化constructor(options: { maxHistory?: number; storageKey?: string; // 如 my-app-undo-history } {}) { super(options); this.storageKey options.storageKey; if (this.storageKey) { this.loadFromStorage(); } } private loadFromStorage(): void { try { const saved localStorage.getItem(this.storageKey); if (saved) { const data JSON.parse(saved); // 重建 Operation 實例需注冊 Operation 類型映射 this.undoStack data.undo.map((item: any) this.deserializeOperation(item) ); this.redoStack data.redo.map((item: any) this.deserializeOperation(item) ); } } catch (e) { console.warn(Failed to load undo history, e); } } private saveToStorage(): void { if (!this.storageKey) return; try { const data { undo: this.undoStack.map(op this.serializeOperation(op)), redo: this.redoStack.map(op this.serializeOperation(op)), }; localStorage.setItem(this.storageKey, JSON.stringify(data)); } catch (e) { console.warn(Failed to save undo history, e); } } // 在 execute() 末尾調用 this.saveToStorage();注意serializeOperation需根據(jù) Operation 類型返回純對象deserializeOperation根據(jù)type字段 new 對應類。這是典型的“序列化-反序列化”模式務必測試邊緣 case如函數(shù)、undefined、Date。5. 進階技巧用 Operation 快照做狀態(tài)調試回放把 Undo Manager 變成黑盒分析儀Undo Manager 的最大隱藏價值不是讓用戶按 CtrlZ而是讓你在生產環(huán)境回放任意一次用戶操作流精準定位 UI Bug。我們把每個 Operation 的execute()和undo()執(zhí)行前后自動采集狀態(tài)快照snapshot構建一條可追溯的“狀態(tài)時間線”。這不需要額外埋點只需在UndoManager.execute()中插入快照邏輯。5.1 在 Operation 執(zhí)行前后自動采集狀態(tài)快照我們擴展UndoManager增加captureSnapshot()方法它接受一個stateGetter函數(shù)返回當前業(yè)務狀態(tài)并在execute()前后各調用一次// undo-manager.ts export class UndoManager { // ... 其他屬性 private snapshots: Array{ timestamp: number; before: unknown; after: unknown; operationLabel: string; } []; constructor(options: { maxHistory?: number; stateGetter?: () unknown; // 業(yè)務狀態(tài)獲取函數(shù) } {}) { this.stateGetter options.stateGetter; } execute(op: Operation): void { // 執(zhí)行前快照 const before this.stateGetter?.() ?? null; op.execute(); // 執(zhí)行后快照 const after this.stateGetter?.() ?? null; this.snapshots.push({ timestamp: Date.now(), before, after, operationLabel: op.label, }); // 入棧... this.undoStack.push(op); this.redoStack []; this.trimStacks(); } // 獲取指定索引的操作及快照用于調試面板 getSnapshotAt(index: number): { op: Operation; snapshot: NonNullabletypeof this.snapshots[number] } | undefined { if (index 0 || index this.snapshots.length) return; return { op: this.undoStack[index], snapshot: this.snapshots[index], }; } }關鍵點stateGetter是業(yè)務方傳入的函數(shù)例如() store.getState()或() ({ form: formData, errors: validationErrors })。它必須是純函數(shù)無副作用??煺沾鎯檩p量對象before/after是執(zhí)行前后的狀態(tài)副本可用于 diff 分析。5.2 構建簡易調試面板可視化狀態(tài)變化鏈我們寫一個 React 組件列出所有歷史操作并允許點擊任一操作將應用狀態(tài)“跳轉”到該時刻類似 Chrome DevTools 的 replay// components/DebugReplayPanel.tsx import React, { useState, useEffect } from react; import { UndoManager } from ../undo-manager; interface SnapshotItem { timestamp: number; before: unknown; after: unknown; operationLabel: string; } export function DebugReplayPanel({ manager }: { manager: UndoManager }) { const [snapshots, setSnapshots] useStateSnapshotItem[]([]); const [activeIndex, setActiveIndex] useStatenumber | null(null); // 訂閱快照更新假設 manager 提供 onSnapshot 事件 useEffect(() { const unsubscribe manager.onSnapshot((snapshot) { setSnapshots(prev [...prev, snapshot]); }); return unsubscribe; }, [manager]); const jumpTo (index: number) { if (index 0 || index snapshots.length) return; const target snapshots[index]; // 這里調用業(yè)務 restoreState(target.before) 方法 restoreState(target.before); setActiveIndex(index); }; return ( div classNamedebug-panel h3狀態(tài)回放面板/h3 div classNametimeline {snapshots.map((snap, i) ( div key{i} className{step ${activeIndex i ? active : }} onClick{() jumpTo(i)} span classNamelabel{snap.operationLabel}/span span classNametime{new Date(snap.timestamp).toLocaleTimeString()}/span div classNamediff {/* 可接入 react-diff-view 顯示 before/after 差異 */} {JSON.stringify(snap.before).length 50 ? ${JSON.stringify(snap.before).slice(0, 50)}... : JSON.stringify(snap.before)} → {JSON.stringify(snap.after).length 50 ? ${JSON.stringify(snap.after).slice(0, 50)}... : JSON.stringify(snap.after)} /div /div ))} /div /div ); } function restoreState(state: unknown): void { // 實際項目中調用 store.replaceState(state) 或類似方法 }效果當用戶報告“我在第 3 步點擊按鈕后頁面空白”你打開調試面板找到第 3 步點擊jumpTo(3)UI 瞬間回到那個時刻你就能看到空白頁面并 inspect 元素、查 console。這比看日志快 10 倍。5.3 生產環(huán)境安全開關快照功能默認關閉按需啟用快照采集有性能開銷深拷貝、內存占用絕不能在生產環(huán)境默認開啟。我們在UndoManager中添加enableSnapshot()方法并用環(huán)境變量控制// undo-manager.ts class UndoManager { private isSnapshotEnabled false; enableSnapshot(stateGetter: () unknown): void { // 僅在開發(fā)環(huán)境或特定 feature flag 下啟用 if (process.env.NODE_ENV development || window.DEBUG_UNDO) { this.stateGetter stateGetter; this.isSnapshotEnabled true; } } execute(op: Operation): void { if (this.isSnapshotEnabled this.stateGetter) { // 執(zhí)行快照邏輯 } // ... 其余邏輯 } }然后在應用入口// main.tsx const manager new UndoManager(); if (process.env.NODE_ENV development) { manager.enableSnapshot(() store.getState()); }最后一句我在線上系統(tǒng)跑了兩年 Undo Manager最大的教訓是——永遠不要相信“操作很簡單不用管歷史”的想法。哪怕只是一個開關按鈕的 toggle一旦用戶需要“剛才我關掉的那個現(xiàn)在想打開回來”你就得有一套完整的、可驗證的、帶快照的 Undo 機制。它不是錦上添花而是交互健壯性的底線。希望幫到你。本文還有配套的精品資源點擊獲取
返回列表
PREV
查看更多資訊
NEXT
返回資訊列表
牛牛操视频逼| 一区=区三区视频| 羞涩视频| 午夜啊啊| 日韩无码服务区| 在线 亚洲 网爆 自拍| 26uuu国产成人综合| 少妇久久久| 久久久久婷婷精品av电影| 欧美AB在线观看| 久久久国产成人一区二区三区在线| 粉嫩av平台| 东京太热男人的天堂久久久| 久久精品女同亚洲女同13| 日日夜夜国产综合| 中文字幕一区二区三区人妻少妇在线| 男人的天堂激情| www.夜夜操| 国产尤物AV尤物在线观看不卡| 香蕉欧美| 中文字幕一区二区视频在线观看 | 九色 蝌蚪 熟女自| 欧美综合网1| 啊啊啊啊啊啊啊国| 人人澡人人爽人人精品| 夜夜爽爽爽| 婷婷五月影院| 99免费在线视频| 蜜臀久久99精品久久久老,,| 久久极品伊人| 亚州色图第三区| 久久98| 97摸视频| 丁香五月天激情综合| 草莓精品视频| 狠狠操狠狠| 丝袜美腿诱惑亚洲欧美视频在线观看| 爽爽歪在线视频| 屌逼传媒| 九月AV| 精品人妻一区二区三区-国产精品 一个人在线看的黄色电影网站 | 成人av在线播放| 欧美极品| 国产精品麻豆成人av| 天天插网| 欧美亚洲第一页| 中文日本免费高清| 一级啊性爱在线视频| 日韩精品在线观看网站| 婷婷五月天久久久| 久久久久骚| 亚洲国产一级中文综合久久天堂在线免费观看| 69AV女优男人的天堂| 日本女厕偷拍| 亚洲精品人伦一区二区| 久热伊人| 久久riav中文精品| 国产激情片在线观看| 成人区人妻精品一| 8x福利精品第一福利视频导航| 免费精品国偷自产在线在线| 国产精品久久久久无码Av网曝门| 国产精品一级片在线看| 亚洲色欲一区二区三区| 亚洲久久天堂| 大香蕉免费3| 日逼国产| 91男女| 久草在线| 国产一区二区a毛片| 91Chinese在线| 在线97在线| nuu12国产麻豆精品| 东京太热男人的天堂久久久| 日韩在线一区二区| 五月婷婷综合网| 精爱久久| 蜜臀久久99精品久久久久久酒店| 综合操逼| 91伊人大香蕉| 神马麻豆福利院 | 狠狠干综合| 蜜桃视频一区二区三区在线观看| 亚洲自拍小说| 免费在线观看国内色片网站网址| 精品欧美日韩在线观看| 久久久久ab| 国际精品久久久| 九九精品无码专区免费| 五月丁香在线| 九九九不卡| 国产对白刺激视频| 97免费视频网| 欧美日本中字另类在线| 99爱久久视频频| 亚洲素人综合| 国产一区二区a毛片| 99热综合| aV中文麻| 国产树林里野战在线看| 欧美亚洲se91| 亚洲啪啪视频免费| 精品无码一区二区| 另类天堂| 加勒比大香蕉视频在线| 9精品久久久久| 成人网站 免费观看| 97超碰久久色| 91久久免费视频互動交流| 五月天色五月| 亚洲熟女综合一区二区| 综合色图,成人综合网| 久久久久人| 无码高清操逼网址| 亚洲男人的天堂V| 亚洲色图欧美一区二区不卡| 久久25| 69一区二区三区 | 久偷拍| 天天看天天日| 五月天色电影| 国产精品久久久久久久电影渣男| 青草影院内射高潮| 国产成人精品日本视频| 2017天天拍大香蕉| 欧美一级欧美三级在线观看| 牛牛AV人人夜夜澡人人爽| 天天色香欲综合网| 欧美日韩大香蕉| 国产精品久久久久久夜夜夜| PMv在线观看| 2025亚洲男人天堂| **一级毛片国产| 在线洲亚线| 开心婷婷五月| 亚洲一区二区三区春色| www.91欧美| 国产综合网站在线播放 | 久久精品人体| 久久精品国产Aⅴ| 婷婷国产精品九区| 91成人精品在线播放| 精品国产乱码久久久久久久| 五月久久HDAV| 狠日操| 久久精品综合| 综合激情97 | 后入福利| 婷婷伊人一区| 嗯嗯嗯好爽| 翔田千里无码一区| 超碰97久| 免费超碰97久久| 偷窥自拍亚洲天堂网爆| 亚洲成a人v欧美综合天堂下载| 嗯嗯啊啊好疼| 中文字幕 码 自拍 视频 区| 国产一区自拍欧美日韩| 久久粉色| 久久同城AV| 激情五月天色色网| 国内精品久久人妻性色av| 国产精品午夜福利视频| 亚洲人在线| 美中日韩无码| 18禁中文字幕| 日操粉逼逼| 青青青国产手线观看视频2| 久久中文字幕女同性恋一区| 久久精品一区| 图色综合网| 凹凸视频特色日本特黄| 91社区拍啪人妻| 97视频网站| 后入式999| 极品粉嫩一区二区| 色婷婷视频| 99在线免费公开视频| 超碰在线在公开超碰在线在公开| 老熟妇综合| 五月综合色| 91小视频| 26uuu性物| 天天综合-91入口| 亚洲色图第四色| 四虎国产成人精品免费一女五男| 亚洲天堂另类小说男人| 另类图片亚洲加勒比另类图片亚洲加勒比另类图片亚洲加勒比 | 伊人玖玖网| 五月婷婷AV| 国产精品自拍xxxx| 超碰成人国产| www…国产操逼| 思思热免费在线视频| 久久久久久9| 伊人国产AV| 999熟女精品| 97超碰巨乳| 中文字幕视频2区| 亚洲精品99| 久久综合激情| 99热久| 国产小u女在线观看| 一中国女人毛片水真多| 久久久久9999| 丰满少妇乱子伦精品无| 啊啊啊啊好多水| 97视频在线观看网站| 亚洲色图欧美色图制服诱惑| 人妻喷水| 国产精品国产精品国产| 91综合熟女| 超碰免费人妻在线| 美女黄网| 97人妻免费中文字幕| 久久精品欧美一区二区三区不卡| 国产精品日韩在线一区| 在线无码视频| 乱伦AVxx| 亚洲色图20p| www.91欧美| 久久噜| 88在线一区二区三区| 美女黄色91| 成人怡红院| 亚洲熟妇一,二,三期| 国产精品不卡一区二区电影| 十八禁的黄污污免费网站| 日本一级二级三级网站| 禁片 高清 在线观看视频网站| 老熟女91av| 欧美精品久久96人妻无码| 天天操人人操骚逼网站| 91人人| 久久黄片国产一区二区| 99热在线观看| 欧美97在线观看| 成人久久久精品| 久久久久女教师免费一区| 97干色| 91午夜无码| 综合色图区| 久久e6只有精品| 啊啊啊啊啊啊啊啊要喷了| 四虎在线视频| 国产成人亚洲精品无码古代早漏男| 亚洲欧美日韩夜夜| 日产国产精品中文久久婷婷| 日本熟妇色熟妇在线视频播放| 国产蜜臀精品一区二区尤物| 人人干黄色| 婷婷色婷婷| 青青操少妇| 麻豆色99999| 青青青草伊人精品| 20cm女自慰在线日韩欧美| 综合欧美激情网| 能看的av| 亚洲怡春院| 国产美女自拍AV| 狠狠干狠狠干| 色欲久久99精品久久| 精品无码秘 人妻一区二区| 中文字幕丝袜国产第一页不卡| 丁香六月激情综合| 中文字幕第23区| 中文字幕丰满子伦无码专区在线视频最新| 久久无码电影| 青青草无码视频| 国产乱子伦一区二区三区在线观看| 中国女人内射6XXXXX| 麻豆久久久久久久久丝袜| 久久久啊啊啊| 超碰久在线天天做| 在线观看精品国产免费| 99啪啪视频| 色97干| 欧美日韩香蕉| 国产AV线| 99久久精品无码一区二区| 亚洲日韩青青草色月| 另类小说欧美激情校园春色| 国产激情在线观看| 亚洲九九视频在线观看| 夜色AV无码手机在线影院| 九九成人精品| 亚洲色色探花| 91精品免费| 亚洲 欧美 制服 另类 自拍| 天天日天天舔东京热 | 国产精品点击进入在线影院| 亚洲一二三精品久久网| 在线日韩精品一区二区三区| 青青青国产| 欧美97在线欧| 日韩一区二区精品视频| 91 丝袜在线播放| 色老汉色| 免费福利视频中文字幕| 一本一首道人妻少妇免费久久| 午夜舔阴达高潮视频免费看| 亚欧中文字幕在线视频| 国产成人bd在线观看| 77国产精品| 人人操人人插人人摸人人干| 日本不卡免费二区| 成人五月香网在线| 韩国一级做a久久久久| 毛片17S| 97人人夜夜精品视频| 亚洲AV无码久久精品蜜桃小说| 九九热久久99精品re| 97自拍一区| 中文字幕日韩人妻视频一区二区三区 | 男人亚洲91首页在线| 囯产精品久久久久久久久久二区三区| 神马福利久草| 欧美成人A天堂片在线观看| 欧洲一区二区三区四区在线观看| 成人精品在线观看| 91老熟妇| 日韩精品怡红院| 日本精品高清一二区一本到| 日本熟妇浓毛hdsex| 人妻无码久久一区二区三区免费| 激情综合亚洲| WWW操逼| 亚州高清av| 日本岛国黄色网址| 日本操逼aaaaa| 精品国产国产AV| 91久久久久久久久18| 91在线视频国产网站| 一区二区三区四区久久视1| 粉嫩av在线一区二区| 好色综合| 欧美在线|亚洲| 5252色欧美在线| 天天干天天狼在线视频| 亚洲无码成人精品| 日韩一级性爱无码| 2017天天插| 精品免费国产二区三区| 九九亚洲| 韩国三级理论在线| 综合在线导航一区| 美日韩男女操屄视频| 蜜臀99久久精品| 欧美变态激情网| 久久超碰爱| 久久久久亚洲Aⅴ无码| 欧美不卡五十路| 久久久久久久久久久久97| 一区| 国产精品久久久蜜臀| 六月丁香久久| 伊人久久艹| 黄片com.| 日韩欧美国产一区二区三区四区| 亚洲无码成人精品| 边做饭边操逼逼| 亚洲色人| 精品人妻一区二区三区日产乱码| 欧美日韩精品久久久久久久久东北老熟妇| 97欧美色| 亚洲91射| 久久久999国产| 1.igao73.com 加入收藏 免费专区 国产精品 中文字幕 日韩精品 欧美精品 精彩 | A 在线网址| 久久久久亚洲Av无码专区老牛影视| 91欧美www| 91老熟女91老女人| 97视频新免费| 加勒比久久av| 天天夜夜rb| 激情久久日韩精品中文字幕麻豆| 色综合20p| 久久久久久久久久黄色网 | 无码直播久久久| 日本国产欧美一区三区二区| 亚洲日韩精品久久久久一区壹牛| 久久九九视频九九视频| 天天舔九色婷婷| 久久这里都是精品| 蜜臀av一区二区三区免费观看| 3p国产欧美99热| 亚洲av淫乱| 亚洲高清无码AAA久久久精品| av一区二区三区四区| 国产无码久久高清| 岛国毛片在线观看免费| 狠狠中文字幕| 欧美国产婷婷久久| 一区二区影视| 精品一区二区三区免费古装毛片香港三级日本三级人妇 | 熟女激情综合网| 啪啪性爱免费视频| 久久性爱视频99| 高清国产成人无码| 久久精视频美日韩在线视频| 大香蕉宗合网在线| 青青草日本中文字幕| 日韩欧美丝袜诱惑| 9997se| 麻豆AV一区二区天美传媒| 欧美亚洲综合高清在线| 男女猛烈无遮掩视频免费软件| 被窝影院午夜看片无码| 欧美性巨大╳╳╳╳╳高跟鞋| 欧美亚洲中文字幕| 天天综合网~69| 看黑丝美女操逼青青网站| 欧美日韩一干二干| 人妻第一页| 日韩簧片免费看| 久久久久国产精品片区无码直播| 欧美亚洲综合色| 青久操| 久久激情五月| 精品人妻一区二区三区视频在线| 国产综合久久久麻桃个 | 手机在线观看不卡无码av| 日韩精品 欧美激情| 亚春色色| 思思热在线视频在线| 无码日韩人妻av一| 嗯嗯嗯好爽| 久久女同性恋一二区| 国内毛片四区| 一牛影视成人片免费| 欧洲色| 2026国产精品视频| 曰韩中文人妻视频| 一区二区三区精品久久| 麻豆黄四叶草网站| 色欲久久99国产精品久久久久久| 中文字幕丝袜国产第一页不卡| 五月丁香啪| 啊啊啊啊啊啊啊在线| 中文字幕99999| 色香色欲天天综合网天天来吧 | 草B在线| 国产18精品亚洲精品| juliaann欧美丝袜办公室| 免费国产电影一区二区| 婷婷综合视频| 久久精品国产99久久,亚洲日韩久久日本一区一区三区 | 欧美一区二区日韩传媒搭讪精品| 亚洲蜜臀精品视频久久| 亚洲精品国产专区在线观看| 久久蜜桃综合网| 97干在线| 欧美成人9797| 91人妻人人澡人人爽人人精品| 人人操人人摸人人看人人干| 九九热这里只有在线精品视 伊人草 成人菠萝蜜视频在线观看 | 色婷婷aV一区二区三区麻豆综合 | 一区三区啪啪| 日韩淫色网| 国产精品成人无码a v毛片| 日韩乱码Av| 成人小电影网站tex| 日韩亚洲Av人人夜夜澡人人爽| 97超碰热线| 久久伊人最新网址视频| 超AV色女| 探花视频免费观看国产专区| 男人亚洲91首页在线| 超碰在线91| 丁香六月激情| 九九九精品美女| 狠狠爱综合网| 久久久999| 人妻插插人妻人| 夜夜草我| 级品肉射| 爆操无码| 男人的天堂va| av大香蕉网站| 欧美激情另类一区二区| 精品少妇人妻| 99免费在线视频| 91亚洲情色| 黄色二级片网站| 国内精品a| 免费草草草草草视频| 丁香五月激情综合国产| 九九热三级片| 蜜桃中文字日产乱幕4区| 午夜.DJ高清在线观看免费7| 99久久9| 午夜高清成人在线视频| 999久久久九九九九| 亚洲精品久久久久久久久豆丁网| 久草精品国产99| 岛国999| 五月天婷婷成人网| 国产一区免费午夜视频| 国产2.3.4区| 人妻夜夜爽天天爽麻豆三区网站| 情趣丝袜无码操逼视频| 欧美综合狠| 综合网,亚洲,欧美| 老司机老司机午夜影院| 麻豆精品.欧美精品.日韩精品.| 日本青青草在线| 高清无码 国产精品| 欧美精品激情| 美熟女逼导航AV操逼| 久青草影院| 国产精品毛片?v一区二区三区| 欧美,日韩,中文,另类| 久久啊哟| 国产欧美一区激情交| 丁香五六月啪啪| 天天综合网亚洲综合网| 九九热视频这里只有精品| 亚欧韩av| 中文字幕一区二区韩| 日韩欧美加勒比| 人妻无码一区二区三区久久99| 欧美性猛交美女自慰91| 久久男女激情视频网站| 中文字幕AV乱伦| 91亚洲人| 亚州五月| 国产一区二区三区,在线观看观看| 天天干美少妇一区| 日本一本道A级黄色毛片试看60分钟| 91东北熟女| 丰满少妇精品一区二区| 亚洲精品不卡一二三区| 欧美亚综合色图| 五月丁香六月婷| 亚洲操逼无码| 国产亚洲中文不卡二区| 人人操人人摸人人看人人插| 偷拍综合网| 91天堂| 国产熟码AV| 久久久免费懂色| 日本男人插女人的逼黄色| 亚殴在线| 激情四射婷婷四五月天| 国产丝袜视频| 懂色综合久久久| 五月丁香久久| 亚洲色天堂日韩中| 天美传媒国产原创中文字幕亚洲欧美另类 | 二色av| 免费簧片在线观看| 一区二区三区美女超清| 亚洲日韩国产精品| 97久久精品| 亚洲97综| 亚洲巨爆乳一区二区三区四季网| 91丨人妻丨国产丨丝袜| 99久久精品国产系列| 91美女小视频| 国产高清成人免费视频| 国产操逼网站亚洲一级黄色| 草草电影院| A 天堂| 欧美传媒| 草草网站影院白丝内射| 天堂中文日本在线观看| ?亚洲伊人伊成久久人综合网| 成人av动漫在线观看| 欧美日韩中文亚洲v在线综合| 亚洲国产成人精品无码专区| 国模吧 一区二区三区| 欧美特大黄一级片片免费| av一区二区三区 中文| 色色五月天婷婷| 男人的天堂2019AV| 欧美性色综合网| 96国产污污污丝袜| 伊人欧美大香蕉视频| 色逼综合| 大香蕉一区二区在线观看.| 欧美老妇曰批的视频| 一级久久性爱视频| 99少妇精品视频| 日本999精品视频| 国产精品久久久九九九| 98超碰欧美| 免费A片三p视频| 天天色天天干天天射| 大香蕉五月天婷婷| 国产精品肉丝自拍| 91老熟女91老女人| 神马九九| 日本性爱少妇| 午夜呻吟欧美| 亚洲男人天堂视频| 不卡av免费在线网址| 久久精品国产亚洲AV无码做| 婷婷五月天综合网| 蜜桃久久久久久久久久久久| 大香蕉人妻久久| 性久久久| 色五月婷婷五月天| 九七毛片九九毛片| 国产色产精品在线观看| 国产精品爽爽va在线观看98| av婷婷色网| 欧美丰满少妇交换91欧美精品| 五月丁香激情四射| www欧美性爱| 天天综合欧美综合| 97天天| 国产懂色精品国产av| 久热久一区二区三区| 精品无人区麻豆乱码1区2区图片| 99re热有精品视频国产| 综合色图亚洲欧美| 无码精品啪啪啪一区二区三区三州| 曰韩中文人妻视频| 色色综合网站| 九九热午夜欧亚国产视频| 国产精品久久久久久久无码AV| 国产成人在线观看综合| 日韩中文字幕宗合在线| 亚洲国产一区二区日韩专区| 混色激情av| 久久大香蕉97| 日日碰狠狠添天天爽超| 久久一本大香蕉| 国产成久久综合片| 色综合中文字幕不卡| 国产精品9999| 深爱五月婷婷| 91色欧美| 丁香五月天激情综合| 欧美日韩中国x| 亚洲成人一区二区精品| 97伊人| 五月丁香婷婷啪啪| 色欲天香天天综合网-成年人三级片网站-欧美乱妇狂野-日韩国产专区-久久久久久 | 日本成人电影资源网| 人妻精品综合中文字幕在线| 97欧美综合| 久热99| 97操碰| 在线99热| 欧美色网络| 在线黄页看毛片| 97国产精品一区| 五月色综合| 91bbbbbb| 亚洲欲色9532548967一区| 久9九综合在线| 天天流夜夜操| a片自拍直播视频| 日本不卡三级网在线播放| 日韩啊V| 91l欧美在线| 亚洲欧美自拍偷拍| 超碰视97中文| 免费AV播放| 日本精品五区| 97精品视频免费| 看大黄色大片原件| 色哟哟av| 骚货人妻偷情自拍在线视频| 看日韩黄片| 粉嫩AV一区夜夜嗨| 一区二区三区激情在线观看| 欧美天天搞| 日韩成人精品| 色图四区| 国产午夜精品一区二区三区牛牛| 去干网最新版| 九热中文字幕| 四季AV一区二区凹凸精品小说| 日本性爱网址| 99夜夜操| 精品亚州18| 密桃99999| 久久久啊啊啊| 国产精品极品美女视频| 日韩精品99久久久久久中文字幕| 日本激情免费大片| 亚洲免费成人精品电影| 91中文字幕| 成人天天看站长推荐| 国产精品无码在线| 欧美一二三| 天天躁狠狠躁av| 丁香激情五月天| 久久久久久一日韩字幕无码| rivers-china.com| 欧美超碰96| 桃花色涩综合影院| 色网站导航大全| 久久精品六区| 四虎免费看黄| 国产剧情一区在线观看| 老熟妇一区二区三区…| 日本免费一区二区不卡| 亚洲网污污污污| 九九热九九| 欧美黄色大片在线观看 | 日韩不卡网操逼中文字幕日韩| 激情综合五| 青娱乐亚洲自拍| 中文字幕蜜乳av| 秘书高跟黑色丝袜国产91在线| 久久久久久九九九九-美女久久久久久久-成人AV | 人人人人插| 十八禁啪啪视频| 欧美色综合网| 精品女同一区| 成人黄页| 色九九九综合| 美女的肌被草喷水视频| 熟女人妻av在线资源,黄色的资源| 性开放中文AV高清无码免费看| 国产在线视频午夜精华在| 91久久国产精品| 超碰久久综合| 制服中出中文人人精品| 中文字日本乱码| 黄色大片一区二区密桃丝袜| 色婷婷丁香五月| 7777欧美成是人在线观看| 久操网无码在线| 一道α片欧美| 国产精品白丝在线播放| 日韩电影在线观看网址| 神马午夜久久| 丰满少妇一区二区三区免费看| 欧美最婬乱婬爆婬牲视频| 九久久精品| 女上位精品在线| 久久久久久少妇| 亚洲美女黄色| 日韩丨制服丨中文|在线| 欧美亚洲涩涩| 欧美天堂亚洲电影院一区在线播放| 国产传媒一区日韩| 成人热久久精品| 青青草大香蕉在线视频| 东京热精品97综合网| 性爱AV天堂| 国产一区二区在线播放,久久亚洲精品中文字幕第一区,亚洲精品在线中文字幕视频 | 91综合色噜噜| 天天看精品动漫视频一区| 人人操人人摸人人骑| 操一操摸一摸| 国产精品永久免费10000| 色欲av一区二区三区蜜芽| 国产日韩精品人妻久久久久色欲网站| 亚欧性爱无码| 日本国产欧美高清在线| 日韩另类| 艳美熟妇先锋一二三区| 亚洲淫乱骚妇AV| 综合激情一一91| 久草色在线观看| 色综91| 亚洲一卡二卡在线免费| 在线a v| 我要看免费韩日黄片| 99精品在线| 天天综和| 欧美日韩97在线| 天天92av| 中文字幕乱在线伦视频中文字幕乱码在线 | 天天干夜夜鈤| 日逼97| 国产精品白丝在线播放 | 久久久久久久久久黄色网| 久久大精品乱码视频人妻熟女| 人妻少妇久久| 神马久久久久| 日韩午夜精品一区二区三区电影| 成人 日韩欧美一区| 草蕉影视亚洲无码| 亚春色色| 少妇一区二区三区精选| 天天插天天操| 久久超碰、| 99久久免费看精品国产一区| 我要去看2个日本美女.com曹逼| 国产高清在线观看欧美| 亚洲精品丝袜-不卡成人免费…… 久久久久成人蜜桃精品 | 欧美影音在线| 久久啊啊啊视频| 91N欧美| 欧美天堂第二区| 亚洲综合首页| 日本一级二级三级网站| 青娱乐av在线| 玖玖爱视频网站| 亚洲国产精品9999在线观看| 久久精品国产精品亚洲艾通辽熟妇| 操B久久| 熟妇色99| 人人摸人人叼| 国产成人主播| 大色综合| 操一区| 中文在线视频| 99视频这有这里有精品| 国产免费一区二区三区最新不卡| 丝袜狠狠草尤物 91| 思思热在线视频免费| 日韩啪啪视频| 欧美91久久久久| 亚洲日韩视频二区| 天天综合网国产| 99热精品在线观看| 一级A片女人高潮叫床| 美女的肌被草喷水视频| 91无遮挡| 成人资源中文字幕在线观看天天| 久久九九精品一区二区| 看一级特黄a大一片| 自拍视频大全亚洲专媒视频/一区二区三区| 欧美熟妇精品黑人巨大91| 国产精品久久久久无码AV会牛| 国产极品久久久| 国产精品白领在线观看| 精品丰满人妻一区二区三区免费观| 后入式999| 围产精品一区二区三区视频播放| 亚洲在高跟鞋自慰久久在色线| 青青操网| 亚洲日韩青青草色月| 免费A片三p视频| 中日无幕一二三四区| 高清无码人妻久久久一区二区三区aⅴ| 国产大学生高潮在线播放| 日本精品一区二区三| 1769一区二区| 后入式999| 亚洲欧美激情在线视频| 欧美色亚洲色| 色综合99| 91麻豆天美传媒在线| 婷婷久久综合| 在线视频97| 91美腿丝袜在线观看| 国产精品无码在线| 校园春色亚洲色图| 91人妻超碰| 色色毛片| m欧洲一级午老| 精品一区二区综合熟妇| 蜜臀久久精品久久久久视频| 国产亚洲日本精品在线| 性感美女91影视| 啊啊啊啊一区| 性爱视频免费网址| 伊人 俄罗斯 a v| 久久亚洲精品成人av| 78m啪啪啪| 亚欧美天堂在线| 男女性感激情网站| 色原狠狠天天天| 色999人与兽| 国产精品爱欲| 超碰 国产熟女精品一区| 91九色在线| 老熟妇乱轮| 精国久久一区二区三区98| 性色av婷婷久久一区二区点复制| 色香av| 免费网色网站| 再深点灬舒服灬太大了好硬好爽| 久久少妇| 国产一区二区在线播放,久久亚洲精品中文字幕第一区,亚洲精品在线中文字幕视频 | 91少妇香蕉久久精品| 亚洲中文日韩欧美大香蕉视频| 亚洲精品97p| 好淫网一二三视区| 亚洲免费在线探花| 欧美性色欧美| 人人摸人人干| 欧美日韩在线视频网站| www.久久制服糖| 亚洲伊人a线观看视频| 青青草华人在线欧美在线| 嗯嗯啊中文字幕| 一线黄色免费性爱片| 久久久久久人体| 吉川爱美亚洲二区在线| 亚洲第一综合| 亚乱色| 探花精品 一区二区| 97超级色碰碰| 桃色六月天| 亚洲激情综合| 人妻人人做人人澡人人爽欧美一区| 国产精品久久久久久久久久久久| 久久AV色| 青青草视频导航官网| 国产玖玖| www.色婷婷色综合| 国产女人和拘做爰视频| 男人天堂网址| 91日韩网站| 日本三级韩国三级美三级91| 精品一区96| 五月丁香成人网| 国产浮力影院第1页| 国产精品白丝在线播放 | 一线黄色免费性爱片| 国产高清自拍| 成人青青草原伊人| 9997se| 国产乱码精品久久久久久| 嗯嗯,啊啊,国产精品| 久久xxxx| 国产精品视频白浆免费| 日本三级A片网站com| 超碰97人妻在线| 色欲久久99国产精品久久久久久| 综合97久久| 欧美91丝袜| 淫乱图区| 亚洲污污网站| 狠狠亚洲| 亚洲第一二区另类图| 欧美性,色九九| 偷窥自拍亚洲色图| 97舔舔| 久久日韩毛| 天天综合亚在线| 97干日韩| 色噜噜国产在线| 国产青一二三| 超碰在线974| 67194无码不卡| 色999偷自拍拍| 爱欲AV| av亚洲天堂资源网站| 啊啊啊好舒服好爽啊啊啊视频| 国产视频一区二区在线观看| 少妇被玩视频二三区| 日日干日日操五月天伦理视频| 午夜久久一区二区无码中出| 亚洲男人天堂网久久| 夜夜高潮夜夜爽高清视频一| 欧美在线色图| 久久一二三四不卡| B049AV在线播放| 色色青青久久| 日本大香蕉综合网红本杳社区| 久久丝袜| 久久久久久久免费A片国产成a人亚洲精∨品无码 | 欧美顶级黄色大片免费| 国产精品香蕉热久久新品| 欧美人人AAA| 日韩一级二级| 少妇一区二区三区在线观看| 91国产美女丝袜足交精品视频| 欧美国产有色电影| 久久久久久99999国产精品| 天天综合,91入口| 青青草福利视频| 国产高清视频无码在线| 操操操日本的逼| 日本3级一区二区免费| 96精品在线| 嗯嗯,好大,好爽,好骚 | 91爆操视频| 婷婷99狠狠躁天天躁| 超碰国产情侣自拍网| 欧美成人综合| 在线视频资源| 精品亚洲一区在线观看| 亚洲少妇中文字幕网址| 伊人网av| 精品999日本| 少妇精品| 日韩美女啪啪一区| 91超级碰| 四虎国产成人精品免费一女五男| 97国产精品久久久久| 欧美色偷偷| 美女写真| 超碰国产情侣自拍网| 超碰碰小说97| a亚洲欧美色欲| 很很热性爱视频| sss视频华人在线| 黑人综合色| 100啪啪视频大全| 色五月激情综合网| 91国产大片| 亚洲人妻日日日| 日韩性爱1级片视频| 久久久一级| 粉嫩av一区二区三区四季| 欧美少妇人妻| 欧美黄片视频在线观看免费 | 婷婷爽人人婷婷爽视频| 欧美亚洲尤物久久| 四月丁香婷婷| 丰满人妻-区二区三区免费看| 亚洲小电影免费涩涩成人在线高清| 国内外色色色色色成人视频| 国产女人9999| 熟女激情综合网| 熟女精品一区二区三区| 超碰伊人在线| 91av一区二区在线观看| 亚洲性综合9| 日本亚洲嫩草影院啪啪| 一级特级aaaa毛片免费观看 | 黑人综合网| 国产精品成人在线| 天天插天天操天天摸天天射天天看| 色色毛片| 超碰超碰95| 97色综合中文网| 曰韩av中文字幕专区| 操91| 天天看天天在线精品| 超碰1024久久| 精品国产三级av韩国在线| 成人资源中文字幕在线观看天天 | 91N欧美| 亚洲高清色综合| 99自拍视频在线| 精品在线78| 亚洲中文字幕av| 蜜桃久久一区| 亚洲色诱惑| 亚洲天在线| 欧美做爰无码A片视频| 日本五区不卡| 婷婷AV一区二区三区| 欧美高潮| 激情五月天社区| 99久久免费看精品国产一区| 欧美强奸一区二区诱惑| 欧美高清在线| 久久性爱城| 日本大香蕉综合网红本杳社区| 日韩人妻无码专区| 国产人妻久久精品一区二区三区| 人人考人人摸人人干| 日日骚一区二区三区| 婷婷色色五月天| 欧美激情专区| 日本天堂网| 超碰色男人操熟女| yy少妇精品久久| 综合久久欧美| 殴美性天天| 91蜜臀在线久久久久| 欧美不卡在线一区二区| 天天看片麻豆| 国产成人精品日本视频| 99操逼| 亚洲欧洲视频小说在线观看| 超碰日韩人妻| 91 综合 色| www.久久99| 亚洲国产另类在线中文| 精品人妻视频一区二区三区蜜桃视频| 最新亚洲人成网站在线影院| 亚洲天堂电影网| www.99视频| 亚洲欧美国产va在线播放频| A啊啊在线观看| 熟女人妻一区二区三区| 亚欧美色| 天天综合网1| 色综合久久888| 一区二区三区美女超清| 中国黄色特级精品一区二区三区片| 操婷婷逼| 99久久亚洲精品无码毛片潘甜甜| 超碰98综合网| 色色婷婷五月天| 欧美日韩*字幕一区| 台湾佬中文娱乐网久久久久久久久久com | 亚洲女毛多水多21P| 久久久久久久97| 中文字幕久久亚州无码| 一区二区日韩欧美久久| 国产福利视频精品视频| 午夜舔阴达高潮视频免费看| 亚洲欧美国产日本一区二区三区| 国产精品女aA片爽爽视频| 久草男人天堂| 天天综合精品| 美国一区二区三区视频| 国产精品一区二区三区免费视频| 91草草草| 殴美牲| 偷拍自拍在线视频观看| 18禁看网站一区| 天天综合91入口| 亚州综合AⅤ| 亚洲有薄码区日本系列中文字幕| 国产高清26uuu| 欧美第一页| 香蕉国产97| 伊人991| 免費人妻夜夜爽天天爽爽一区| 在线人人人人人人精品超 | 99国产天美| 亚洲色五月| 亚洲国产麻豆一区二区三区| 日本一级特级毛片视频| 日韩综合第八区国产精品| 绑缚麻绳人妻寝取完整版| 天美传媒一二三区永久网站| 黄页视频网站野外| 国产黄色视频久久| 国产精品自拍视频| 97亚洲综合在线| 裸体美女久久久| 久久久av爱| 久操黄色视频| 激情五月天婷婷| 四虎影院成年人片| 极品尤物自安慰| 17c在线成人免费A片观看| 精品九九九九| 欧美性第一页| 97免费视频在线| 91日韩网站| 日韩青久久| 欧美精品,四区。五区| 91麻豆一二三区| 久久香蕉超碰97国产精品| 色女99一级片在线观看| 99热综合在线| 丝袜六区| 玖玖97综合| 欧美.亚洲.另类.丝袜.制服.诱惑| 激情综合久久| 99色热| 五月天婷婷成人网| 久久乐| 久久久精品国产亚洲伊人| 五月天婷婷欧美三区| 色色色网站| 骚货人妻偷情自拍在线视频| 四虎AV在线观看| 懂色AV一区二区三区| 天无日色综合| 亚洲精品97在线| 日韩/97| 久久99999| 亚洲色图 图片| 99这里都是精品| 狠狠色五月亚洲91| 国产农村妇女毛片精品久久| 蜜臀久久久99久久久久| 色香AV| 欧美爱三级日韩久久| 久草国产在线视频| 欧美日韩中文亚洲v在线综合|