Edited at

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

More than 1 year has passed since last update.


はじめに

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


参考にしたもの

下記ページに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);
}
}