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 をインストールする方法

推薦する

クリックして展開し、全文を読む機能を実現する純粋なCSS

注記記事表示リストインターフェースを開発する場合、情報の基本的な概要を提供するために記事ヘッダーコン...

DockerはPruneコマンドを使用してnoneイメージをクリーンアップします

目次無イメージの創造と混乱Noneオブジェクトをクリーンアップする方法トリムミラーコンテナで使用され...

ボタントリガーイベントを使用して背景色の点滅効果を実現します

背景色の点滅効果を実現するには、次のコードを <body> 領域に追加するだけです。コー...

アルバムと写真をアルバムに保存するためのWeChatアプレット

私は現在、Xiao Nian Gao に似たビデオおよびツール アプリを開発しています。ユーザーが作...

JSベースの手持ち連射機能+テキスト揺れ特殊効果コードの簡単実装

少し前にTikTokで揺れる連打が流行っていたので真似してみることにしました。さっそく効果をみてみま...

MySQLデータベースのnullに関する知識ポイントのまとめ

MySQL データベースでは、null は一般的な状況です。MySQL での null に関する注意...

Pure CSS3はdivの出入りを順番に実現します

この記事は主に、純粋な CSS3 を使用して div が順番に出入りする効果を紹介します。一定の参考...

入力テキスト ボックスと画像検証コードの位置合わせの問題 (画像は常に入力より 1 つ上になります)

Web ページ制作では、input と img が同じ行に配置されることが多く、img タグが常に ...

MySQL学習データベース検索文DQL小百章

目次1. データの簡単な取得2. データの並べ替えと取得2.1. 基本構文2.2. ソート方向を指定...

CSS が最初のサイクルで画像を読み込むために @keyframes を使用するときに発生するホワイトギャップの問題 (フラッシュ画面) をすばやく解決します。

問題の説明: CSS アニメーション プロパティを使用すると、ループが最初に読み込まれたときに白いギ...

eCharts でパーセンテージ付きの横棒グラフを実装する方法

目次サンプルコードレンダリングコード分​​析要約するサンプルコード var データ = [220, ...

ウェブサイトのデザイン体験のための7つの異なるカラースキーム

ウェブサイト構築におけるカラーマッチングは非常に特殊であり、ウェブサイトのテーマ、感情、雰囲気などの...

JavaScript を使用して動的に生成されるテーブルの詳細な説明

*ページを作成する: 2つの入力ボックスとボタン*コードと手順/* 1. 入力行と列の値を取得する2...

Centos6.9 インストール Mysql5.7.18 ステップ記録

インストール手順 rpm -ivh mysql-コミュニティ-共通-5.7.18-1.el7.x86...

Reactソースコードにおけるビット演算について詳しく説明します

目次序文いくつかの一般的なビット操作ビットAND (&)ビットOR (|)ビット否定(~)マ...