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共通インデックスとユニークインデックスの詳細な説明

推薦する

Docker実践: Pythonアプリケーションのコンテナ化

1. はじめにコンテナはサンドボックス メカニズムを使用して相互に分離します。コンテナ内にデプロイさ...

Nginx シグナル制御

Nginx の紹介Nginx は、高性能な HTTP およびリバース プロキシ サーバーであり、IM...

よく使われる HTML タグとその特徴の完全なリスト

まず、HTML タグのいくつかの特性を知っておく必要があります。 1. 「<keyword&g...

ネイティブJSでマウススライドによる愛の拡散効果を実現

この記事では、マウスをスライドすると愛が広がる js 特殊効果を紹介します。効果は次のとおりです。 ...

jsvc を使用して tomcat を起動する方法 (通常のユーザーとして実行)

jsvc の紹介実稼働環境では、Tomcat はデーモン モードで実行する必要があります。Tomc...

Vue で AES.js を使用する詳細な手順

AES暗号化の使用データ転送の暗号化と復号化処理 --- AES.js最初のステップ: vue に ...

JS配列の一般的な方法とテクニックを学び、マスターになりましょう

目次splice() メソッドjoin() メソッド逆() メソッドevery() メソッド削減()...

Nginx リバース プロキシを使用してクロスドメイン問題を解決する方法の詳細な説明

質問前回のクロスドメイン リソース共有に関する記事では、ドメイン間で Cookie を送信する場合、...

WeChatミニプログラムでEchartとサブパッケージを使用するための完全な手順

序文休日は終わっていますが、それは別の形で(お腹に触れることで)私たちに現れます。ミニプログラムでデ...

MySQL 5.7 MGR シングルマスター決定マスターノード方式の詳細説明

当銀行のMGRは年末に開始されます。公式文書を読んだり、毎日テストを受けたりしなければなりません。毎...

MySQLのロック構造の詳細な説明

Mysqlは3種類のロック構造をサポートしていますテーブルレベルのロック、低オーバーヘッド、高速ロッ...

MySql5.7.21 インストールポイント記録メモ

ダウンロードしたバージョンは、Zip 解凍版、Windows システムです。長い間 Windows ...

HTMLで下線を設定するには?HTMLでテキストに下線を付ける方法

HTML で下線を引くには、以前はテキストを <u></u> タグで囲む必要...

Windows で Mysql を起動したときに 1067 が表示される場合の解決策

数日前に仕事を始めて、Mysql をインストールしたところ、開くことができました。今日、会社に行った...

CSS フロートプロパティ図 フロートプロパティの詳細

CSS の float プロパティを正しく使用することは、カバーすべき内容が多く、ブラウザの互換性の...