はじめに
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"
でイベントを追加しています.
<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イベントを発火させています.
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タグを追加し,左右のスワイプイベントを追加しています.
<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側には左右のスワイプイベントに対応するメソッドを追加します.
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);
}
}