27
19

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Vue.jsでjQueryの slideDown()とslideUp() 相当を行う方法

Posted at

Vue.jsでjQueryの slideDown()とslideUp() 相当を行う方法

概要

jQueryの slideDown() / slideUp() の表示方法が気に入っていて、
Vue.jsでも出来ないかとやってみた、メモ書き。備忘録。

結論から言うと、Vue.jsの標準機能の範囲で出来る
スクリーンショット 2019-03-20 12.26.49.png

具体的には、次のように構成することで、実装する。for文で変化量を計算して適用とか不要

  • v-if ディレクティブで対象エリアの表示/非表示を切り替える。
  • transition タグ+CSS3を用いて、表示/非表示の変化時を滑らかにする。

デモはこちら。⇒ Vue.jsでのアコーディオンメニュー例

なお、こういう「にょ~ん」と開いたり閉じたりするメニューを「アコーディオンメニュー」と呼ぶことがある、と今回に初めて知ったよ。「vue.js slideup() slidedown()」で検索してもイマイチ、これだ!ってのが見つからなくて、な。

なおなお、基本的にはCSSのtransition効果を用いた実現方法の様子。なので、CSSを理解している人なら悩まない実装なのかもしれない(当方、CSSは分からんので、ね)。

アコーディオンメニュー(slideDown/Up)の実装方法

次の順で、実装方法を説明する。
とりあえず動けばよい、って方は後半へ読み飛ばしOK。

  1. v-if ディレクティブで対象エリアの表示/非表示の実装する。
  2. transition タグを用いて、変化が瞬間ではなく連続的に起こるようCSSを適用する。

メニューの表示/非表示切り替え

これは、Vue.jsの v-if を用いてそのまま実装するだけ。

デモ ※これは瞬間的に表示/非表示が切り替わる版。未だ目的の前段階。

accordion_slide_menu0.html
<!DOCTYPE html>
<html>
  <head>
  	<title>アコーディオンメニュー/SlideUp(), SlideDown()</title>
  
    <meta charset="UTF-8" />
    <!-- Font Awesome を利用 -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous"></link>

    <!-- CDN の vue.js を利用 -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.min.js"></script>

    <!-- transitionにはCSS必須 -->
    <link rel="stylesheet" href="accordion_slide_menu.css"></link>
  </head>
<body>

    <div id="vue_slideupdown">
        <!-- vuejs-slidemenu -->
        <div class="cls_toggle_expand_collapse" v-on:click="toggleCtrlPanel">
            <i class="fa fa-caret-down"  v-if="isPanelShow"></i>
            <i class="fa fa-caret-right" v-if="!isPanelShow"></i>
            {{textToggle}}
        </div>
        <div class="menu_slide_accordion" v-if="isPanelShow">
            slideUp(), slideDown() したい内容を任意に書く。<br>
            純粋なhtmlでも良いし、<br>
            Vueの要素を書いても良い。<br>
        </div>
        <div>
            デモ。<br>
            <br>
            その他の要素。<br>
            この部分は、上部のメニューの開閉に伴ってアップダウンする。<br>
            ※こちらは「スライドアップ、スライドダウンの効果無し版」
        </div>
    </div>

    <!-- サンプルなので、簡便を目的にhtml内に記述 -->
    <script>
    var vueAccordion = new Vue({
        el:"#vue_slideupdown",
        data: {
            textToggle: "開閉するトグル(ここを押す)",
            isPanelShow: false
        },
        methods:{
            toggleCtrlPanel: function () {
                this.isPanelShow = !this.isPanelShow;
            }
        }
    })
    </script>
</body>
</html>

表示切替するエリアに適用するCSSは以下のようにしておく。なお、CSSで表示サイズを指定しておかないと、あとでSlideDown()/Up()相当を実装するときに上手く行かないので注意。※縦サイズのみが変化対象なので、縦サイズが指定されていれば良い。

accordion_slide_menu.css
/*
 * [accordion_slide_menu.css]
 */

.cls_toggle_expand_collapse {
    margin  : 4px;
    padding : 8px;
    cursor  : pointer;
    background-color: aquamarine
}

/*
 * Slide / accordionメニューの設定
 */ 
.menu_slide_accordion {
    background-color: antiquewhite;
    height: 120px;
    overflow: hidden;
}

表示時の変化を連続的にする

上記の表示/非表示を切り替えに緩やかな時間変化を付ける。

デモ

これを行うには、先ず表示/非表示を切り替えるエリアである <div class="menu_slide_accordion" v-if="isPanelShow"> の部分を、
transition タグで次のように囲む。

<transition name="trans_slide">
    <div class="menu_slide_accordion" v-if="isPanelShow">
        slideUp(), slideDown() したい内容を任意に書く。<br>
        純粋なhtmlでも良いし、<br>
        Vueの要素を書いても良い。<br>
    </div>
</transition>

すると、「囲んだ要素内のDOMが追加、更新、削除したときにトランジション効果を適用」することが容易にできる。具体的には次のように「transitionタグのname属性名+-xxxx」というクラス指定を用いて「変化の仕方」と「変化させるパラメータ」を指定する。

/* Vueの方で自動的に付与されるクラス::-enter-xx */
.trans_slide-enter-active, .trans_slide-leave-active {
    transition: opacity .5s;
}
.trans_slide-enter, .trans_slide-leave-to {
    opacity: 0;
}

