VueはSplitを使用して、ユニバーサルドラッグアンドスライドパーティションパネルコンポーネントをカプセル化します。

VueはSplitを使用して、ユニバーサルドラッグアンドスライドパーティションパネルコンポーネントをカプセル化します。

序文

Iview に似た Split コンポーネントを手動でカプセル化して、領域を 2 つの領域に分割し、ドラッグして幅や高さを調整できるようにします。最終的な効果は次のようになります。

始める

基本レイアウト

Vue プロジェクトで SplitPane コンポーネントを作成し、ページに導入して使用します。

<テンプレート>
 <div class="page">
 <分割ペイン />
 </div>
</テンプレート>

<スクリプト>
'./components/split-pane' から SplitPane をインポートします。
エクスポートデフォルト{ 
 コンポーネント: 
 分割ペイン 
 }, 
 データ() { 
 戻る {} 
 }
}
</スクリプト>

<スタイル スコープ lang="scss">
.ページ { 
 高さ: 100%; 
 パディング: 10px;
 背景: #000;
}
</スタイル>

// 分割ペイン.vue

<テンプレート>
 <div class="split-pane">
 スプリット
 </div>
</テンプレート>

<スクリプト>
エクスポートデフォルト{ 
 データ() { 
 戻る {} 
 }
}
</スクリプト>

<スタイル スコープ lang="scss">
.分割ペイン { 
 背景:淡い緑; 
 高さ: 100%;
}
</スタイル>

SplitPane コンポーネントは、Area 1、Area 2、Sliders の 3 つの部分で構成されます。これら 3 つの要素を追加し、それぞれクラス名を追加します。.pane はエリア 1 とエリア 2 で共有されることに注意してください。

<テンプレート>
<div class="split-pane">
 <div class="pane ペイン-one"></div> 
 <div class="pane-trigger"></div> 
 <div class="pane ペイン 2"></div> 
</div>
</テンプレート>

コンテナーをフレックス レイアウトに設定し、領域 2 の flex プロパティを 1 に設定します。すると、領域 2 は領域 1 の幅に応じて適応します。

<スタイル スコープ lang="scss">
.分割ペイン { 
 背景:淡い緑;
 高さ: 100%;
 ディスプレイ: フレックス; 
 .ペイン-1 { 
 幅: 50%; 
 背景:淡い紫赤; 
 } 
 .ペイントリガー{ 
 幅: 10px; 
 高さ: 100%; 
 背景:淡いゴールデンロッド; 
 } 
 .ペイン2 { 
 フレックス: 1; 
 背景:ターコイズ 
 }
}
</スタイル>

領域 1 の幅の変更を設定することが、このコンポーネントを実装する際の核心であることがわかります。

水平レイアウトに加えて、垂直レイアウトもサポートされているため、コンポーネントに direction 属性が追加されます。この属性は外部から渡され、その値は row または column であり、親要素の flex-direction 属性にバインドされます。

<テンプレート> 
 <div class="split-pane" :style="{ flexDirection: direction }"> 
 <div class="pane ペイン-one"></div> 
 <div class="pane-trigger"></div> 
 <div class="pane ペイン 2"></div> 
 </div>
</テンプレート>

<スクリプト>
エクスポートデフォルト{ 
 小道具: { 
 方向:  
  タイプ: 文字列、  
  デフォルト: '行' 
 } 
 }, 
 データ() { 
 戻る {} 
 }
}
</スクリプト>

水平レイアウトでは、エリア 1 は幅: 50% に設定され、スライダーは幅: 10px に設定されています。垂直レイアウトに変更すると、これら 2 つの幅が高さになります。したがって、スタイル内の 2 つの幅設定を削除し、lengthType 計算属性を追加して、インライン スタイル内の 2 つの要素の幅と高さを異なる方向に応じて設定します。

<テンプレート> 
 <div class="split-pane" :style="{ flexDirection: direction }"> 
 <div class="pane ペイン-one" :style="lengthType + ':50%'"></div>
 <div class="pane-trigger" :style="lengthType + ':10px'"></div>  
 <div class="pane ペイン 2"></div> 
</div>
</テンプレート>

