2019

7

29

jQueryからVue.jsへ移行事始めしてやんよ!!!その2

タグ:

Pocket
LINEで送る
Facebook にシェア
reddit にシェア
LinkedIn にシェア

前回、jQuery使いの人がVue.jsを覚えたい&移行を考えてる方向けへの 基本的なディレクティブとオプションをまとめました。

jQueryからVue.jsへ移行事始めしてやんよ!!!

Vueには他にも便利なコンポーネントオプションがたくさんあるのでご紹介

①アニメーション効果(transition)

Vueインスタンスの中にtransitionタグ内の子要素に効果を設定する事でがきます。

HTML
<div id="transition-1">
    <button @click="show = !show">切り替え</button>
    <transition>
        <div v-if="show">フェードアウト</div>
    </transition>
</div>
CSS
/* アニメーション中のスタイル */
.v-leave-active,
.v-enter-active {
    transition: opacity 1s;
}
/* 表示アクティブ */
.v-enter {
    opacity: 0;
}
/* 表示終了後 */
.v-enter-to {
    opacity: 1;
}

/* 非表示アクティブ */
.v-leave {
    opacity: 1;
}
/* 非表示終了後 */
.v-leave-to {
    opacity: 0;
}
JavaScript
<script>
    new Vue({
        el: '#transition-1',
        data: { show: true }
    })
</script>

6つのトランジションクラス

効果は別途CSSで指定ができ、トランジションのために適用される6つのクラスが用意されています

トランジションクラス詳細
v-enter要素が挿入される前に適用される初期状態
v-enter-activeトランジションに入るフェーズ中に適用
v-enter-toenter の終了状態。
トランジション/アニメーションが終了すると削除
v-leaveトランジションに入るフェーズ中に適用
v-leave-activeトランジションが終わるフェーズ中に適用
v-leave-toleave の終了状態。
トランジション/アニメーションが終了すると削除

個別に複数のtransitionを設定したい場合

別々のtransition効果を持つインスタンスを複数置きたい場合はtransitionタグ内にname属性"◯◯" を設定する事で
CSSにそのname-enter◯◯-leaveの記述でこれまでの静的classのようにCSSでのアニメーションも付与できます

HTML
<div id="example-1">
    <button @click="show = !show">切り替え</button>
    <transition name="fade">
        <div v-if="show">フェードアウト</div>
    </transition>
</div>

<div id="example-2">
    <button @click="show = !show">切り替え</button>
    <transition name="bounce" appear>
         <div v-if="show">飛び出ます</div>
    </transition>
</div>
CSS
.fade-enter-active,
.fade-leave-active {
    transition: opacity .5s;
}

.fade-enter,
.fade-leave-to{
    opacity: 0;
}

.bounce-enter-active,
.bounce-leave-active {
    transition: opacity 1s;
}
.bounce-enter,
.bounce-leave-to {
    opacity: 0;
}
.bounce-enter-active {
    animation: bounce-in 1s;
}
.bounce-enter-active-to {
    color: white;
}
.bounce-enter-active-to {
    background-color: red;
}

.bounce-leave-active {
    animation: bounce-in 1s reverse;
}
@keyframes bounce-in {
    0% { transform: scale(0); }
    50% { transform: scale(1.5); }
    100% { transform: scale(1); }
}
JavaScript
    new Vue({
        el: '#example-1',
        data: { show: true }
    })

    new Vue({
        el: '#example-2',
        data: { show: true }
    })

transitionタグにappear属性を追加しておく事で初期描画のタイミング◯◯-enter-activeが作動します。


②カスタムディレクティブ(directives)

Vueで用意された基本的なディレクティブにはv-ifv-onv-bindなどがありますが
それ以外にオリジナルな役割を持つディレクティブを作成することもできます。

ここではVueインスタンスのmsgプロパティの英字文字列を大文字に変換するv-upperというカスタムディレクティブを作成

HTML
  <div id="app">
    <p v-upper="msg"><!-- 「I LOVE YOU」で出力 --></p>
  </div>
JavaScript
// `v-upper` というカスタムディレクティブをローカルに登録する場合
new Vue({
    el: '#app',
    data() {
       return {
           msg: 'i love you'
       }
    },
    directives: {
        upper(el, bindObj) {
           el.textContent = bindObj.value.toUpperCase();
        }
    }
})

// `v-upper` というカスタムディレクティブをグローバルに登録する場合
Vue.directive('upper',function(el, bindObj){
    console.log(bindObj)
    el.textContent = bindObj.value.toUpperCase();
})

new Vue({
    el: '#app',
    data() {
        return {
            msg: 'i love you'
        }
    },
})

グローバルディレクティブとしてVue.directiveを個別に作成している場合は、適用されるVueインスタンスが限定されないので v-upperを指定しているVueインスタンスには全て適応されます。

