Vue3.0はドロップダウンメニューのカプセル化を実装します

Vue3.0はドロップダウンメニューのカプセル化を実装します

Vue3.0 がリリースされてからしばらく経ちましたが、勉強を始める必要があります。

まず、達成したい効果を見てみましょう

メニュー項目のコンテンツを展開することは非常に一般的です。vue3.0でそれを開発するにはどうすればよいでしょうか?ここでは、bootstrapのデフォルトスタイルを使用します。

アイデア1:

<DropDown :title="'終了'" :list="メニューリスト" />

アイデア2:

<ドロップダウン:title="'終了'">
   <drop-dowm-item>新しい記事を作成する</drop-down-item>
   <drop-dowm-item>記事の編集</drop-down-item>
   <drop-dowm-item>個人情報</drop-down-item>
</ドロップダウン>

どちらのアイデアも問題ありません。比較すると、2 番目のアイデアの方が明確です。これを使用すると、具体的なレベルがわかり、それが elementUI コンポーネントの開発モードでもあります。
では、2番目のコンポーネント開発のアイデアを分析してみましょう

ドロップダウン.ts

<テンプレート>
  <div class="dropdown" ref="dropDownRef">
    <a
      @click.prevent="開く"
      class="btn btn-secondary ドロップダウントグル"
      href="#" rel="外部nofollow" 
    >
      {{ タイトル }}
    </a>
    <div class="dropdown-menu" :style="{ display: 'block' }" v-show="isOpen">
      <スロット></スロット>
    </div>
  </div>
</テンプレート>

js部分

<script lang="ts">
「vue」から、defineComponent、ref、onMounted、onUnmounted、watch } をインポートします。
「../hooks/useClickOutside」からuseClickOutsideをインポートします。
エクスポートデフォルトdefineComponent({
  名前:「ドロップダウン」、
  小道具: {
    タイトル:
      タイプ: 文字列、
      必須: true、
    },
  },

  セットアップ(コンテキスト) {
    定数isOpen = ref(false);
    //vue3.0 は DOM オブジェクトの参照を取得します。const dropDownRef = ref<null | HTMLElement>(null);
    const トグルオープン = () => {
      isOpen.value = !isOpen.value;
    };
    const handleClick = (e: マウスイベント) => {
      console.log(e.target, "e");
      if (dropDownRef.value) {
        console.log(dropDownRef.値);
        もし (
        //contains はノードにノードが含まれているかどうかを判定します!dropDownRef.value.contains(e.target as HTMLElement) &&
          isOpen.値
        ){
          isOpen.値 = false;
        }
      }
    };
    マウント時(() => {
    //グローバル クリック イベントを登録します document.addEventListener("click", handleClick);
    });
    マウント解除時(() => {
    //バインド解除 document.removeEventListener("click", handleClick);
    }); 
    戻る {
      開いている、
      トグル開く、
      ドロップダウン参照、
    };
  },
});
</スクリプト>

ドロップダウンアイテム.ts

<テンプレート>
  <li class="dropdowm-option" :class="{ 'is-disabled': 無効 }">
    <スロット></スロット>
  </li>
</テンプレート>
<スタイルスコープ>

/* ここがスロットを貫通させる必要がある場所です*/
.dropdowm-option.is-disabled >>> * {
  色: #6c757d;
  ポインタイベント: なし;
  背景色: 透明;
}
</スタイル>
<script lang="ts">
「vue」からdefineComponentをインポートします。

エクスポートデフォルトdefineComponent({
  小道具: {
    無効:
      タイプ: ブール値、
      デフォルト: false、
    },
  },
  設定() {
    戻る {};
  },
});
</スクリプト>

この時点でコンポーネントは完成します。しかし...ドキュメント全体を非表示にするためにクリックするイベントはコンポーネント全体とはあまり関係がないので、フックに抽出することができます。

クリックアウトサイド.ts

'vue' から { ref, onMounted, onUnmounted,Ref } をインポートします。
const useClickOutside = (elementRef:Ref<null | HTMLElement>) => {
    定数isClickOutside = ref(false)
    const ハンドラ = (e: MouseEvent) => {
        console.log(要素参照値);
        if (要素参照値) {
            if (elementRef.value.contains(e.target as HTMLElement)) {
                isClickOutside.value = false
            } それ以外 {
                isClickOutside.value = true
            }
        }
    }
    マウント時(() => {
      document.addEventListener("クリック", ハンドラー);
    });
    マウント解除時(() => {
      document.removeEventListener("click", ハンドラー);
    });
    isClickOutsideを返す
}