計算: { 
 長さタイプ() {  
 this.direction === 'row' ? 'width' : 'height' を返します 
 } 
}

同時に、水平レイアウトでは、領域 1、領域 2、スライダーの高さはすべて 100% になり、垂直レイアウトではすべて幅: 100% に変更する必要があります。したがって、元の高さ設定を削除し、方向をコンテナーのクラスにバインドし、クラスに応じて両方のケースで 3 つの子要素の属性を 100% に設定します。

<テンプレート>
 <div class="split-pane" :class="direction" :style="{ flexDirection: direction }">
 <div class="pane ペイン-one" :style="lengthType + ':50%'"></div>
 <div class="pane-trigger" :style="lengthType + ':10px'"></div>
 <div class="pane ペイン 2"></div>
 </div>
</テンプレート>

<スクリプト>
エクスポートデフォルト{
 小道具: {
 方向:
  タイプ: 文字列、
  デフォルト: '行'
 }
 },
 データ() {
 戻る {}
 },
 計算: {
 長さタイプ() {
  this.direction === 'row' ? 'width' : 'height' を返します
 }
 }
}
</スクリプト>

<スタイル スコープ lang="scss">
.分割ペイン {
 背景:淡い緑;
 高さ: 100%;
 ディスプレイ: フレックス;
 &。行 {
 .ペイン{
  高さ: 100%;
 }
 .ペイントリガー{
  高さ: 100%;
 }
 }
 &。カラム {
 .ペイン{
  幅: 100%;
 }
 .ペイントリガー{
  幅: 100%;
 }
 }
 .ペイン-1 {
 背景:淡い紫赤;
 }
 .ペイントリガー{
 背景:淡いゴールデンロッド;
 }
 .ペイン2 {
 フレックス: 1;
 背景:ターコイズ
 }
}
</スタイル>

この時点で、ページ上のコンポーネントにdirection="column"を渡すと、縦方向に変更されていることがわかります。

<テンプレート>
 <div class="page">
 <SplitPane の方向="列" />
 </div>
</テンプレート>


データバインディング

現在のエリア1の幅(高さ)とスライダーの幅(高さ)はどちらもスタイルにハードコードされており、操作するにはjsでバインドする必要があります。まず、計算に使用できる数値をデータに入れます

データ() {
 戻る {
  panelLengthPercent: 50, // エリア 1 の幅 (%)
  triggerLength: 10 // スライダーの幅 (px)
 }
}

次に、計算によって 2 つのスタイルに必要な文字列が返されます。同時に、スライダーが領域 1 と領域 2 の中央に配置されることを確認するために、領域 1 の幅をスライダーの幅の半分に縮小する必要があります。

 計算: {
 長さタイプ() {
  this.direction === 'row' ? 'width' : 'height' を返します
 },

 パネルの長さの値() {
  `calc(${this.paneLengthPercent}% - ${this.triggerLength / 2 + 'px'})` を返します
 },

 トリガー長さ値() {
  this.triggerLength + 'px' を返す
 }
 }

最後にテンプレートにバインドします

<テンプレート>
 <div class="split-pane" :class="direction" :style="{ flexDirection: direction }">
 <div class="pane ペイン-one" :style="長さタイプ + ':' + ペインの長さ値"></div>
 <div class="pane-trigger" :style="長さタイプ + ':' + トリガー長さ値"></div>
 <div class="pane ペイン 2"></div>
 </div>
</テンプレート>

イベントバインディング

スライダーをドラッグするプロセスを想像してください。最初のステップは、スライダー上でマウスを押し、スライダーに mousedown イベントを追加することです。

<div class="pane-trigger" :style="lengthType + ':' + triggerLengthValue" @mousedown="handleMouseDown"></div>

