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

推薦する

忘れられたボタンタグ

注:この記事は他の人によって翻訳されていますが、考えるべき点が多く、理解しにくい点もあると感じていま...

CentOS 7 で RPM を使用して mysql5.7.13 をインストールする

0. 環境この記事のオペレーティング システム: CentOS 7.2.1511 x86_64 My...

VMware ワークステーション 12 に Ubuntu 14.04 (64 ビット) をインストール

1. インストール環境コンピュータモデル: Lenovo Y471a (i5) ノートパソコンシステ...

jsを使って簡単な計算機を作る

この記事では、jsで簡単な計算機を作成する具体的なコードを参考までに共有します。具体的な内容は次のと...

CentOSはexpectを使用してスクリプトやコマンドをバッチでリモート実行します

サーバーへのファイルのアップロード、ソフトウェアのインストール、コマンドやスクリプトの実行、サービス...

JSが絵柄デジタル時計を実現

この記事の例では、画像デジタル時計を実現するためのJSの具体的なコードを参考までに共有しています。具...

Centos7 に yum 経由で MySQL をインストールする方法

1. MySQLがインストールされているかどうかを確認する yum インストール済みリスト | gr...

JavaScript 改ざん防止オブジェクトの使用例

目次JavaScript 改ざん防止オブジェクト1. 拡張不可能なオブジェクト2. 封印された物体3...

Linux ディスクのマウント、パーティション分割、容量拡張操作を実装する方法

基本概念操作の前に、まずいくつかの基本的な概念を理解する必要がありますディスクLinux システムで...

SQLで同じフィールドの異なる値のデータ統計を実行する

適用シナリオ: シールのさまざまな状態に応じて、さまざまな状態のシールの数をカウントする必要がありま...

Nginx rtmp モジュールのコンパイル ARM バージョンの問題

目次1. 準備: 2. ソースコードのコンパイル1. 設定する2. コンパイルエラー3. ターゲット...

Linux を使用して時間指定ファイルが占有するディスク容量を計算する方法

スケジュールされたタスク エディターを開きます。Cent は、デフォルトで vim を使用して直接開...

Linux システムファイル共有 samba 設定チュートリアル

目次sambaをアンインストールしてインストールする新しい共有パスを作成し、権限を設定するSamba...

WeChatアプレットbindtapとcatchtapの違いの詳細な説明

目次1. イベントとは何ですか? 2. イベントの使い方3. バインドタップとキャッチタップの違い4...

MySQLとOracleのメタデータ抽出例分析

目次序文メタデータとは参照文書アドレスまずはMySQLについてお話しましょうOracleについて話し...