Vue で変数式セレクターを実装する方法

Vue で変数式セレクターを実装する方法

入力ボックスに式を入力することは、ミドルオフィス プロジェクトでは一般的なシナリオです。通常、特定の文字 ($ など) を入力すると、ドロップダウン リストが表示されます。ユーザーはドロップダウン リスト内の変数をクリックし、入力ボックスに他の演算子を入力し続けて式を作成します。効果は次のようになります。

前回のプロジェクトでは、React + TypeScrpt を使用して、React 版の変数式セレクターを実装しました。この記事では、Vue を使用して変数式セレクターを実装する方法を紹介します。

この変数式により、次の効果が得られます。

  1. 入力ボックスに特定の文字を入力すると、ドロップダウン リストが表示されます。
  2. キーボードの上下キーを押すことでドロップダウン オプションを切り替えることができます。ドロップダウン オプションをマウスでクリックするか、Enter キーを押すと、選択した内容が入力ボックスに表示されます。
  3. 入力文字の任意の位置にカーソルを移動し、ドロップダウン リストでコンテンツを選択すると、選択したコンテンツが現在のカーソル位置に表示されます。
  4. ドロップダウン リストが表示されているが、コンテンツが選択されていない場合、入力ボックスは入力禁止になります。コンテンツが選択された後、入力ボックスは引き続きコンテンツを入力できるようになります。
  5. 入力ボックスの履歴の表示を無効にします。

HTML構造の定義

既存のセレクターでは必要な効果が得られないため、セレクターを独自に実装する必要があります。 input タグを選択セレクターの入力ボックスとして使用し、ul li タグを選択セレクターのドロップダウン リストとして使用します。基本的な HTML 構造は次のとおりです。

<div class="式コンテナ">
 <入力 />
 <div v-if="表示可能" クラス="式リストボックス">
 <ul class="式UlBox">
  <li></li>
 </ul>
 </div>
</div>

入力タグバインディング属性

Vue では、要素またはサブコンポーネントの参照情報を登録する場合は、ref 属性を追加する必要があります。 ref を使用して登録された参照情報は、親コンポーネントの refs オブジェクトに登録されます。操作が必要な要素またはサブコンポーネントは、refs オブジェクトを通じて見つけることができます。そのため、input タグに ref 属性を追加します。

<input ref="inputRef" />

入力タグに ref 属性を追加するだけでなく、入力タグにイベントをバインドする必要もあります。 Vue では、通常、イベントをバインドするために v-on (略語: @) を使用します。 blur、keydown、input イベントを input タグにバインドします。

<入力
 ref="入力参照"
 v-model="expressValue"
 クラス="ant-input"
 :readOnly="読み取り専用 ? true : false"
 オートコンプリート="オフ"
 :placeholder="プレースホルダー"
 @blur="inputOnBlurHandle"
 @keydown="inputOnKeyDownHandle"
 @change="onchangeHandle"
 @input="onInputHandle"
/>

入力タグはキーダウンイベントをリッスンします

keydown イベントを input タグにバインドし、このときに押されたキーボードのキーをリッスンします。shift + $ を同時に押すと、ドロップダウン リストが表示され、入力ボックスの現在の値が保存され、input タグは編集不可に設定され、ドロップダウン リストからコンテンツのみを選択できるようになります。 keydown にバインドされたイベント処理関数は次のとおりです。

// 入力ボックスのキーダウンイベント inputOnKeyDownHandle(e) {
 // Shift + $ キーを同時に押す if (e.keyCode === 52 && e.shiftKey) {
 // 入力ボックスの値を取得します。const expressValue = e.target.value;
 this.setInputValue(expressValue);

 // 現在のカーソル位置を取得します。const position = getPositionForInput(this.$refs.inputRef);
 // 現在のカーソルの開始位置 const cursorIndex = position.start;

 // カーソルの位置を入力の範囲プロパティに設定します // updateRange(this.$refs.inputRef);

 // カーソルの開始位置を保存します。this.saveCursorIndex({ start: cursorIndex });
 // ドロップダウン選択ボックスを表示するように設定します。this.setSelectedBoxVisible(true);
 // 入力タグを編集不可に設定し、ドロップダウン リストからの選択のみを許可します。this.setInputIsReadonly(true);
 }
},

li タグバインディング属性

選択セレクターは、ul li タグを使用して実装されます。ドロップダウン オプションを選択する場合は、li タグを操作する必要があるため、li タグに ref 属性とクリックおよびキーダウン イベントを追加し、HTML5 の data-* 属性を使用してオプション値を保存する必要があります。

<ul ref="ulRef" class="expressionUlBox">
 <li
 v-for="(item, index) オプション内"
 ref="liRef"
 :key="アイテム.フィールド"
 :data-set="アイテム"
 :data-index="インデックス"
 :data-value="アイテムフィールド"
 タブインデックス="0"
 @click="liClickHandle"
 @keydown="liKeyDownHandle"
 >
 {{アイテム名}}
 </li>
