Vueドロップダウンリストの2つの実装方法の比較

Vueドロップダウンリストの2つの実装方法の比較

Vueドロップダウンリストの2つの実装

最初の方法はv-forを使用する

  <el-select v-model="form.columeType" placeholder="フィールドタイプ">
           <el-option v-for="(item,index) in columeTypeArr" :key="index" :label="item.label" :value="item.value">
           </el-option>
  </el-select>

このメソッドでは、次のようにデータにcolumeTypeArrを定義する必要があります。

データ(){
    戻る {
       列タイプArr:[{
            値:'文字列',
            ラベル:'文字列'
        },{
            値:'Int',
            ラベル: '整数',
        },{
            値: '10進数',
            ラベル:'数値型'
        }],
    }
}

2番目の方法はデッドライティング法を使うことです

選択の下に直接記入してください

  <el-select v-model="form.fileOrgType" placeholder="選択してください">
        <el-option ラベル="はい" 値="Y"> </el-option>
        <el-option label="いいえ" value="N"></el-option>
  </el-select>

2 つの方法の比較:

2 つの方法は似ていますが、最初の方法はデータで構成する必要がある点が異なります。バックグラウンドからデータをエコーする必要がある場合は、明らかに最初の方法の方が適しています。

パラメータが少ない単純なドロップダウン リストの場合、2 番目の方法の方が明らかに有利です。

Vueドロップダウンメニューコンポーネントの実装

Vue ドロップダウン メニュー コンポーネントを実装してみましょう。

インターネット上にはすでにこのような基本的な UI コンポーネントが多数存在しているのに、なぜ自分で実装する必要があるのでしょうか?実際のところ、車輪の再発明をするつもりはありませんが、このプロセスを通じて、Vue コンポーネント開発の詳細と注意事項をいくつか確認したいと思います。

ドロップダウン メニュー コンポーネントを選択する理由は何ですか?

理由: 小さいながらも、必要な機能がすべて備わっています。この小さなコンポーネントには、Vue コンポーネント開発に関する多くの知識ポイントが含まれています。

さあ、始めましょう!

まず、vue-cliプロジェクトを作成します。私はvue-cli3を使用します。作成プロセスは省略します。次に、vueコンポーネントを作成します: DropDownList.vue

テンプレートを記述する前に、このコンポーネントのビュー構造と機能を分析しましょう。

ドロップダウン メニュー コンポーネントは、次の 2 つの部分で構成する必要があります。

選択した項目のテキスト

選択メニュー(デフォルトでは非表示)

主な機能は次のとおりです。

マウスがドロップダウンメニューコンポーネント上を通過すると、選択するメニューが表示されます。

選択するメニューを非表示にするには、ドロップダウンメニューコンポーネントからマウスをスライドさせます。

選択メニュー内の項目をクリックすると、選択した項目のテキストが更新され、コンポーネントは変更イベントを送信します。

次のテンプレートを記述します。

<テンプレート>
  <div class="zq-drop-list" @mouseover="onDplOver($event)" @mouseout="onDplOut($event)">
        <span>選択した項目のテキスト<i></i></span>
        <ul>
            <li>北京</li>
            <li>上海</li>
            <li>広州</li>
        </ul>
    </div>
</テンプレート>

選択された項目のテキストの右側にある i タグは、ドロップダウン メニューの三角形のアイコンを実装するために使用されます。以下の CSS では、背景画像を使用してこれを実装しています。

ルート要素 div にマウスオーバーとマウスアウトのコールバック関数を追加しました。具体的な実装については以下を参照してください。

次に、このドロップダウン メニューのスタイルを記述し、テンプレートの下にスタイル タグを追加します。他のコンポーネントのスタイルとの競合を防ぐために、コンポーネントを開発するときには、スタイルに scoped 属性を追加することをお勧めします。なお、ここではscssを使用しており、具体的なコードは以下のとおりです。