マウスを押してスライドを開始した後、mousemove イベントをリッスンする必要がありますが、マウスはページ上の任意の位置にスライドする可能性があるため、スライダーではなくドキュメント全体をリッスンする必要があることに注意してください。ユーザーがマウスを離すと、ドキュメント全体のマウス移動リスナーがキャンセルされるので、マウスが押された瞬間に、マウス移動とマウス解放の2つのイベントがドキュメントに追加される必要があります。

 メソッド: {
  // スライダーを押す handleMouseDown(e) {
  document.addEventListener('mousemove', this.handleMouseMove)
  document.addEventListener('mouseup', this.handleMouseUp)
 },

 // スライダーを押した後にマウスを移動する handleMouseMove(e) {
  console.log('ドラッグ')
 },

 // スライダーを解放する handleMouseUp() {
  document.removeEventListener('mousemove', this.handleMouseMove)
 }
 }

実際に制御したいのはエリア 1 の幅で、エリア 1 の幅は現在のマウスとコンテナーの左側の間の距離と等しくなります。つまり、マウスが下の図の円の位置に移動すると、エリア 1 の幅は中央の長さと等しくなります。

この長さは、現在のマウスとページの左端の間の距離から、コンテナーとページの左端の間の距離を引いた値に基づいて計算できます。つまり、緑の長さは赤から青を引いた値に等しくなります。

コンテナのDOM情報を取得するには、コンテナにrefを追加します。

...
<div ref="splitPane" class="split-pane" :class="direction" :style="{ flexDirection: direction }">
...

ref の getBoundingClientRect() を印刷すると、次の情報が表示されます。

console.log(this.$refs.splitPane.getBoundingClientRect())

ここで、left はページの左側からのコンテナーの距離を表し、width はコンテナーの幅を表します。
マウス イベント オブジェクト イベントの pageX を通じて、ページの左側からのマウスの現在の距離を取得できるため、コンテナーの左側からのマウスの必要な距離を計算できます。
最後に、この距離をコンテナの幅で割り、100 を掛けてこの距離のパーセンテージ値を取得し、それを panelLengthPercent に割り当てます。

 // スライダーを押した後にマウスを移動する handleMouseMove(e) {
  const clientRect = this.$refs.splitPane.getBoundingClientRect()
  定数オフセット = e.pageX - clientRect.left
  定数paneLengthPercent = (オフセット / clientRect.width) * 100

  this.paneLengthPercent = ペインの長さパーセント
 },

縦向きレイアウトに対応しています。

 // スライダーを押した後にマウスを移動する handleMouseMove(e) {
  const clientRect = this.$refs.splitPane.getBoundingClientRect()
  パネルの長さパーセントを 0 にします

  if (this.direction === 'row') {
  定数オフセット = e.pageX - clientRect.left
  ペインの長さパーセント = (オフセット / クライアント矩形の幅) * 100
  } それ以外 {
  定数オフセット = e.pageY - clientRect.top
  ペインの長さパーセント = (オフセット / クライアント矩形の高さ) * 100
  }

  this.paneLengthPercent = ペインの長さパーセント
 },

最適化

この時点では要件は満たされているように見えますが、一般的なコンポーネントとしては、まだ最適化が必要な領域がいくつかあります。

ジッター問題を最適化する

スライダーの幅を大きい値に設定すると、次のようにジッターの問題が見つかります。

現在の計算ロジックでは、スライダーの幅を考慮せずに、マウスがスライダーの中央にあると常に想定されるため、スライダーのいずれかの側を押して少し動かすと、大きなシフトが発生します。

dotaのスライダーの左(上)側からの現在のマウスオフセットを定義します

 データ() {
 戻る {
  panelLengthPercent: 50, // エリア 1 の幅 (%)
  triggerLength: 100, // スライダーの幅 (px)
  triggerLeftOffset: 0 // スライダーの左(上)側からのマウスのオフセット}
 }

この値は、マウスからページの左側までの距離から、スライダーからページの左側までの距離を引いた値に等しくなります (e.srcElement.getBoundingClientRect() 経由)。スライダーが押されるたびに割り当てられ、水平/垂直レイアウトを区別します: 赤 - 青 = 緑

 // スライダーを押す handleMouseDown(e) {
  document.addEventListener('mousemove', this.handleMouseMove)
  document.addEventListener('mouseup', this.handleMouseUp)

  if (this.direction === 'row') {
  this.triggerLeftOffset = e.pageX - e.srcElement.getBoundingClientRect().left
  } それ以外 {
  this.triggerLeftOffset = e.pageY - e.srcElement.getBoundingClientRect().top
  }
 },

