私は最近、ユーザー操作を元に戻す、またはやり直す機能を備えたビジュアル操作プラットフォームを開発しています。オンラインでいくつかのソリューションを検索し、思い描いたソリューションを完成させました。 履歴記録要件の要点
一見単純な要件ですが、インフラストラクチャ設計のエラーにより、将来的に作業負荷が増大することになります。したがって、上記 2 点の要件を組み合わせると、vuex の基本的な考え方がこの要件を満たすのに非常に適していることがわかります。これは redux にも当てはまります。 実装のアイデアこのプロジェクトでは、コードの厳密性を高め、将来のメンテナンスを容易にするために TypeScript を使用しています。そのアイデアを見てみましょう。 1. まず履歴記録のデータ構造を定義するインターフェース HistoryItem { timestrap: number; // レコードのタイムスタンプ name: string; // レコード名 redo: string; // 変更をやり直す undo: string; // 変更を元に戻す redoParams: any[]; // Redo Mutation 送信パラメータ undoParams: any[]; // Undo Mutation 送信パラメータ } インターフェース HistoryStatus { historys: HistoryItem[]; // 記録履歴 array_currentHistory: number; // 現在のノードインデックス} 2. 履歴状態モジュールを書く基本的な操作履歴状態用の vuex モジュールを記述し、記録された変更を作成し、アクションをやり直したり元に戻したりする したがって、ユーザーが空のレコードをクリックして最初の操作を元に戻すことが簡単にできるように、空のレコードを追加する必要があります。 vuex-module-decoratorsを使用して、より保守しやすいコードを書く 「vuex-module-decorators」から VuexModule、Module、Mutation、Action をインポートします。 @Module({名前空間: true }) エクスポートクラス HistoryModule は VuexModule<HistoryStatus> を拡張し、HistoryStatus を実装します { /** * 空のレコードを初期化する主な理由は、リスト操作を容易にするためです。 * ユーザーが最も古いレコードをクリックすると、ユーザーの操作の最初のステップを正常に元に戻すことができます**/ 公開履歴:HistoryItem[] = [ { 名前: `Open`、 タイムストラップ: Date.now(), やり直し: "", 再実行パラメータ: [], 元に戻す: "", 元に戻すパラメータ: [], }, ]; パブリック_currentHistory: 数値 = 0; // ゲッター 現在の値を取得する(){ this._currentHistory を返します。 } // ゲッター historyList() を取得します: HistoryItem[] { this.historys || [] を返します。 } // 履歴を作成 @Mutation パブリック CREATE_HISTORY(ペイロード: HistoryItem) { this._currentHistory < this.historys.length - 1 の場合 { this.historys = this.historys.slice(0, this._currentHistory); } // js の深いコピーと浅いコピーの問題により、作成時にデータを深くコピーする必要があります // lodash の clone 関数を試してみたいのですが、JSON.stringify の clone メソッドの方が高速であることがわかりました。結局のところ、関数内にデータは存在しません // ここでは変更しません。主にアイデアを表現するためです this.historys.push(_.cloneDeep(payload)); this._currentHistory = this.historys.length - 1; } @突然変異 パブリックSET_CURRENT_HISTORY(インデックス: 数値) { this._currentHistory = インデックス < 0 ? 0 : インデックス; } // @Action をやり直す パブリック RedoHistory(回数: 数値 = 1) { {state、commit} = this.context; とします。 履歴を: HistoryItem[] = state.historys; 現在の状態を数値とする。 (現在 + 回数 >= history.length) の場合、戻り値: (times > 0) の間 { 現在の++; history = history[current]とします。 if (履歴) { コミット(history.redo、...history.redoParams、{root: true}); } 回--; } コミット("SET_CURRENT_HISTORY", 現在の); } // @Actionを元に戻す パブリックUndoHistory(回数: 数値 = 1) { {state、commit} = this.context; とします。 履歴を: HistoryItem[] = state.historys; 現在の状態を数値とする。 (現在値 - 回数 < 0) の場合は return; (times > 0) の間 { history = history[current]とします。 if (履歴) { コミット(history.undo、...history.undoParams、{root: true}); } 回--; 現在 - ; } コミット("SET_CURRENT_HISTORY", 現在の); } } 3. 元に戻す機能とやり直し機能を書く上記の2つのステップを完了すると、さまざまな操作を記述できます。 データに対する基本的な操作のためのミューテーションを記述する @突然変異 パブリック CREATE_PAGE(ペイロード: { ページ: PageItem; インデックス: 数値 }) { this.pages.splice(payload.index, 0, _.cloneDeep(payload.page)); this._currentPage = this.pages.length - 1; } @突然変異 パブリック REMOVE_PAGE(id: 文字列) { index = this.pages.findIndex((p) => p.id == id); とします。 インデックス > -1 && this.pages.splice(index, 1); if (this._currentPage == インデックス) { this._currentPage = this.pages.length > 0 ? 0 : -1; } } 必要に応じて、保存->記録->実行というアクションに基本的な操作をカプセル化します。 //パッケージ作成ページ関数@Action パブリックCreatePage(タイプ: "ページ" | "ダイアログ") { {state、commit} = this.context; とします。 // 作成されるページを記録して保存します。let id = _.uniqueId(type) + Date.now(); pageName = pageType[type]とします。 ページ: PageItem = { id、 名前: `${pageName}${state.pages.length + 1}`, タイプ、 レイヤー: [], スタイル: { 幅: 720, 高さ: 1280 }, }; //履歴を作成する let history: HistoryItem = { 名前: `${pageName} を作成`, タイムストラップ: Date.now(), やり直し: "ページ/CREATE_PAGE", redoParams: [{ index: state.pages.length - 1, page }], 元に戻す: "ページ/REMOVE_PAGE", undoParams: [id], }; // この履歴を保存して記録します commit("Histroy/CREATE_HISTORY", history, { root: true }); コミット(history.redo、...history.redoParams、{root: true}); } @アクション パブリックRemovePage(id: string) { // 現場の状況を記録して保存します。let index = this.pages.findIndex((p) => p.id == id); if (インデックス < 0) 戻り値: ページを作成します: PageItem = this.context.state.pages[index]; //履歴を作成する let history: HistoryItem = { 名前: `${page.name} を削除`, タイムストラップ: Date.now(), やり直し: "ページ/REMOVE_PAGE", 再実行パラメータ: [id], 元に戻す: "ページ/CREATE_PAGE", undoParams: [{ページ,インデックス}], }; // この履歴レコードを保存します this.context.commit("Histroy/CREATE_HISTORY", history, { root: true }); this.context.commit(history.redo, ...history.redoParams, { root: true }); } 以上で、元に戻す機能とやり直し機能は基本的に完了です。 4. 使用1. ページを作成または削除するときに、カプセル化された「アクション」を使用するだけで済みます。 プライベート作成(タイプ: "ページ" | "ダイアログ") { this.$store.dispatch("Page/CreatePage", type); } プライベート削除(id: 数値) { this.$store.dispatch("Page/RemovePage", id); } 2. グローバルホットキーを設定する タイプスクリプトApp.vue プライベートマウント() { 自分自身 = this とします。 ホットキー("ctrl+z", 関数(イベント, ハンドラー) { self.$store.dispatch("履歴/元に戻す履歴"); }); ホットキー("ctrl+y", 関数(イベント, ハンドラー) { self.$store.dispatch("履歴/再実行履歴"); }); } 効果 これで、vuex で履歴レコードを実装するためのサンプルコードに関するこの記事は終了です。より関連性の高い vuex 履歴レコードについては、123WORDPRESS.COM の以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。 以下もご興味があるかもしれません:
|
<<: MySql 8.0.11 のインストール プロセスと Navicat とのリンク時に発生する問題の概要
>>: DockerでSpring Bootアプリケーションを実行する方法
text-fill-color とは何を意味しますか?文字通りの意味から言えば、「テキストの塗りつぶ...
01PARTCoreWebApiチュートリアルローカルデモ環境Visual Studio2019--...
この記事では、MySQL データベースの一般的な操作テクニックをまとめます。ご参考までに、詳細は以下...
ナビゲーションバーの作成:技術要件: CS HTMLタグ達成目的:ナビゲーションバーメニューの作成コ...
1. 問題の説明セキュリティ上の理由から、新しく構築されたサーバー クラスターでは、指定されたポート...
目次1. Nginxロケーションの基本設定1.1 Nginx 設定ファイル1.2 Pythonスクリ...
1. my.iniファイルにskip-grant-tablesを追加し、MySQLサーバーを再起動し...
この記事では、js+canvasコードの雨効果の具体的なコードを参考までに共有します。具体的な内...
apache: ポートに基づいて仮想ホストを作成する仮想ホスト(a、b、c)の作成を例に挙げます1)...
目次マスタースレーブレプリケーションメカニズム非同期レプリケーション準同期レプリケーションマスタース...
目次序文JSON.stringify の 6 つの機能特集1特集2特集3特集4特集5特集6手動で文字...
序文SQL モードは、MySQL がサポートする SQL 構文と、実行されるデータ検証チェックに影響...
1. Tomcatをインストールする1. Docker HubでTomcatイメージを見つける d...
一般的に、マウスは上向きの斜め矢印として表示され、テキストの上に移動すると垂直線になり、ハイパーリン...
目次序文:暗号化アルゴリズム: 1. HTTPS の概要2. NginxはHTTPSウェブサイト設定...