③フィルター(filters)

filtersオプションはVueインスタンスで展開したマスタッシュ内の値に対してフィルター処理をかけることができます

moment.jsを利用してマスタッシュ内に展開したDateメソッドから取得した現時刻を、
"現在の日付"、"現在の時刻"、"来月の日付"のそれぞれのフォーマット処理を加えて出力します。

HTML
    <div id="root">
        <p>現在の日付「{{ timeNow | timeFormat }}」</p>
        <p>現在の時刻「{{ timeNow | timeFormat('hh:mm:ss') }}」</p>
        <p>{{ timeNow | nextMonth | filterA }}</p>
    </div>

 <script src="https://cdn.bootcdn.net/ajax/libs/moment.js/2.27.0/moment.js"></script>
JavaScript
    // 現時刻のフォーマットをグローバルフィルタで処理
    Vue.filter('timeFormat', function (value,format='YYYY-MM-DD hh:mm:ss') {
        return moment(value).format(format)
    })

    new Vue({
        el: '#root',
        data() {
            return {
                timeNow : Date.now()
            }
        },
        // #rootにのみ適用させるローカルフィルタ処理
        filters:{
            // 翌月(month + 1)で日本式にフォーマット
            nextMonth(value){
                return moment().add(1, 'month').format('YYYY年MM月DD日');
            },
            // フィルタを連結
            filterA(value){
                return "1ヶ月後は" +value;
            }
        }
    })

④プラグイン(use)&オプション追加(mixins)

jQueryと同じ様に自作のスクリプトをVue用のプラグインとして組み込むことができます。

自作プラグインファイル
(function(w){
    let MyPlugin = {}

    MyPlugin.install = function (Vue, options) {
        // 1. グローバルメソッドまたは属性を追加する
        Vue.myGlobalMethod = function () {
            return {
                data() {
                    return {
                        title: '自作プラグインデモ',
                        timeNow : Date.now()
                    };
                },
                created: function() {
                    console.log('プラグインが読み込まれました');
                }
            };
        }

        // インスタンスmsgのグローバルdirectiveディレクティブ
        Vue.directive('my-upper', {
            bind (el, binding, vnode, oldVnode) {
                el.innerText = binding.value.toUpperCase()
            }
        })

        // Dateフォーマットのグローバルfilterディレクティブ
        Vue.filter('my-timeFormat', function (value,format='YYYY年MM月DD日 hh:mm:ss') {
            return moment(value).format(format)
        })

        // 4. インスタンスメソッド操作
        Vue.prototype.$myMethod = function () {
            // インスタンスの描画完了後にh1のcolorを変更
            const title = document.getElementsByTagName('h1')[0];
            title.style.color = 'red'
        }
    }
    w.MyPlugin = MyPlugin
})(window);
HTML
    <div id="app">
        <h1>{{ title }}</h1>
        <p v-my-upper="msg"></p>
        <p>本日の日付「{{ timeNow | my-timeFormat('YYYY年MM月DD日') }}」</p>
        <p>現在の時刻「{{ timeNow | my-timeFormat('hh:mm:ss')}}」</p>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/moment.js/2.27.0/moment.js">
    <script src="MyPlugin.js"></script>
JavaScript
    // 1. 自作プラグインを読み込み
    Vue.use(MyPlugin)
    // 2. グローバルメソッドを取得
    const myMixin = Vue.myGlobalMethod()

    // 3. 操作対象のインスタンス
    let vm = new Vue({
        el:'#app',
        data(){
            return {
                msg : 'abcde',
            }
        },
        // グローバルメソッドの設定を追加
        mixins: [myMixin],
    })

    // 4. インスタンスメソッド操作
    vm.$myMethod()

jQueryと同様に外部スクリプトで「MyPlugin.js」をロードしたうえで、Vue.use(MyPlugin)でプラグインのVueコンストラクタを取得します。
今回はプラグインと一緒にmixinsオプションも使ってプラグインのグローバルメソッド設定をページのVueインスタンスに追加しています。

プラグインの動作について

myGlobalMethodでVueインスタンスのdataに ①h1タイトル(title)と②現時刻(timeNow)オプションを埋め込みます
デモではVueインスタンスは1つですが、このグローバルメソッドはすべてのVueインスタンスに適用されてしまうので注意

filterとdirectiveのコードと同様の処理をVueインスタンスから出力したタグに適用させています

Vueインスタンスが描画され、通常のJavaScriptの操作が可能になったタイミングでh1タグの文字色を赤に変更しています。


まとめ

Vue.jsには他に便利なオプションやディレクティブがたくさんあるので、また紹介します!
Pocket
LINEで送る
Facebook にシェア
reddit にシェア
LinkedIn にシェア

トップへ