上記のCSS表記例は、次ような「変化」を指定する内容。動作としては「挿入時に、1秒をかけて透明から不透明に変化する」+「削除人、1秒をかけて不透明から透明に変化する」というアニメーションになる。

  • DOMが挿入されようとしたら(xxx-enter)、「opacity = 0」に設定する。
  • DOM挿入後の状態に向かって、opacity属性を、5sの時間をかけて変化させる。
    • ここで「挿入後」とは「表示が完了した」状態なので、「opacity = 1」を意味する。
    • この「〇〇属性を、xxの時間をかけて変化させる」はCSS3の transition 機能そのもの。この例であれば「変化中(xxx-enter-active)は transition: opacity .5s に従う」という設定の仕方となる。
  • DOMが削除されたら(xxx-leave-to)、「opacity = 0」に設定する。
  • DOM削除後の状態に向かって、opacity属性を、5sの時間をかけて変化させる。
    • ここで「削除後」の状態として「opacity = 0」の状態を指定しているので、この変化の開始前の「opacity = 1」に対して「1→0」と変化させることを意味する。
    • 削除へ向かう変化中(xxx-leave-active)の変化の仕方は、同様にCSS3の transition 機能で指定する。

透明度を変化させる代わりに、次のようにheight属性値の変化を指定することで「にょ~ん、と上から下へ開く。しゅるる~、と下から上へ閉じる」というslideDown(), slideUp() 相当のアニメーション動作を実装できる

/* Vueの方で自動的に付与されるクラス::-enter-xx */
.trans_slide-enter-active, .trans_slide-leave-active {
    transition: all .5s;
}
.trans_slide-enter, .trans_slide-leave-to {
    height: 0;
}

slideDown(), slideUp() 相当の動作を設定したCSSファイルの全体像は、次のようになる。

ここで、変化対象とするdivクラスのwidth属性の初期値(挿入時=表示時の初期値)を明記することを忘れずに。さもないと変化の向かう先が見つからず、上手くアニメーションにならない。それから、「overflow: fidden;」を指定しておくことで「高さが小さくなったdiv要素からはみ出したテキストを表示しない」設定にすることを忘れずに。これを設定しないと、divの動作から置いて行かれてはみ出したテキストが残り、見た目がイマイチになる。

accordion_slide_menu.css
/*
 * [accordion_slide_menu.css]
 */

.cls_toggle_expand_collapse {
    margin  : 4px;
    padding : 8px;
    cursor  : pointer;
    background-color: aquamarine
}

/*
 * Slide / accordionメニューの設定
 */ 
.menu_slide_accordion {
    background-color: antiquewhite;
    height: 120px;
    overflow: hidden;
}
/* Vueの方で自動的に付与されるクラス::-enter-xx */
.trans_slide-enter-active, .trans_slide-leave-active {
    transition: all .5s;
}
.trans_slide-enter, .trans_slide-leave-to {
    height: 0;
}

transition タグを追加した、htmlコード全体は次のようになる。メニューを開閉するjavascriptコード側の変更は不要。これで、アコーディオンメニュー/SlideUp(), SlideDown()相当の動作実装は完了ー。

デモ ※本節の冒頭のリンク先と同一。

accordion_slide_menu.html
<!DOCTYPE html>
<html>
  <head>
  	<title>アコーディオンメニュー/SlideUp(), SlideDown()</title>
  
    <meta charset="UTF-8" />
    <!-- Font Awesome を利用 -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous"></link>

    <!-- CDN の vue.js を利用 -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.min.js"></script>

    <!-- transitionにはCSS必須 -->
    <link rel="stylesheet" href="accordion_slide_menu.css"></link>
  </head>
<body>

    <div id="vue_slideupdown">
        <!-- vuejs-slidemenu -->
        <div class="cls_toggle_expand_collapse" v-on:click="toggleCtrlPanel">
            <i class="fa fa-caret-down"  v-if="isPanelShow"></i>
            <i class="fa fa-caret-right" v-if="!isPanelShow"></i>
            {{textToggle}}
        </div>
        <transition name="trans_slide">
            <div class="menu_slide_accordion" v-if="isPanelShow">
                slideUp(), slideDown() したい内容を任意に書く。<br>
                純粋なhtmlでも良いし、<br>
                Vueの要素を書いても良い。<br>
            </div>
        </transition>
        <div>
            デモ。<br>
            <br>
            その他の要素。<br>
            この部分は、上部のメニューの開閉に伴ってアップダウンする。<br>
        </div>
    </div>

    <!-- サンプルなので、簡便を目的にhtml内に記述 -->
    <script>
    var vueAccordion = new Vue({
        el:"#vue_slideupdown",
        data: {
            textToggle: "開閉するトグル(ここを押す)",
            isPanelShow: false
        },
        methods:{
            toggleCtrlPanel: function () {
                this.isPanelShow = !this.isPanelShow;
            }
        }
    })
    </script>
</body>
</html>

以上ー。

蛇足

感想など。

CSS3のtransition属性を知っていれば、悩まない話だったポイ。CSSは全く分からんからなぁ、私は。この実装方法に辿り着くまで大分悩んだよ。。。

参考サイト

27
19
1

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
27
19

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?