</ul>

liタグがフォーカスされる

通常の div/span/li およびその他の要素ノードは、直接フォーカスを取得できません。 div/span/li などの要素ノードの onfocus イベントと onblur イベントをトリガーする必要がある場合は、それらに tabindex 属性を追加する必要があります。 tabindex 属性は、実際には、コンピュータ上で「Tab」ボタンがクリックされたときにカーソルが移動する位置を指定します。コンピュータ上で「Tab」ボタンがクリックされたとき、tabindex 属性の値が小さいほど (最小値は 0)、タブがフォーカスを取得するまでの時間が短くなります。

実装した選択セレクターでは、オプション値を切り替えるためにキーボードの上下キーを使用する必要があるため、li が onfocus イベントと onblur イベントをトリガーできるように、 li タグに tabindex 属性を追加する必要があります。

<li tabindex="0"></li>

グローバルキーボードイベントリスナー

キーボード イベントをグローバルに監視するということは、実際にはイベントをドキュメントにバインドすることを意味します。作成されたライフサイクル フックでキーボード イベントをリッスンします。現在押されているキーが上キーまたは下キーの場合、ドロップダウン オプションは上キーまたは下キーを使用して切り替えることができます。

作成された() {
 _this は定数です。
 document.onkeydown = 関数(){
 定数キー = window.event.keyCode;
 // 上下キーif (key === 38 || key === 40) {
  _this.upAndDownKeySwitch(キー);
 }
 //左と右のキー else if (key === 39 || key === 37) {
  // _this.leftAndRightKeySwitch(キー);
 }
 };
},

キーボードの上下キーを使用してセレクター ドロップダウン オプションを切り替える処理ロジックは次のとおりです。

// キーボードの上下キー選択式 upAndDownKeySwitch(key) {
 liNodes を this.$refs.liRef に設定します。
 liNodes の長さを定数で指定します。

 // Dw 矢印キー if (liNodes && liLength && key === 40) {
 定数カウント =
  this.arrowCount.dwArrow === liLength - 1
  ? 0
  : this.arrowCount.dwArrow + 1;
 // フォーカスを取得したときに最初の li が表示領域に表示されない問題を解決するためにパディングを設定します if (liLength > 1) {
  (カウント === 0)の場合{
  this.$refs.ulRef.style.padding = "40px 0 10px 0";
  } それ以外 {
  this.$refs.ulRef.style.padding = "10px 0";
  }
 }
 
 // 現在のli要素がフォーカスを取得します liLength && liNodes[count].focus();
 // 現在フォーカスされている li 要素が可視領域に表示されるように ul の scrollTop を設定します if (count === liLength - 1) {
  // 最後の li 要素が表示領域に表示できない問題を解決します this.$refs.ulRef.scrollTop = count * 40;
 } それ以外 {
  this.$refs.ulRef.scrollTop = count * 10;
 }

 // カウントステータスをコンポーネントのコンテンツ状態に保存します。this.arrowCount = { upArrow: count, dwArrow: count };
 }

 // 上矢印キー if (liNodes && liLength && key === 38) {
 定数カウント =
  this.arrowCount.upArrow <= 0
  ?li長さ - 1
  : this.arrowCount.upArrow - 1;
 // フォーカスを取得したときに最初の li が表示領域に表示されない問題を解決するためにパディングを設定します if (liLength > 1) {
  if (count === liLength - 1) {
  this.$refs.ulRef.style.padding = "10px 0 40px 0";
  } それ以外 {
  this.$refs.ulRef.style.padding = "10px 0";
  }
 }
 // 現在のli要素がフォーカスを取得します liNodes[count].focus();
 // ul の scrollTop を設定して、現在フォーカスされている li 要素が表示領域に表示されるようにします。this.$refs.ulRef.scrollTop = count * 60;
 // カウントステータスをコンポーネントのコンテンツ状態に保存します。this.arrowCount = { upArrow: count, dwArrow: count };
 }
},

入力タグの値を設定する

デフォルトでは、入力した文字の任意の位置にカーソルを移動し、ドロップダウン オプションを選択すると、入力した文字の末尾にオプション値が挿入されます。現在のカーソル位置にオプション値を挿入したいので、カーソル位置を計算し、正しい位置にオプション値を追加する必要があります。これには、カーソルの位置とテキストの選択に関する関連知識が必要です。詳細については、「選択」を参照してください。

/**
 * テキストを挿入 * @param ctrl 入力要素オブジェクト (input、textarea など)
 * @param inputValue 入力ボックスの値*/