この triggerLeftOffset を使用すると、領域 1 の幅の設定は、マウスからコンテナーの左側までの距離から、マウスからスライダーの左側までの距離 (triggerLeftOffset) を引いた値に、スライダーの幅の半分を加えた値になります。
これは、マウスをスライダーの中央に戻すことと同じです。

 // スライダーを押した後にマウスを移動する handleMouseMove(e) {
  const clientRect = this.$refs.splitPane.getBoundingClientRect()
  パネルの長さパーセントを 0 にします

  if (this.direction === 'row') {
  定数オフセット = e.pageX - clientRect.left - this.triggerLeftOffset + this.triggerLength / 2
  ペインの長さパーセント = (オフセット / クライアント矩形の幅) * 100
  } それ以外 {
  定数オフセット = e.pageY - clientRect.top - this.triggerLeftOffset + this.triggerLength / 2
  ペインの長さパーセント = (オフセット / クライアント矩形の高さ) * 100
  }

  this.paneLengthPercent = ペインの長さパーセント
 },

ジッターの問題はもうありません

2番目のマウススタイルを最適化する

マウスがスライダー上を通過すると、ドラッグできることをユーザーに知らせるためにスタイルが変更されます。水平レイアウトと垂直レイアウトのスライダー CSS にそれぞれマウス スタイルの変更を追加します。

<スタイル スコープ lang="scss">
.分割ペイン {
 背景:淡い緑;
 高さ: 100%;
 ディスプレイ: フレックス;
 &。行 {
 .ペイン{
  高さ: 100%;
 }
 .ペイントリガー{
  高さ: 100%;
  cursor: col-resize; // ここ}
 }
 &。カラム {
 .ペイン{
  幅: 100%;
 }
 .ペイントリガー{
  幅: 100%;
  cursor: row-resize; // ここ}
 }
 .ペイン-1 {
 背景:淡い紫赤;
 }
 .ペイントリガー{
 背景:淡いゴールデンロッド;
 }
 .ペイン2 {
 フレックス: 1;
 背景:ターコイズ
 }
}
</スタイル>

3スライドの制限を最適化する

ユニバーサル コンポーネントとして、最小および最大のスライド距離制限を設定するための外部関数を提供し、min と max の 2 つのプロパティを受け取る必要があります。

 小道具: {
 方向:
  タイプ: 文字列、
  デフォルト: '行'
 },
 
 最小: {
  タイプ: 数値、
  デフォルト: 10
 },

 最大: {
  タイプ: 数値、
  デフォルト: 90
 }
 },

handleMouseMoveに判定を追加します:

 // スライダーを押した後にマウスを移動する handleMouseMove(e) {
  const clientRect = this.$refs.splitPane.getBoundingClientRect()
  パネルの長さパーセントを 0 にします

  if (this.direction === 'row') {
  定数オフセット = e.pageX - clientRect.left - this.triggerLeftOffset + this.triggerLength / 2
  ペインの長さパーセント = (オフセット / クライアント矩形の幅) * 100
  } それ以外 {
  定数オフセット = e.pageY - clientRect.top - this.triggerLeftOffset + this.triggerLength / 2
  ペインの長さパーセント = (オフセット / クライアント矩形の高さ) * 100
  }

  ペインの長さパーセントが this.min 未満の場合
  パネルの長さパーセント = this.min
  }
  ペインの長さパーセントが this.max の場合
  パネルの長さパーセント = this.max
  }

  this.paneLengthPercent = ペインの長さパーセント
 }

4つのパネルのデフォルトの幅とスライダーの幅を最適化します

