◆ひとりごと

Swiperじゃなくてtiny-slider使った方が良いような気がする。

◆要件

◆結論(旧版)

yarn add swiper
yarn add -D @types/swiper

◆異常

EdgeのCSS 3Dレンダリングがバグってて、画像がぶっ壊れる(激怒)
SVGアニメーションとか停止するからね。ほんと意味不明。ビルゲイツぶっ殺す。

⇒関連issue:coverflow effect not working in MS Edge

あと、画面上に二つswiper出すと壊れる。

▼対応

  • coverflowのエフェクトやめよう。swiperもゴミっぽいから使うのやめたいけど、まぁとりあえずいいや。使う。
  • coverflowやめる代わりに、両側に透過したスライドをちら見せすることにする。
  • swiperを初期化するためのキーを外部から入れられるようにしよう。
  • loopカルーセルだと、paginationクリックしたときに妙な挙動するからクリック不可にしよう。

◆結論

◆カルーセルが作りたかった

Vue CarouselとかVue-Awesome-Swiperとか色々あって、それら使えば余裕っしょと思ったんだけど、うまく動かない。

「なんぞ」と思ってライブラリの中を見たんだけど、なんとなくスジが悪い。深く考えずに使おうにも、d.tsが提供されていないもんで帰宅しそうになる。

◆Swiper

Vue-Awesome-Swiperというライブラリは、内部的にはSwiperなるものを使っているらしかった。jQueryじゃないし、じゃあもうそれ使えば良いかと。

誰が作ったんだか知らんが型定義も提供されている。

◆axios

axios登場してないけど、親のコンポーネントでaxios使って配列を取得してslidesにバインディングしてくれればいいよ。

◆詰まり

動かない。が、HMRで更新が掛かったときに動く。なんじゃあこりゃあ!

ChromeのF12で要素を確認してみたところ、動いている時はDOM要素に「swiper-slide-active」クラスやら「swiper-slide-prev」「swiper-slide-next」やらがついているようであった。逆に、動いていないときはそれらがついていない。

ここからわかることは

  • v-forで要素は作られている
  • つまり、axiosでデータ取得はできている
  • けどswiperの処理が効いていない

ということだ。これはなぜか。

◆Swiperの初期化

Swiperの初期化タイミングがおかしいのだと思った。

その頃の俺はSwiperが魔法で動いていると思っていたゆえ、適切な初期化タイミングについての頭が無かった。が、Swiperの中を眺めた結果「これはどうやら魔法ではないぞ」という認識を獲得した。Vueのレンダリング、axiosでのデータ取得、Swiperの処理の調整をつけてやらねばなるまい、じゃあ特別な稽古つけてやるかと思った。

そして、◆結論を導出した。

◆解説

ページレンダリングされた後でSwiperを初期化しようね。

そして、swiperOptionsは親から渡してもいいし、逆にslidesは親からじゃなくてこのコンポーネント内で取りに行ってもいいだろう。

オプションを変えたい時は公式のデモを参考にしてくれ。

あと、使ってると思うけどvue-property-decorator使え。

◆質問コーナー

Q:使い方わからん
 東京都杉並区/ちんちん丸出し さん(26歳 会社員)

A:このままじゃ使えません。親からslidesプロパティに配列をバインドしてくれ。「.fuga」なんてプロパティはないだろうから、よしなに。つまり「div class=”swiper-slide”」の中に好きなようにHTMLを書きなされ。

あと、swiperInitKeyプロパティに親から文字列を設定してやらねばならん。設定した文字列は、swiperを初期化するときの目印になる。つまり同じ一つの画面でswiperInitKeyが重複してはいけない。
文字列を直接バインドしたい時は「:swiperInitKey=”hoge”」じゃなくて「:swiperInitKey=”‘hoge'”」だから注意ね。

この説明で分からないんならコメント欄で聞いてくれ。

Q:loopedSlides の 「slide数÷2 以上」ってなに
 東京都杉並区/不屈の凍死 さん(26歳 会社員)

A:そういうことです。slide数が決定されていないなら、vueのcomputed使ってswiperOptionsを算出するようにしよう。typescriptならcomputedはgetで記述できるよ。

Q:レスポンシブですか?(リアクティブですか?) 
 東京都杉並区/Vue忍者 さん(26歳 会社員)

A:試してねぇから知らねぇ。ちゃんと操作してやればなんとなく動く気がするが。駄目だったら「slides」をdeepにWatchして、Swiperをもっかい初期化しろ。

Q:SSRなんだろ?
 東京都杉並区/変態糞エンジニア さん(26歳 会社員)

A:僕は違います(半ギレ)
対応してないよたぶん。やり方も知らん。

Q:画像の遅延ロードしたい
 東京都杉並区/衝撃的くさみ さん(26歳 会社員)

A:わかる。例では出してないけど、実際そうしてる。Vueのコンポーネントをスライドとして表示してるわ。
つまり、「スライドのコンポーネントで画像のロードが完了したとき」にイベントをEmitしてやって、それをカルーセルコンポーネントでキャッチしたときにswiperを初期化してやればいい。ただ、swiperが何回も初期化されてしまうから、処理を間引くためにdebounceをかけてやろう。typescript-debounce-decoratorを使うと良いぞ。{ leading: false }を忘れずにな。

遅延ロードのやり方がどうなるかぜんぜんわからん!人は下の記事を参考にしてくれてもいい。

Vue.jsでimgの:srcにaxiosのresponse.dataをbindしてerrorをcatchした時は違う画像みせたかった人の逸話

Q:動きません。
 東京都杉並区/怒れる大仏 さん(26歳 女子高生)

A:えーほんとー?おっかしいなー。俺のとこだと動くんだけどなー。うーーーん。ごめんねー?