追記:IE11とかEdgeとかのクソブラウザがスカポンタンでハゲゴミのパッパラパーだから書き直してる。

◆要件

  • カルーセル
  • 両端に前後のスライドちら見せ
  • 自動送り
  • 無限ループ
  • 親要素から要素数不明のオブジェクト列を受け取り、その内容からスライドを生成。
  • 親要素はaxiosでそのオブジェクト列を取得する。レンダリングとは非同期な通信である。
  • TypeScriptで、単一ファイルコンポーネントで、SCSS

◆結論

yarn add swiper
yarn add -D @types/swiper

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

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

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

◆Swiper

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

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

◆詰まり

動かない。が、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を書きなされ。この説明で分からないんならコメント欄で聞いてくれ。

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

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

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

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

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

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