一般的なコンポーネントとして、パネルの初期化比率とスライダーの幅も外部ユーザーが決定する必要があります。
データ内のpaneLengthPercentとtriggerLengthをpropsに転送し、外部から受信します。

 小道具: {
 方向:
  タイプ: 文字列、
  デフォルト: '行'
 },
 
 最小: {
  タイプ: 数値、
  デフォルト: 10
 },

 最大: {
  タイプ: 数値、
  デフォルト: 90
 },

 パネルの長さパーセント: {
  タイプ: 数値、
  デフォルト: 50
 },

 トリガーの長さ: {
  タイプ: 数値、
  デフォルト: 10
 }
 },
 データ() {
 戻る {
  triggerLeftOffset: 0 // スライダーの左(上)側からのマウスのオフセット}
 },

このページでは、paneLengthPercent を渡す必要があります。paneLengthPercent はデータで定義されたデータである必要があり、この値は動的に変更する必要があるため、.sync 修飾子でマークされている必要があることに注意してください。

// ページ.vue

<テンプレート>
 <div class="page">
 <SplitPane direction="row" :paneLengthPercent.sync="paneLengthPercent" />
 </div>
</テンプレート>

...
 データ() {
 戻る {
  パネルの長さパーセント: 30
 }
 }
...

次に、this.$emit を通じてイベントをトリガーして、コンポーネントの handleMouseMove の panelLengthPercent 値を変更します。

 // スライダーを押した後にマウスを移動する handleMouseMove(e) {
  const clientRect = this.$refs.splitPane.getBoundingClientRect()
  パネルの長さパーセントを 0 にします

  if (this.direction === 'row') {
  定数オフセット = e.pageX - clientRect.left - this.triggerLeftOffset + this.triggerLength / 2
  ペインの長さパーセント = (オフセット / クライアント矩形の幅) * 100
  } それ以外 {
  定数オフセット = e.pageY - clientRect.top - this.triggerLeftOffset + this.triggerLength / 2
  ペインの長さパーセント = (オフセット / クライアント矩形の高さ) * 100
  }

  ペインの長さパーセントが this.min 未満の場合
  パネルの長さパーセント = this.min
  }
  ペインの長さパーセントが this.max の場合
  パネルの長さパーセント = this.max
  }

  this.$emit('update:paneLengthPercent', panelLengthPercent) // ここ},

この時点で、コンポーネントの要素情報は外部のプロパティによって制御できます。

5つのスロットを最適化

コンテナコンポーネントなので、コンテンツを追加できないと意味がありません。2 つの領域にそれぞれ 2 つの名前付きスロットを追加します。

<テンプレート>
 <div ref="splitPane" class="split-pane" :class="direction" :style="{ flexDirection: direction }">
 <div class="pane ペイン-one" :style="長さタイプ + ':' + ペイン長さ値">
  <スロット名="1"></スロット>
 </div>
 
 <div 
  クラス="ペイントリガー"
  :style="長さタイプ + ':' + トリガー長さ値"
  @mousedown="ハンドルマウスダウン">
 </div>
 
 <div class="pane ペイン 2">
  <スロット名="2"></スロット>
 </div>
 </div>
</テンプレート>

6つの禁止選択を最適化する

ドラッグ処理中に、領域内にテキスト コンテンツがある場合、テキストが選択される可能性があり、スライダーに選択禁止効果が追加されます。

...
 .ペイントリガー{
 ユーザー選択: なし;
 背景:淡いゴールデンロッド;
 }
...

仕上げる

コンポーネントの完全なコード

背景色は記事の表示目的のみに保持され、実際の使用時には削除されます。

<テンプレート>
 <div ref="splitPane" class="split-pane" :class="direction" :style="{ flexDirection: direction }">
 <div class="pane ペイン-one" :style="長さタイプ + ':' + ペイン長さ値">
  <スロット名="1"></スロット>
 </div>
 
 <div 
  クラス="ペイントリガー" 
  :style="長さタイプ + ':' + トリガー長さ値" 
  @mousedown="ハンドルマウスダウン"
 </div>
 
 <div class="pane ペイン 2">
  <スロット名="2"></スロット>
 </div>
 </div>
</テンプレート>

