Vue3 ドラッグ可能な左パネルと右パネルの分割コンポーネントの実装

Vue3 ドラッグ可能な左パネルと右パネルの分割コンポーネントの実装

最近、vue を使用しているときに、中央部分をドラッグして左右の div の幅を調整できることを実現したいという要件に遭遇しました。この記事ではそれを整理して共有します。詳細は次のとおりです。

レンダリング

コンポーネントの分解

フレックスレイアウトを全体的に使用する

左パネル

  • パネルの特定のコンテンツは、slot という名前のスロットを通じて渡されます。
  • タイトルはpropを通じて渡される
  • ドラッグ可能。ドラッグによってコンテンツ スタイルが破壊されないようにするには、パネルの幅の最大値と最小値を設定します。

右パネル

  • 右パネルの幅は左パネルの幅に応じて変わります。コンテンツの幅は flex-auto を使用して自動的に調整されることに注意してください。
  • モバイルデバイスに適応させる必要があります。
  • Tailwind メディアクエリの適応的な使用

入力パラメータの分解

小道具

  • @param {Number} maxWidth 最大幅
  • @param {Number} minWidth 最小幅
  • @param {String} leftTitle 左タイトル
  • @param {String} rightTitle 正しいタイトルですか?
  • @param {Boolean} storeReage localstoregeで保存するかどうか

スロット

  • left-content {要素} 左コンテンツ
  • right-content {要素} 右コンテンツ

具体的な実装

ドラッグする方法は?

左パネルと右パネルの間に隠しボックスを追加し、このボックスを box-shadow で非表示にします。特定のイベントはこのdivに実装されます

<div id="line" class="w-2 cursor-move hidden md4:block"onMousedown={hnadleMouseDown}>
</div>

イベントリスニング

    const hnadleMouseDown = (イベント: マウスイベント) => {
      /* 開始点を取得して保存します*/
      {pageX, pageY} = evtとします。
      ベース位置.pageX = pageX;
      ベース位置.pageY = pageY;
      /* マウス移動イベントをリッスンする*/
      document.addEventListener("mousemove"、handleMouseMove);
      document.addEventListener("mouseup"、handleMouseUp);
    };
    const ハンドルマウス移動 = evt => {
      /* ブラウザのデフォルトイベントがブラウザのジェスチャ機能をトリガーしないようにする*/
      evt.preventDefault();
      /* DOM が複数回リフローするのを防ぐためにタイマーを設定します */
      タイムアウトをクリアします(タイマー値);
      タイマー値 = setTimeout(() => {
        {pageX} = evtとします。
        const baseDiv = document.querySelector(".right-border-shadow");
        /* プロセス幅が最大値/最小値の範囲内かどうか*/
        baseWidth: 数値 | undefined = とします
          Number(baseDiv?.clientWidth) + (pageX - basePosition.pageX);
        ベース幅 =
          baseWidth > Number(props?.maxWidth) ? props.maxWidth : baseWidth;
        ベース幅 =
          数値(基本幅) < 数値(props?.最小幅)
            ? プロパティの最小幅
            : ベース幅;
        baseDiv?.setAttribute("style", `width:${baseWidth}px`);
        /* 幅変更イベントを発行 */
        ctx.emit("drugend");
        /* ストアからストアへ */
        ストアを設定します(ベース幅)。
      }, 50);
    };
    定数handleMouseUp = evt => {
      /* ドラッグが終了したら、イベントのリスニングをキャンセルし、最終的な幅を出力します*/
      定数幅 = document.querySelector(".right-border-shadow")?.clientWidth;
      document.removeEventListener("mousemove"、handleMouseMove);
      document.removeEventListener("mouseup"、handleMouseUp);
      ctx.emit("drugend", 幅);
    };

幅処理

スタイル={`幅:${
            store.get("split-width")
              ? store.get("split-width")
              : props.minWidth
              ? プロパティの最小幅
              : 384
          }px`}

最適化

ブラウザウィンドウの幅を手動で変更する

