私は最近、ユーザー操作を元に戻す、またはやり直す機能を備えたビジュアル操作プラットフォームを開発しています。オンラインでいくつかのソリューションを検索し、思い描いたソリューションを完成させました。 履歴記録要件の要点
一見単純な要件ですが、インフラストラクチャ設計のエラーにより、将来的に作業負荷が増大することになります。したがって、上記 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アプリケーションを実行する方法
ファイル操作に関連するシステムコール作成するint creat(const char *ファイル名,...
1. はじめにレスポンシブ Web デザインにより、Web サイトは複数のデバイスと複数の画面に同時...
I. 概要HTML テンプレートを作成するときに、テキスト レイアウトの手段としてスペースが使用さ...
LinuxでのMySQL-5.7.19バージョンの初心者向けの最初のインストールについては、前の記事...
目次目的実験環境実験原理実験手順1. 独立したCAを生成する2. サーバーの秘密鍵と署名要求ファイル...
コンセプト紹介: 1. px (ピクセル):仮想的な長さの単位で、コンピュータ システムのデジタル画...
方法1: SET PASSWORDコマンドを使用するまずMySQLにログインします。フォーマット: ...
<br />Web ページをデザインするときには、いつも不快なことに遭遇します。最も一般...
方法1:フロート:右さらに、フローティングにするとレイアウトがよりコンパクトになります(隙間がなくな...
1. 改行なしを実現するには<nobr>タグを使用するコードをコピーコードは次のとおりで...
この記事の例では、Vueモバイル端末で指のスライド効果を実現するための具体的なコードを紹介します。具...
目次Vuex は単一の状態ツリーを使用するため、すべてのアプリケーション状態が比較的大きなオブジェク...
1. pipとは何かpip は、Python パッケージの検索、ダウンロード、インストール、アンイ...
ページ A、B、C の 3 つがあります。ページ A にはページ B が含まれ、ページ B にはペー...
1. mysqlエクスポートファイル: SELECT `pe2e_user_to_company`....