エクスポートデフォルトuseClickOutside

次にDropDown.tsコンポーネントを書き直します

//既存のイベントロジックを削除します<script lang="ts">
... 
 定数isClickOutside = useClickOutside(dropDownRef);
    /* console.log(isClickOutside.value, "isClickOutside"); */
    //監視方法を導入し、データが変更されると、isOpen の値を false に変更します
    ウォッチ(isClickOutside, (newValue) => {
      if (isOpen.value && isClickOutside.value) {
        isOpen.値 = false;
      }
    });
 ...
</スクリプト>

同じ効果が得られ、コンポーネント全体のコードも大幅に簡素化されます。

以上がこの記事の全内容です。皆様の勉強のお役に立てれば幸いです。また、123WORDPRESS.COM を応援していただければ幸いです。

以下もご興味があるかもしれません:
  • vue3 キャッシュページキープアライブと統合ルーティング処理の詳細な説明
  • Vue3.0とBootstrapを組み合わせてマルチページアプリケーションを作成する
  • Vue3+TypeScriptは再帰メニューコンポーネントの完全な例を実装します
  • Vue2.x と Vue3.x のルーティングフックの違いの詳細な説明
  • Vue3ルーティングVueRouter4を使用する簡単な例
  • Vue2/vue3 ルーティング権限管理方法の例
  • Vue3 ページ、メニュー、ルートの使用

<<:  例を通してMySQLの更新がテーブルをロックするかどうかを判定する

>>:  Idea は、Web プロジェクトを開始するように Tomcat を設定します。グラフィック チュートリアル

推薦する

border-radiusは要素に丸い境界線を追加する方法です

border-radius:10px; /* すべての角は半径 10px で丸められます*/ bor...

10分で始めるCSS3アニメーション

導入アニメーションを使用すると、JavaScript や jQuery に依存せずに、純粋な CSS...

JavaScriptプロトタイプチェーン図のまとめと実践

目次プロトタイプチェーンプロトタイプチェーンに基づいてシンプルなJQueryライブラリを実装すること...

Linux環境でのDockerインストールチュートリアル

1. 設置環境Dockerは次のCentOSバージョンをサポートしていますCentOS 6.5 (6...

Vueは左上と右上のスライドナビゲーションを実装します

ナビゲーションなどは日々の開発でよく使うので、記録として記事を書きます。ナビゲーションは終了/開始位...

ffmpeg 中国語パラメータの説明と使用例

1. ffmpeg がビデオ ファイルをプッシュする場合、オーディオとビデオのエンコード形式は H2...

mysql8.0.19 winx64バージョンのインストール問題を解決する

MySQL は、スウェーデンの会社 MySQL AB によって開発されたオープンソースの小規模なリレ...

デザイン協会: なぜ間違った場所を探したのですか?

数日前、バスで仕事に行きました。バスのカードリーダーの実際の使用シーンを実際に見て、カードリーダーの...

重複したMySQLテーブルをマージして削除する簡単な方法

シナリオ:クロールされたデータは、別のメインテーブルと同じ構造を持つデータテーブルを生成するため、マ...

有名ウェブサイトのロゴにおすすめのフォント40選

世界で最も有名なウェブサイトのロゴデザインにはどんなフォントが使われているかご存知ですか?これらのフ...

MySQL複合クエリの詳細な説明

UNIONの使用ほとんどの SQL クエリは、1 つ以上のテーブルからデータを返す単一の SELEC...

Linux sar コマンドの使用方法とコード例の分析

1. CPU使用率sar -p (一日中表示) sar -u 1 10 (1: 1秒ごと、10: 1...

MySQLデータの重複チェックと重複排除の実装ステートメント

テーブル user があり、フィールドは id、nick_name、password、email、p...

Dockerでコンテナを作成するときにコンテナIPを指定する実装例

Docker はコンテナを作成するときに、デフォルトでブリッジ ネットワークを使用し、IP アドレス...

MySQL の分離レベルの包括的な分析

データベースが同じデータ バッチを同時に追加、削除、および変更すると、ダーティ書き込み、ダーティ読み...