vue.jsのv-animationとv-effectを使ってみる


vue.jsでv-animationだけで機能が実現できない場合に、javascriptでカスタマイズしたエフェクトを付けられるv-effectを試しに使ってみたメモ。

ドキュメントにある通り、以下のようにHTMLとCSSを定義するとCSS animationが適用されます。

HTML

<p class="animated" v-if="show" v-animation>Look at me!</p>

CSS

.animated {
    display: inline-block;
}
.animated.v-enter {
    animation: fadein .5s;
}
.animated.v-leave {
    animation: fadeout .5s;
}

注意点は、v-animationはノードがvueのmodelの変化に対するbinding(v-showなど)によりノードがDOMに追加・削除されたりする場合のみ効果が適用されるという点です。自前でdisplay:noneをセットしたり、nodeをremoveしても、v-enterやv-leaveは適用されないです。以下で紹介するv-effectも同じで、対象のノードがbindingによって、DOMに追加・削除された際にscriptのenterとleaveがそれぞれ実行されます。

HTML

<p v-effect="my-effect"></p>

JS

Vue.effect('my-effect', {
    enter: function (el, insert, timeout) {
        // insert() will actually insert the element
    },
    leave: function (el, remove, timeout) {
        // remove() will actually remove the element
    }
});

こりゃ簡単そうだと思い、enterにslideIn、leaveにslideOutさせるような効果をjavascriptで記述して見ると、あれDOMからノードが削除されないでずっと残ってる??

なんでだろうと思い、vue.jsのtransitionのmoduleの中のapplyTransitionFunctionsというコードを見てみると、

    if (stage > 0) { // enter
        if (typeof enter !== 'function') {
            changeState()
            return codes.JS_SKIP_E
        }
        enter(el, changeState, timeout)
        return codes.JS_E
    } else { // leave
        if (typeof leave !== 'function') {
            changeState()
            return codes.JS_SKIP_L
        }
        leave(el, changeState, timeout)
        return codes.JS_L
    }

enterが定義されていない時は単にchangeState()を呼んでいます。それによって、DOMの追加・削除を行っているようで、しかもそのchangeStateはenter/leaveの引数に渡っていました。つまり、自分で定義しているeffectの中のenter/leaveの中でこのchangeStateを呼んであげれば良いことが判明。

で、v-effectのサンプルコードを見返してみると、ちゃんとコメントに

”// insert() will actually insert the element”


”// remove() will actually remove the element”

と記述されていますねw

なので、自前の処理を行って必要であれば、insert()とremove()を適宜呼んであげればvueを使って、nodeの表示時および非表示時へのカスタマイズした効果の実装が可能になりました!

ところで、vue.jsのソースコードちらっとgithubで眺めていてわかったのが、このライブラリはほとんどgoogleのEvan Youという方が一人で実装しているんだなぁと気づいて感心しました。一人でこういうフレームワークを実装し切るパワーを付けなくは。