blog

Vue@ドラッグアンドドロップコンポーネント

概要\n\n\n分析\n「1.テクニカルポイント\nスロット固定ポジショニング コンポーネントラッピング&マウスムーブイベント\n\n「2.実装のアイデア\nまず、ドラッグビューコンポーネントをカプセ...

Nov 3, 2020 · 3 min. read
シェア

概要

分析

"1.テクニカルポイント"

  • スロット
  • 固定ポジショニング
  • コンポーネントのパッケージング
  • touchemove & mousemove

"2.実現のためのアイデア"

  • まず、ドラッグビューコンポーネントをカプセル化し、コンポーネント自体はドラッグアンドドロップのロジックのみを処理し、コンポーネントのコンテンツは親コンポーネントからスロットを通して渡されます。
  • ドラッグビューを固定配置に設定し、移動イベントでドラッグビューに割り当てるleftとtopを計算するだけです。

"3.加工計算"

topとleftの値の計算は比較的簡単で、タッチポイントのxとy座標からコンテナの幅と高さの半分を引いた値を取得すればよいので、以下の式が導かれます:

top = clientY - elHeight / 2;
left = clientX - elWidth / 2;

コードの実装

"1.構成部品"

<template>
 <div
 class="drag__wrapper"
 ref="dragRef"
 :style="{top:pos.y+'px', left:pos.x+'px'}"
 @mousemove="onTouchMove"
 @touchmove.stop="onTouchMove"
 >
 <slot />
 </div>
</template>
<script>
export default {
 props: {
 position: {
 type: Object,
 default: () => ({
 x: 300,
 y: 500,
 }),
 },
 },
 data() {
 return {
 flags: false,
 pos: {
 x: 0,
 y: 0,
 },
 };
 },
 mounted() {
 // デフォルト値を設定する
 this.pos = { ...this.$props.position };
 // コンテナ要素の寸法情報を取得する
 const rect = this.$refs.dragRef.getBoundingClientRect();
 // 後の計算のためにコンテナ要素のサイズの半分を取得する
 this.wrapperHalfWidth = rect.width / 2;
 this.wrapperHalfHeight = rect.height / 2;
 // スクリーンサイズの情報を取得する
 const clientWidth =
 document.body.clientWidth || document.documentElement.clientWidth;
 const clientHeight =
 document.body.clientHeight || document.documentElement.clientHeight;
 // 画面内のドラッグ可能な要素の境界値を取得する。
 this.maxX = clientWidth - rect.width;
 this.maxY = clientHeight - rect.height;
 },
 methods: {
 onTouchMove(event) {
 // PCや携帯電話と互換性のある連絡先を取得する
 let touch;
 if (event.touches) {
 touch = event.touches[0];
 } else {
 touch = event;
 }
 // スライダーを配置する
 this.pos.x = touch.clientX - this.wrapperHalfWidth;
 this.pos.y = touch.clientY - this.wrapperHalfHeight;
 // 境界を処理する
 if (this.pos.x < 0) {
 this.pos.x = 0;
 } else if (this.pos.x > this.maxX) {
 this.pos.x = this.maxX;
 }
 if (this.pos.y < 0) {
 this.pos.y = 0;
 } else if (this.pos.y > this.maxY) {
 this.pos.y = this.maxY;
 }
 // ブロックページスライドのデフォルトイベント
 event.preventDefault();
 },
 },
};
</script>
<style>
.drag__wrapper {
 position: fixed;
}
</style>

2.コール

<template>
 <div class="page test bg-light">
 <p class="tips">{{tips}}</p>
 <drag-view :position="{x: 300, y : 500}">
 <div class="box" @click="onTap"> </div>
 </drag-view>
 </div>
</template>
<script>
import DragView from "../../components/DragView/DragView.vue";
export default {
 data() {
 return {
 tips: "",
 };
 },
 methods: {
 onTap() {
 this.tips = "カスタマーサービスボタンをクリックする ";
 },
 },
 components: {
 DragView,
 },
};
</script>
<style scoped="scoped" lang="less">
.tips {
 text-align: center;
 margin: 50px 0;
 color: cornflowerblue;
 font-size: 22px;
}
.box {
 width: 50px;
 height: 50px;
 background: cornflowerblue;
 border-radius: 50%;
 text-align: center;
 line-height: 50px;
 color: #ffffff;
 font-size: 16px;
}
</style>

ヒント

  1. ドラッグボタンの初期位置は、ドラッグビューコンポーネントが呼び出されたときに、positionプロパティによって設定されます。
  2. ドラッグ&ドロップボタンのクリックイベントは、親コンポーネントで直接定義されます。

結論

さて、パートナー、今日の共有はここにある、私の記事の友人のように注目の波を指すことができ、ありがとうございます。あなたの注意は、私の継続的な努力の力です。

Read next