◆ひとりごと
Swiperじゃなくてtiny-slider使った方が良いような気がする。
◆要件
- カルーセル
- 両端に前後のスライドちら見せ
- 自動送り
- 無限ループ
- 親要素から要素数不明のオブジェクト列を受け取り、その内容からスライドを生成。
- 親要素はaxiosでそのオブジェクト列を取得する。レンダリングとは非同期な通信である。
- TypeScriptで、単一ファイルコンポーネントで、SCSS。
- vue-property-decorator使ってるよ!便利だよ!君も使いなよ!
◆結論(旧版)
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:えーほんとー?おっかしいなー。俺のとこだと動くんだけどなー。うーーーん。ごめんねー?
コメントを残す