LoginSignup
1
3

More than 3 years have passed since last update.

Vue.Draggable の奇妙な動きを対症療法でなんとかする

Posted at

初投稿です。よろしくお願いします。

1.環境

Vue.js:2.6.11
Vue.Draggable:2.23.2
Google Chrome

2.問題

趣味でなんとなく Vue.js で Webアプリを作っています。

ドラッグ&ドロップで要素をぴょこぴょこ移動させる機能を作りたいな~と思ってたら、Vue.Draggable というなんとも便利なものが存在しているではありませんか。

さっそくインストールして実装。

なかなかいい感じになってきたな、と思ってたらふと妙な動きをしていることに気付きました。

まずは動画を見てください。

※Google Chrome の場合

test1.gif

下のエリアの要素を少し動かしただけなのに、左上のエリアがなにやら蠢いています。
よくみると、下のエリアの要素を動かしはじめた一瞬、その要素が左上のエリアにワープしています。

なんじゃぁこれは、と公式のサイトを見てみたのですが、公式のサイトのデモアプリでも同じような動きをします。
あ~じゃあダメだな、と思いつつ諦めきれず英語のサイトや中国語のサイトをあさりましたが解決せず…

3.対症療法

ぼ~っとしながら奇妙な動きをするドラッグ&ドロップの操作を繰り返してると、ふと対症療法が浮かんできました。

色々試して気が付いたのは、この現象はcloneイベントの直後に発生しているということです。
そこで、cloneイベントのイベントハンドラに以下の記述を追加しました。


<draggable tag="ul" v-model="left" :group=state @clone="onClone">
    <li v-for="l in left" :key="l.content">
        <div>{{ l.content }}</div>
    </li>
</draggable>
<!-- あと右上エリアの分と下エリアの分-->

data() {
    return {
        state: undefined,
        left: [
            {content: "task1"},
            {content: "task2"},
            {content: "task3"},
            {content: "task4"}
        ],
        //あと右上エリアの分と下エリアの分
    }
},
methods: {
    onClone: function () {
        this.state = null
        setTimeout(this.setGroup, 100)
    },
    setGroup: function () {
        this.state = "move"
    }
}

cloneイベントが発生したらgroup 属性を null にして group 間の移動ができないようにします。
0.1秒くらい待って、group 属性に値をセットしてgroup 間の移動を可能にします。

すると以下の動画のようになります。

test2.gif

奇妙な動きはなくなりました。

また、同一エリア内での要素の移動に関して、動かした要素の二行上の要素が一瞬動くという奇妙な動きをすることもあります。

それもこの対症療法で対応できる気がします。

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3