<スタイル スコープ lang="scss">
    .zq-ドロップリスト{
        表示: インラインブロック;
        最小幅: 100px;
        位置: 相対的;
        スパン{
            表示: ブロック;
            高さ: 30px;
            行の高さ: 30px;
            背景: #f1f1f1;
            フォントサイズ: 14px;
            テキスト配置: 中央;
            色: #333333;
            境界線の半径: 4px;
            私{
                背景: url(https://www.easyicon.net/api/resizeApi.php?id=1189852&size=16) 繰り返しなし 中央 中央;
                左マージン: 6px;
                表示: インラインブロック;
            }
        }
        ul{
            位置: 絶対;
            上: 30px;
            左: 0;
            幅: 100%;
            マージン: 0;
            パディング: 0;
            境界線: 実線 1px #f1f1f1;
            境界線の半径: 4px;
            オーバーフロー: 非表示;
            li{
                リストスタイル: なし;
                高さ: 30px;
                行の高さ: 30px;
                フォントサイズ: 14px;
                下部境界線: 実線 1px #f1f1f1;
                背景: #ffffff;
            }
            li:最後の子{
                下部境界線: なし;
            }
            li:ホバー{
                背景: #f6f6f6;
            }
        }
    }
</スタイル>

スタイルに関しては、ここでは詳しく説明しません。注意が必要な点をいくつか挙げます。

i 要素のスタイルはインターネット上の画像を使用しました。自分で変更することもできます。

選択メニューの ul は css で隠されていません。js で制御したいからです。具体的な理由は次のとおりです。

選択メニュー ul は、展開されたときにページ上の他の要素のレイアウトに影響を与えないように、絶対配置を使用します。

コンポーネントは次のようになります。

このコンポーネントのプロパティの定義を続けます。当然ですが、選択するメニューはプロパティとして渡す必要があり、内部でハードコードしてはなりません。プロパティの定義は次のとおりです。

<スクリプト>
エクスポートデフォルト{
    名前: "DropDownList",
    小道具:{
        データリスト:{
            タイプ:配列、
            デフォルト(){
                戻る [
                    {名前: "オプション 1"},
                    {名前: "オプション 2"}
                ]
            }
        },
        ラベルプロパティ:{
            タイプ:文字列、
            default(){ "name" を返す }
        }
    },
    データ(){
        戻る {
            アクティブインデックス:0
        }
    },
}

このうち、dataList は選択するメニューのデータ ソース属性です。ここでは、この属性の既定値を定義します。これは、著者が身に付けることを推奨する習慣でもあります。コンポーネントとしては、既定値を持つのが最適です。他の人がコンポーネントを使用するときに、関連する属性を最初に設定しなくても完成品の効果を確認でき、コンポーネントに必要な属性のデータの詳細をすばやく表示できるためです。

もう 1 つの属性は labelProperty です。この属性の機能は何ですか?実際のプロジェクトのデータ ソースには、必ずしも名前フィールドが含まれているとは限らないため、ドロップダウン メニューでデータ テキストをレンダリングできない可能性があります。そのため、この属性を定義して、実際のデータ ソースがテキストをレンダリングするフィールドを指定します。このフィールドは文字列である必要があります。このプロパティのデフォルト値は name です。これは、デフォルトのデータ ソースと一致する必要があるためです。コンポーネントの内部データである activeIndex もご覧になったと思います。これは、現在選択されている項目のインデックスを示すために使用され、後ほど使用します。

これで、このコンポーネントを他の場所にインポートして使用できるようになりました。まだ完成していませんが、まずはインターフェイスに表示してみましょう。

<テンプレート>
  <div class="home">
    <ドロップリスト:dataList="dplist" labelProperty="city" @change="onDpChange($event)"></ドロップリスト>
    <p>その他のテキストコンテンツ</p>
  </div>
</テンプレート>
<スクリプト>
  '@/components/DropDownList.vue' から DropList をインポートします。
  //その他のコードは省略</script>

このページでは、DropDownList コンポーネントを紹介し、使用します。:dataList="dplist" は、現在のページの dplist 配列をコンポーネントの dataList プロパティにバインドします。この配列内のオブジェクトには city フィールドがあります。このフィールドがドロップダウン メニューに表示されることを期待しているので、コンポーネントの labelProperty を city に設定します。また、このコンポーネントの変更イベントを登録します。このイベントは、以下に示すように、内部でディスパッチされる必要があります。

ここで、コンポーネントのテンプレート部分に戻り、それがまだ静的コンテンツであることを確認してみましょう。これらの静的コンテンツを変更して、属性を通じてレンダリングされるようにします。

<テンプレート>
    <div class="zq-drop-list" @mouseover="onDplOver($event)" @mouseout="onDplOut($event)">
        <span>{{dplLable} </i></span>
        <ul>
            <li v-for="(item, index) in dataList" :key="index" @click="onLiClick(index, $event)">{{item[labelProperty]}}</li>
        </ul>
    </div>
</テンプレート>

選択されたメニューliのテキストはitem[labelProperty]であり、開発者が指定したフィールドが正しく表示されます。

選択した項目のテキスト式 dplLabel を見てみましょう。この属性も内部データも定義していません。どこから来るのでしょうか?選択項目のテキストはdataList[activeIndex][labelProperty](これはわかりやすいので、ご不明な点があればメッセージを残してください)のはずですが、この式は長すぎてテンプレートに記述すると保守しにくいため、計算プロパティに記述します。

計算:{
        dplLabel(){
            this.dataList[this.activeIndex][this.labelProperty] を返します
        }
    }

上に dplLabel があります。計算されたプロパティは本当に便利です。

ドロップダウン メニューのビューとデータの関連付け部分を記述したので、その機能を実装する必要があります。

最初のステップは、選択メニューをデフォルトで非表示にすることです。ここでは CSS display:none を使用し、マウスがその上を通過したときに display:block を使用するのはいかがでしょうか。このため、メニュー項目をクリックしても非表示にすることができず、使い勝手が悪くなります。 js を使用して制御しますが、Vue は DOM 要素への直接アクセスをあまりサポートしていません。コンポーネントが初期化されるときに DOM 要素にアクセスしたい場合は、カスタム命令という最も便利な方法があります。

ドロップダウン メニュー コンポーネントにローカル カスタム命令を追加します。コードは次のとおりです。

ディレクティブ:{
        dpl:{
            バインド(el){
                el.style.display = "なし";
            }
        }
    },

この dpl はカスタム命令です。私の不器用な命名は無視してください。次に、カスタム命令のフック関数の bind メソッドで el 要素にアクセスし、そのスタイル属性 display:none; を制御します。最後に、このカスタム命令をテンプレートの ul タグに追加します。 v- を追加することを忘れないでください。効果を見てみましょう。選択メニューが非表示になっています。

<ul v-dpl>

カスタム命令フック関数を使用して DOM 要素にアクセスし、DOM を制御します。これは非常に実用的です。

最初に定義したマウスオーバーとマウスアウトの監視をドロップダウンメニューに実装し、選択されたメニューの表示と非表示を実現してみましょう。

onDplOver(イベント){
    ul = event.currentTarget.childNodes[1]とします。
    ul.style.display = "ブロック";
},
onDplOut(イベント){
    ul = event.currentTarget.childNodes[1]とします。
    ul.style.display = "なし";
},

マウス イベントでは、イベントの currentTarget オブジェクトにアクセスしますが、なぜそれがターゲットではないのでしょうか?ドロップダウン メニューの子要素もこのイベントをトリガーするため、ターゲットにアクセスすると、期待する最上位の要素ではない可能性があります。

最後のステップでは、選択されたメニュー項目のクリック イベントを実装します。クリックすると、選択されたメニューが非表示になり、内部状態が変更され、変更イベントがディスパッチされます。

onLiClick(インデックス){
    let path = event.path || (event.composedPath && event.composedPath()) //Firefox および Safari と互換性あり
    パス[1].style.display = "なし";
    this.activeIndex = インデックス;
    this.$emit("change", {
        インデックス:インデックス、
        値:this.dataList[インデックス]
    })
}

ここで注意すべき詳細があります。li 要素を通じて外側の ul 要素を見つける必要がありますが、path は Firefox と Safari をサポートしていません。幸い、これら 2 つのブラウザーは combinedPath をサポートしているため、コードの最初の行は互換性があります。次に、内部データ activeIndex を変更して選択した項目のテキストを更新し、最後に、emit メソッドを呼び出して、親要素に変更イベントをディスパッチします。イベント オブジェクトをカプセル化して渡すことを忘れないでください。

完全なコードは次のとおりです。

<テンプレート>
    <div class="zq-drop-list" @mouseover="onDplOver($event)" @mouseout="onDplOut($event)">
        <span>{{dplLable} </i></span>
        <ul v-dpl>
            <li v-for="(item, index) in dataList" :key="index" @click="onLiClick(index, $event)">{{item[labelProperty]}}</li>
        </ul>
    </div>
</テンプレート>
<スクリプト>
エクスポートデフォルト{
    名前: "DropDownList",
    データ(){
        戻る {
            アクティブインデックス:0
        }
    },
    小道具:{
        データリスト:{
            タイプ:配列、
            デフォルト(){
                戻る [
                    {名前: "オプション 1"},
                    {名前: "オプション 2"}
                ]
            }
        },
        ラベルプロパティ:{
            タイプ:文字列、
            default(){ "name" を返す }
        }
    },
    ディレクティブ:{
        dpl:{
            バインド(el){
                el.style.display = "なし";
            }
        }
    },
    方法:{
        onDplOver(イベント){
            ul = event.currentTarget.childNodes[1]とします。
            ul.style.display = "ブロック";
        },
        onDplOut(イベント){
            ul = event.currentTarget.childNodes[1]とします。
            ul.style.display = "なし";
        },
        onLiClick(インデックス){
            let path = event.path || (event.composedPath && event.composedPath()) //Firefox および Safari と互換性あり
            パス[1].style.display = "なし";
            this.activeIndex = インデックス;
            this.$emit("change", {
                インデックス:インデックス、
                値:this.dataList[インデックス]
            })
        }
    },
    計算:{
        dplLabel(){
            this.dataList[this.activeIndex][this.labelProperty] を返します
        }
    }
}
</スクリプト>
<スタイル スコープ lang="scss">
    .zq-ドロップリスト{
        表示: インラインブロック;
        最小幅: 100px;
        位置: 相対的;
        スパン{
            表示: ブロック;
            高さ: 30px;
            行の高さ: 30px;
            背景: #f1f1f1;
            フォントサイズ: 14px;
            テキスト配置: 中央;
            色: #333333;
            境界線の半径: 4px;
            私{
                背景: url(https://www.easyicon.net/api/resizeApi.php?id=1189852&size=16) 繰り返しなし 中央 中央;
                左マージン: 6px;
                表示: インラインブロック;
            }
        }
        ul{
            位置: 絶対;
            上: 30px;
            左: 0;
            幅: 100%;
            マージン: 0;
            パディング: 0;
            境界線: 実線 1px #f1f1f1;
            境界線の半径: 4px;
            オーバーフロー: 非表示;
            li{
                リストスタイル: なし;
                高さ: 30px;
                行の高さ: 30px;
                フォントサイズ: 14px;
                下部境界線: 実線 1px #f1f1f1;
                背景: #ffffff;
            }
            li:最後の子{
                下部境界線: なし;
            }
            li:ホバー{
                背景: #f6f6f6;
            }
        }
    }
</スタイル>

上記は、Vue でドロップダウン メニュー コンポーネントを実装する方法を示しています。比較的シンプルですが、基本的にはコンポーネント開発の一般的な機能がいくつか含まれています。これが皆様の参考になれば幸いです。また、123WORDPRESS.COM を応援していただければ幸いです。

以下もご興味があるかもしれません:
  • カーソルの表示と非表示に基づいてVueでドロップダウンリストを実装する
  • Vue フォーム v-model バインディング ドロップダウン リスト機能
  • Vue は歌手リストのアルファベット順ソート、ドロップダウンスクロールバー、サイドバーソートのリアルタイム更新を実装します
  • Vue は Baidu ドロップダウン リストのインタラクティブ操作例を実装します
  • Vue ドロップダウン リスト機能のサンプル コード

<<:  Tomcat が非同期サーブレットを実装する方法の詳細な説明

>>:  MySQL共通インデックスとユニークインデックスの詳細な説明

推薦する

JavaScript の基本: ループと配列

目次ループ - for forループの基本的な使い方ループを終了するネストされたループ配列配列とは何...

通知メッセージカルーセルを実装するための CSS3 トランジション

Vueバージョンをファイルにコピーして使用します <テンプレート> <!-- カル...

CSS で中空マスク レイヤーを実装するサンプル コード

この記事の内容: ページ中空マスクレイヤー、ページ中空マスクガイドレイヤー、画像中空マスク通常のマス...

大きな太陽の天気アイコンを純粋な CSS で記述する方法の例

効果効果図は以下のとおりです実装のアイデアDivは太陽の長方形の光と影を実現します前の疑似要素は、既...

HTML のテキストエリア タグ

<textarea></textarea> は、複数行を入力できるテキスト ...

挿入前にレコードが既に存在するかどうかを確認するには、SQL ステートメントを使用します。

目次SQL文を挿入する前にレコードが既に存在するかどうかを確認するSQL挿入時の判断の簡単なコレクシ...

HTML テーブル マークアップ チュートリアル (16): タイトルの水平方向の配置属性 ALIGN

デフォルトでは、表のタイトルは水平方向に中央揃えされます。ALIGN 属性を使用して、タイトル テキ...

Centos7でファイルをバックアップするときは、バックアップファイルにバックアップの日付を追加します

Linux は、システム内のデバイス、インターフェース、ファイル、スタートアップ、アプリケーション ...

MySQL数千万の大規模データに対する30のSQLクエリ最適化テクニックの詳細な説明

1. クエリを最適化するには、テーブル全体のスキャンを避けてください。まず、where と orde...

Dockerでローカルマシン(ホストマシン)にアクセスする方法

質問Docker でローカル データベースにアクセスするにはどうすればよいでしょうか? 127.0....

JS で配列の重複排除を実装する 7 つの方法

目次1. Set()+Array.from() を使用する2. 2層ループ+アレイ接合方式の使用3....

MySQL ツリー構造データベース テーブル設計

目次序文1. 基本データ2. 継承駆動設計3. 左右の値のエンコーディングに基づく設計4. ツリー構...

jsはテーブルの追加と削除の操作を動的に実装します

この記事の例では、jsでテーブルを動的に追加および削除するための具体的なコードを参考までに共有してい...

MySQL 最適化における B ツリー インデックスの知識ポイントのまとめ

SQL を最適化する必要があるのはなぜですか?当然ですが、SQL ステートメントを記述する場合、次の...

WebプロジェクトをIdeaにインポートし、Tomcatに公開する問題を解決します

Idea は既存の Web プロジェクトをインポートして Tomcat に公開しますが、Tomcat...