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 を設定します。グラフィック チュートリアル

推薦する

Docker クロスサーバー通信オーバーレイソリューション (パート 1) Consul 単一インスタンス

目次シナリオタスクアイデア分析するコンセプトと選択ちょっとしたテスト環境説明予防実践テスト引用シナリ...

MySQL 8.0ドライバとAlibaba Druidバージョン間の互換性の問題を解決

この記事では主に、MySQL 8.0 ドライバーと Alibaba Druid バージョン間の互換性...

MySQL の中国語ソートの詳細と例

MySQL の漢字ソートの詳細な説明デフォルトでは、MySQL は日付、時刻、および英語の文字列の並...

ニューススタイルのウェブサイトデザイン例25選

bmi ボイジャーピッチフォークアルスター食料品店チャウ真/斜めポスタこれは偽のDIYですクリエイテ...

Mariadb リモート ログイン構成と問題解決

序文:インストール プロセスについては詳しく説明しません。問題に直接触れましょう。MySQL のリモ...

vue3でDOMをマウントするためのプラグインを書く際の問題について

vue2と比較して、vue3にはアプリの概念が追加され、vue3プロジェクトの作成も // メイン....

Dockerコマンドの自動補完の実装

序文この友人がどれくらいDockerを使っていなかったのかは分かりませんが、突然Dockerコマンド...

nginx rewriteを使用してURLをリダイレクトする方法

最近仕事でnginxの設定を変更する必要が頻繁にあり、nginxでrewriteを使用する方法を学び...

VueRouterルーティングの詳細な説明

目次vueルーター1. ルーティングの概念を理解する1.1 ルーティングとは何ですか? 1.2. バ...

Deepin で virtualenv をインストールして使用するチュートリアル

virtualenv は、分離された Python 仮想環境を作成するためのツールです。独立したディ...

LinuxはMySQLデータベースの自動バックアップとスケジュールバックアップを毎日実装しています

概要バックアップは災害復旧の基礎であり、システム操作エラーやシステム障害によるデータ損失を防ぐために...

スキニングを実現するネイティブJavaScript

ネイティブJavaScriptでスキニングを実装するための具体的なコードは参考までに。具体的な内容は...

Navicat Premium が MySQL 8.0 に接続してエラー「1251」を報告する問題を解決する方法の分析

長い間何もしていなかった人は、努力をすると一生懸命働いていると思うようになります。 1. 問題Nav...

Vue cli開発に基づく外部コンポーネントVantのデフォルトスタイルの変更の詳細な説明

目次序文1. 少ない2. コンポーネントをインポートする3. 設定ファイルを変更するステップ1: l...