エクスポート関数 insertAtCursor(ctrl, inputValue) {
 // IE サポート
 if (ドキュメント選択) {
 Ctrl+Focus();
 // ドキュメント.選択.作成範囲() 
 // 現在のテキスト選択に基づいて TextRange オブジェクトを返すか、コントロール選択に基づいて ControlRange オブジェクトを返します。const sel = document.selection.createRange();
 // 現在の TextRange オブジェクトにテキストを設定します。sel.text = inputValue;
 } そうでない場合 (ctrl.selectionStart || ctrl.selectionStart === 0) {
 // selectionStart テキスト選択領域の開始位置 // selectionEnd テキスト選択領域の終了位置 // MOZILLA など
 定数開始位置 = ctrl.selectionStart;
 定数 endPos = ctrl.selectionEnd;
 // カーソル位置に値を挿入 ctrl.value =
  // カーソル位置の前の値 ctrl.value.substring(0, startPos) +
  //挿入する値 inputValue +
  //カーソル位置の後の値 ctrl.value.substring(endPos, ctrl.value.length);
 // カーソルの位置をリセットします // 値を挿入した後、カーソルの位置は文字列の末尾にある必要があります // ページ上の点滅するカーソルは、実際には幅 0 の特別な選択範囲です。簡単に言えば、選択範囲の左と右の境界が交差してカーソルを形成します ctrl.selectionStart = startPos + inputValue.length;
 ctrl.selectionEnd = 開始位置 + 入力値の長さ;
 } それ以外 {
 ctrl.value += 入力値;
 }
 // 入力要素オブジェクト (input、textarea) がフォーカスを取り戻します。このとき、カーソルの位置は入力文字の末尾にあるはずです。ctrl.focus();
}

フルエフェクトプレビュー

以上が、Vue が変数式セレクターを実装する方法の詳細です。Vue の変数式セレクターの実装の詳細については、123WORDPRESS.COM の他の関連記事に注目してください。

以下もご興味があるかもしれません:
  • Vue 日付時刻ピッカーコンポーネントの使い方の詳細な説明
  • Cascaderカスケードセレクタデータエコーを使用したVueの落とし穴についての簡単な説明
  • Vueはマルチラベルセレクタを実装する
  • Vant で時間セレクターを実装するための Vue サンプル コード
  • mpvue WeChat アプレットの複数列セレクターの使用により、州と都市の選択を実現
  • Vueアイコンセレクターのサンプルコード

<<:  Mysql が CPU を過剰に占有する場合の最適化方法 (必読)

>>:  Docker チュートリアル: コンテナの使用 (簡単な例)

推薦する

よく使われる HTML 形式のタグ_Powernode Java Academy

1. タイトルHTML では、<h1></h1> から <h6>...

Node.jsを使用してホットリロードページを実装する方法の詳細な説明

序文少し前に、browser-sync+gulp+gulp-nodemon を組み合わせて、本番環境...

Vueはメニューナビゲーションを実装するためにelement-uiを使用します

この記事では、Element-uiを使用してメニューナビゲーションを実装するVueの具体的なコードを...

Linux でのファイル コンテンツの重複排除と交差と差異の実装

1. データ重複排除日常業務では、Hive や Impala を使用してクエリとエクスポートを行う際...

UbuntuからMySQLを削除して再インストールする方法

まずmysqlを削除します: sudo apt-get remove mysql-*残ったデータをク...

JavaScript のガベージコレクションの仕組みの詳細な説明

目次ガベージコレクション (GC) はなぜ必要なのでしょうか?ガベージコレクションとは廃棄物の発生ガ...

WebプロジェクトのDockerデプロイメントの実装

前回の記事では、docker サービスをインストールしました。引き続き、Web プロジェクトのデプロ...

Docker で Docker0 ブリッジのデフォルトのネットワーク セグメントを変更する方法

1. 背景Docker サービスが開始されると、デフォルトで docker0 ブリッジが作成され (...

CSS3はシームレスなスクロールと手ぶれ防止を実現します

質問画像とテキストのシームレスなスクロールは、一般的に携帯電話では良い効果をもたらしますが、一部のモ...

Linux で Docker を使用して MySQL をインストールする手順

テスターとして、学習プロセス中に Linux でソフトウェアをインストールする必要が頻繁にある場合が...

Linuxホスト名変更コマンドの詳しい説明

Linux ホスト名変更コマンド1. ホスト名を一時的に変更するだけの場合は、hostname コマ...

純粋なCSS3で実装されたネオンライト効果

達成される効果は次のとおりです。 マウスがボタン内に移動すると、ネオンライトのような効果が生成され、...

JS クロスドメイン ソリューション React 構成 リバース プロキシ

クロスドメインソリューションjsonp (get をシミュレート) CORS (クロスオリジンリソー...

CentOS8 で Docker を使用してオープンソース プロジェクト Tcloud をデプロイするチュートリアル

1. Dockerをインストールする1. 仮想マシンに Centos7 をインストールしました。Li...

ウェブサイト上のWeiboコンポーネントの再設計の詳細な紹介(写真とテキスト)

前面に書かれたWeibo コンポーネントは、サードパーティのアクセス ユーザーが開発を必要とせずに ...