<スクリプト>
エクスポートデフォルト{
 小道具: {
 方向:
  タイプ: 文字列、
  デフォルト: '行'
 },
 
 最小: {
  タイプ: 数値、
  デフォルト: 10
 },

 最大: {
  タイプ: 数値、
  デフォルト: 90
 },

 パネルの長さパーセント: {
  タイプ: 数値、
  デフォルト: 50
 },

 トリガーの長さ: {
  タイプ: 数値、
  デフォルト: 10
 }
 },
 データ() {
 戻る {
  triggerLeftOffset: 0 // スライダーの左(上)側からのマウスのオフセット}
 },
 計算: {
 長さタイプ() {
  this.direction === 'row' ? 'width' : 'height' を返します
 },

 パネルの長さの値() {
  `calc(${this.paneLengthPercent}% - ${this.triggerLength / 2 + 'px'})` を返します
 },

 トリガー長さ値() {
  this.triggerLength + 'px' を返す
 }
 },

 メソッド: {
 // スライダーを押す handleMouseDown(e) {
  document.addEventListener('mousemove', this.handleMouseMove)
  document.addEventListener('mouseup', this.handleMouseUp)

  if (this.direction === 'row') {
  this.triggerLeftOffset = e.pageX - e.srcElement.getBoundingClientRect().left
  } それ以外 {
  this.triggerLeftOffset = e.pageY - e.srcElement.getBoundingClientRect().top
  }
 },

 // スライダーを押した後にマウスを移動する handleMouseMove(e) {
  const clientRect = this.$refs.splitPane.getBoundingClientRect()
  パネルの長さパーセントを 0 にします

  if (this.direction === 'row') {
  定数オフセット = e.pageX - clientRect.left - this.triggerLeftOffset + this.triggerLength / 2
  ペインの長さパーセント = (オフセット / クライアント矩形の幅) * 100
  } それ以外 {
  定数オフセット = e.pageY - clientRect.top - this.triggerLeftOffset + this.triggerLength / 2
  ペインの長さパーセント = (オフセット / クライアント矩形の高さ) * 100
  }

  ペインの長さパーセントが this.min 未満の場合
  パネルの長さパーセント = this.min
  }
  ペインの長さパーセントが this.max の場合
  パネルの長さパーセント = this.max
  }

  this.$emit('update:paneLengthPercent', ペインの長さパーセント)
 },

 // スライダーを解放する handleMouseUp() {
  document.removeEventListener('mousemove', this.handleMouseMove)
 }
 }
}
</スクリプト>

<スタイル スコープ lang="scss">
.分割ペイン {
 背景:淡い緑;
 高さ: 100%;
 ディスプレイ: フレックス;
 &。行 {
 .ペイン{
  高さ: 100%;
 }
 .ペイントリガー{
  高さ: 100%;
  カーソル: col-resize;
 }
 }
 &。カラム {
 .ペイン{
  幅: 100%;
 }
 .ペイントリガー{
  幅: 100%;
  カーソル: 行のサイズ変更;
 }
 }
 .ペイン-1 {
 背景:淡い紫赤;
 }
 .ペイントリガー{
 ユーザー選択: なし;
 背景:淡いゴールデンロッド;
 }
 .ペイン2 {
 フレックス: 1;
 背景:ターコイズ
 }
}
</スタイル>

コンポーネントの使用例

背景色は記事の表示目的のみに保持され、実際の使用時には削除されます。

<テンプレート>
 <div class="page">
 <分割ペイン 
  方向="列" 
  :min="20" 
  :max="80" 
  :トリガーの長さ="20" 
  :paneLengthPercent.sync="ペインの長さパーセント" 
 >
  <テンプレート v-slot:one>
  <div>
   エリア1</div>
  </テンプレート>

  <テンプレート v-slot:two>
  <div>
   エリア2
  </テンプレート>

 </分割ペイン>
 </div>
</テンプレート>

<スクリプト>
'./components/split-pane' から SplitPane をインポートします。

エクスポートデフォルト{
 コンポーネント:
 分割ペイン
 },
 データ() {
 戻る {
  パネルの長さパーセント: 30
 }
 }
}
</スクリプト>

<スタイル スコープ lang="scss">
.ページ {
 高さ: 100%;
 パディング: 10px;
 背景: #000;
}
</スタイル>


