LoginSignup
1
3

More than 5 years have passed since last update.

Vue.jsでiOSみたいなトグルスイッチをつくる

Last updated at Posted at 2018-05-31

はじめに

vue.jsを使ったトグルスイッチを作成します.いわゆるかっこいいチェックボックスですね.

image.png

参考にしたもの

下記ページにJavaScriptを一切使わず,CSSとHTMLのみでトグルスイッチを実現した実装方法が紹介されています.今回はこちらを参考にしつつ,Vue.jsで実装しました.
- 「How TO - Toggle Switch w3schools.com」https://www.w3schools.com/howto/howto_css_switch.asp

リポジトリ

実装した内容は下記リポジトリにアップロード済みです.ご参考にしていただければ幸いです.

実装

テンプレート

HTMLは先程のw3schools.comとほぼ変わりません.checkboxのinputタグは実際には不要ですが,SEO対策として有利に働くかなぁと思って残しておきます.
@click="onToggled"でイベントを追加しています.

toggle-switch.vue.html
<div class="toggle-switch">
<div class="toggle-switch__switch" @click="onToggled">
    <input type="checkbox" class="toggle-switch__switch__checkbox">
    <div 
     class="toggle-switch__switch__slider" 
     :class="{'toggle-switch__switch__slider--enabled': isEnabled, 'toggle-switch__switch__slider--disabled': !isEnabled}">
    </div>
</div>
<label class="toggle-switch__label"><slot></slot></label>
</div>

スクリプト(TypeScript)

HTMLテンプレートに対する動作を実装します.onToggledイベントでisEnabledのtrue/falseを切り替えます.またtoggledイベントを発火させています.

ToggleSwitch.vue
import Vue from 'vue';
import { Component, Prop } from 'vue-property-decorator';
@Component({})
export default class extends Vue {
    @Prop()
    protected enabled: boolean;

    protected isEnabled = this.enabled ? this.enabled : false;

    protected onToggled() {
        this.isEnabled = !this.isEnabled;
        this.$emit("toggled", this.isEnabled);
    }
}

スタイル

CSS部分はほぼそのままです.--enabled--disabledでON・OFF時のデザインをそれぞれ記述しています.

なおscssで実装しました.

.toggle-switch {
    &__switch {
        $switch_width: 60px;
        position: relative;
        display: inline-block;
        width: $switch_width;
        height: 34px;

        &__checkbox {
            display: none;
        }

        &--vtouch {
            width: 100%;
            height: 100%;
        }

        &__slider {
            $slider_margin: 4px;
            $slider_size: 26px;
            position: absolute;
            cursor: pointer;
            top: 0;
            left: 0;
            bottom: 0;
            right: 0;
            border-radius: 34px;

            &:before {
                content: "";
                position: absolute;
                height: $slider_size;
                width: $slider_size;
                transition: .4s;
                border-radius: 50%;
                background-color: white;
            }

            &--disabled {
                background-color: #ccc;
                &:before {
                    left: $slider_margin;
                    bottom: $slider_margin;
                }
            }

            &--enabled {
                background-color: #2196F3;
                &:before {
                    left: ($switch_width - ($slider_size + $slider_margin));
                    bottom: $slider_margin;
                }
            }
        }
    }
}

呼び出し

コンポーネントを呼び出します.

<toggle-switch>メールで通知する</toggle-switch>
<toggle-switch :enabled="true">電話で通知する</toggle-switch>

スマートフォン対応

基本的にこれだけでも動作しますが,スマートフォン向けに一部改修します.
スマートフォンでもタップすれば動作します.しかしながら,スイッチの部分を横にスワイプした場合,反応しません.反応するようにします.

ライブラリ導入

vue-touch@nextというライブラリを導入します.vue2.x系は2018年5月22日現在nextブランチであるため注意してください.

$ npm install --save-dev "vue-touch@next"

コードの改修

v-touchで左右のスワイプイベントを追加します.

HTMLにはv-touchタグを追加し,左右のスワイプイベントを追加しています.

toggle-switch.vue.html
<v-touch class="toggle-switch__switch--vtouch" @swipeleft="turnOff" @swiperight="turnOn" :swipe-options="{direction: 'horizontal'}">
    <input type="checkbox" class="toggle-switch__switch__checkbox">
    <div 
     class="toggle-switch__switch__slider" 
     :class="{'toggle-switch__switch__slider--enabled': isEnabled, 'toggle-switch__switch__slider--disabled': !isEnabled}">
    </div>
</v-touch>

TypeScript側には左右のスワイプイベントに対応するメソッドを追加します.

ToggleSwitch.vue
import VueTouch from "vue-touch";
Vue.use(VueTouch);

export default class extends Vue {
    protected turnOff() {
        this.isEnabled = false;
        this.$emit("toggled", this.isEnabled);
    }

    protected turnOn() {
        this.isEnabled = true;
        this.$emit("toggled", this.isEnabled);
    }
}
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