次のティック(() => {
        ctx.emit("load", ctx);
        MutationObserver = window.MutationObserver;
        if (ミューテーションオブザーバー) {
          /* ブラウザウィンドウの変更を監視します。この API は場合によっては必要です */
          mo = 新しい MutationObserver(関数() {
            const __wm = document.querySelector("#rezie-id");
            // __wm 要素が変更された場合にのみ __canvasWM を再呼び出しします
            もし (!__wm) {
              // mo.disconnect() が常にトリガーされないようにする。
              mo = null;
              ctx.emit("サイズ変更");
            }
          });
          mo.observe(document.querySelector("#rezie-id"), {
            属性: true、
            サブツリー: true、
            子リスト: true、
          });
        }
      });

効果がありません。アドバイスをお願いします

バグ

親コンポーネントの onMounted フックで子要素のスロット要素ノードを取得するときにエラーが発生しました。値は null です。現在の解決策は、子コンポーネントの onMounted フックでロード イベントをスローし、親コンポーネントが onLoad を使用して後続のロジックを処理することです。

git アドレス

倉庫住所プレビューアドレス

Vue3 ドラッグ可能な左右のパネル分割コンポーネントの実装に関するこの記事はこれで終わりです。Vue3 ドラッグ可能な左右のパネル分割コンポーネントに関するその他の関連コンテンツについては、123WORDPRESS.COM で以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • vue-Split はパネルのセグメンテーションを実現します
  • Vueはドラッグアンドスライド分割パネルを実装します
  • Vue 分割パネルのカプセル化実装記録

<<:  MySQL 自動インクリメント ID のオーバーサイズ問題のトラブルシューティングと解決策

>>:  Linux で pyenv をインストールする方法

ブログ    

推薦する

テーブルの最大幅と最小幅を設定する際の互換性の問題と解決策の詳細な説明

テーブル内の min-width と max-width プロパティの設定 <テーブル>...

Linuxでディスク使用量を確認する方法

1. dfコマンドを使用してディスク全体の使用量を表示します。 df コマンドは、ハードディスクのマ...

Nginx は高可用性クラスタ構築を実装します (Keepalived+Haproxy+Nginx)

1. コンポーネントと実装機能Keepalived: Haproxy サービスの高可用性を実現し、...

Windows 64 ビット版 MySQL 5.7 以降の解凍パッケージにデータディレクトリと my-default.ini がなく、サービスが起動できない問題の簡単な解決方法 (問題概要)

私は SQL の初心者で、オープンソースのインストールは非常に簡単だと思っていましたが、その過程でい...

Centos8 に nginx をインストールするための詳細なチュートリアル (画像とテキスト)

Nginx (「エンジン エックス」と発音) は、インターネット上の最大規模のサイトの負荷を処理す...

docker compose サービスの起動順序を制御する方法

まとめDocker-compose は複数の Docker コンテナ サービスを簡単に組み合わせるこ...

MySQL マスタースレーブレプリケーション切断の一般的な修復方法

目次01 問題の説明02 ソリューション1. 他のスレーブライブラリを見つけてすぐに置き換える2. ...

リンクされた画像をダウンロードしてアップロードするJavaScriptの実装

写真をアップロードするので、まずはダウンロード可能な画像リソースかどうかを判断する必要があります。正...

MySQL のデッドロック チェックとデッドロック除去の例の詳細な説明

1. クエリプロセスプロセスリストを表示2. 対応するプロセスを照会し、IDを強制終了します。検証(...

MySql のインデックス、ロック、トランザクションの知識ポイントのまとめ

この記事では、MySql のインデックス、ロック、トランザクションに関する知識のポイントをまとめてい...

Vueカスケードドロップダウンボックスの設計と実装

目次1. データベース設計2. フロントエンドページ3. 完全なデモフロントエンド開発では、カスケー...

MySQL での GROUP_CONCAT の使用例の分析

この記事では、例を使用して、MySQL で GROUP_CONCAT を使用する方法について説明しま...

mysql における mydumper と mysqldump の比較

いくつかのテーブルまたは単一のデータベースのみをバックアップする場合は、innobackup よりも...

JSキャンバスは描画ボードと署名ボードの機能を実現します

この記事では、お絵かきボード/サインボード機能を実現するためのJSキャンバスの具体的なコードを参考ま...

HTML リスト ボックス、テキスト フィールド、ファイル フィールドのサンプル コード

ドロップダウンボックス、テキストフィールド、ファイルフィールド 上半分はデモンストレーション効果、下...