これで、Vue が Split を使用してユニバーサルなドラッグ アンド スライド分割パネル コンポーネントをカプセル化する方法についての説明は終わりです。Vue のドラッグ アンド スライド分割パネルに関する関連コンテンツについては、123WORDPRESS.COM で以前の記事を検索するか、次の関連記事を引き続き参照してください。今後も 123WORDPRESS.COM を応援していただければ幸いです。

以下もご興味があるかもしれません:
  • Vueのドラッグ可能なコンポーネントであるVue Smooth DnDの使用方法の詳細な説明
  • vue ドラッグ コンポーネント vuedraggable API オプションは、ボックス間の相互ドラッグと並べ替えを実現します。
  • 動的なページ構成機能を実現するVueドラッグコンポーネントリスト
  • Vueドラッグコンポーネントの使い方の詳しい説明
  • Vueドラッグコンポーネント開発例の詳しい説明
  • Vueは動的に生成されたコンポーネントをドラッグアンドドロップする要件を実装します
  • Vue がドラッグ プログレス バーのスライド コンポーネントを開発
  • vue draggable resizable はドラッグ可能なスケーリングのコンポーネント機能を実現します
  • Vue ドラッグ可能なコンポーネントを使用して、Vue プロジェクトでテーブル コンテンツのドラッグ アンド ドロップによる並べ替えを実装します。
  • VueコンポーネントDraggableはドラッグ機能を実装します
  • Vueでドラッグ可能なコンポーネントを実装する方法

<<:  nginx で第 3 レベルドメイン名を設定する方法の例

>>:  MySQL 5.7 mysql コマンドラインクライアントの使用コマンドの詳細

推薦する

Dockerはホスト間のネットワーク通信を実現するためにMacvlanを導入する

基本的な概念: Macvlanの動作原理: Macvlan は、Linux カーネルでサポートされて...

yum の基本的な使い方と例(推奨)

yumコマンドYum (フルネームは Yellow dog Updater, Modified) ...

MySQL における between の境界と範囲の説明

境界範囲間のmysql間の範囲は両側の境界値を含む例: 3 から 7 までの id は、id >...

Vue の新しいパートナー TypeScript クイックスタート実践記録

目次1. 公式の足場を使って構築する2. プロジェクトディレクトリ分析3. TypeScript の...

Linux の PHP に XML 拡張機能をインストールする詳細な手順

PHP Linux に XML 拡張機能をインストールする1. PHPインストールソースパッケージを...

サーバーストレステストの概念と方法 (TPS/同時実行性)

目次1 ストレステストの指標1.1 秒あたり1.2 クォータ1.3 平均処理時間(RT) 1.4 同...

Nginx/Httpd リバース プロキシ Tomcat 設定チュートリアル

以前のブログでは、Tomcatのサーバーの各コンポーネントの使用について学びました。 Tomcatは...

OneProxy に基づいて MySQL の読み取り/書き込み分離と負荷分散を実装する

導入パート1: 冒頭に書いたOneProxy は、民間ソフトウェアによって完全に独立して開発された分...

html+cssレイアウトの3つの方法(ナチュラルレイアウト/フローレイアウト/ポジショニングレイアウト)

1. 自然なレイアウト<br />レイアウトは変更せずに自動的に左揃えになります。 2....

MySQLテクノロジーにおけるInnoDBロックの詳細な説明

目次序文1. ロックとは何ですか? 2. InnoDBストレージエンジンのロック2.1 ロックの種類...

MySQL スケジュール データベース バックアップ (フル データベース バックアップ) の実装

目次1. MySQLデータのバックアップ1.1. データをバックアップするためのmysqldumpコ...

JavaScript ES 新機能ブロックスコープ

目次1. ブロックスコープとは何ですか? 2. ブロックスコープが必要なのはなぜですか? 3. 関数...

Nginx_geo モジュールを使用して CDN スケジュールを設定する方法

NginxのGeoモジュールの紹介geo ディレクティブは、ngx_http_geo_module ...

JavaScript の setTimeout() の使用法の概要

目次1. はじめに2. setIntervalとsetTimeoutの違い3.タイムアウトを設定する...

MySQL での order by の使用に関する詳細

目次1. はじめに2. 本文2.1 単一列のソート2.2 複数の列を並べ替える2.3 ソート方法2....