Rails 581圖片輪播做法
功能製作教學
前情提要:
前面已經有提到使用swiper輪播圖的用法,今天要用到更進階的教學,要像581那樣,點下按鈕跳出另外一個頁面,並且圖片可以在上面輪播
swiper安裝、使用
如果還不知道 swiper 怎麼使用的,請到前面一篇文章查看 swiper基礎教學
House show頁面
首先看到show這邊的view怎麼設定的,可以看到section裡面包著三個render部分,一個是圖片展示部分的上方區塊,一個是留言展示的下方區塊,還有一個留言表單區塊。
不過今天我們只要看圖片部分而已,所以另外部分就先不看。
view/houses/show
> <section class="mx-36">
> <div class="mb-6 bg-white rounded-lg shadow">
>
> <%# 渲染房子上方區塊 %>
> <%= render "card", house: @house %>
>
> <div class="w-full p-4 text-gray-600 focus-within:text-gray-400">
> <%# 下面這邊是渲染留言表單出來,順便會把兩個實體變數傳過去,一個是房子實體變數傳過去變區域變數,一個是把nil當作parent區域變數傳過去 <%>
> <%= render partial: 'comments/form', locals: { house: @house, parent: nil, url: comments_path(@house) } %>
> </div>
>
> <div class="w-full p-10 mb-8 border-gray-100 border-y">
> <%= render @comments %>
> </div>
> <br>
>
> </div>
> </section>
_card 頁面
下面這一區塊就是圖片展示區塊,可以看到 查看所有圖片按鈕
那一個區塊,我有掛上一個controller和action,所以等等點擊下去後,會跳出另外一個頁面
> <%# 圖片輪播區塊 %>
> <div class="relative px-2 mx-3 mt-6 text-sm font-medium text-gray-400 mb-7">
> <div class="flex gap-2">
> <%# 左邊圖片 %>
> <div class="w-1/2">
> <div class="w-full mr-1 text-xs text-blue-700 cursor-pointer font-base">
> <%= image_tag house.images.first.variant(:first), class: "object-cover w-full h-full rounded-l-xl align-center" %>
> </div>
> </div>
> <%# 右邊圖片 %>
> <div class="w-1/2 overflow-hidden rounded-r-xl">
> <div class="grid grid-cols-2 grid-rows-2 gap-2">
> <% house.images[1..4].each do |image| %>
> <div class="w-full row-span-1 mr-1 text-xs text-blue-700 cursor-pointer font-base">
> <%= link_to image_tag(image.variant(:standard)), image.url, data: { lightbox: 'image-gallery' }, class: "object-cover w-full h-full", target: "_blank"%>
> </div>
> <% end %>
> </div>
> </div>
> <%# 查看所有圖片按鈕 %>
> <div class="absolute right-0 px-6 py-3 text-base text-black bg-gray-100 rounded cursor-pointer bottom-3 hover:bg-gray-300"
> data-controller="show-all-images"
> data-action="click->show-all-images#lookPics"
> >
> <p>
> 查看所有圖片 - <%= house.images.size %> 張 ->
> </p>
> </div>
> </div>
> </div>
查看所有圖片的controller.JS
來看一下剛剛查看所有圖片的controller做了什麼事,我們在點下按鈕的時候,使用兩個controller互相溝通的方法,把 popup_carousel
這個action給傳出去了
// show_all_images_controller.js
import { Controller } from "@hotwired/stimulus"
import { dispatchAction } from "./lib/dispatch"
export default class extends Controller {
static targets = []
connect() {}
lookPics() {
const evt = new CustomEvent("popup_carousel")
window.dispatchEvent(evt)
}
}
設定輪播頁面
現在我們來把輪播圖要放的區塊放出來,我們把該區塊放在house的show頁面,這邊有幾點要特別注意
(1) 因為這區塊一開始是隱藏的,所以用hidden藏起來
(2) 在這區塊設定一個新的controller,並接住剛剛傳出來的action
(3) 為了方便整理,用渲染的方式,把輪播圖程式碼放到另外一個頁面
view/houses/show
> <section class="mx-36">
> ...省略
> </section>
>
>
> <%# 點下去會出現所有圖片的輪播圖 %>
> <div class="absolute hidden" data-controller="carousel-pop-up"
> data-carousel-pop-up-target="page"
> data-action="popup_carousel@window->carousel-pop-up#showPop"
> >
> <%= render "carousel", house: @house %>
> </div>
_carousel 頁面
這個頁面就是輪播圖確定頁面了,這邊也幾個特別要提的
(1) 有新增一個叉叉的icon,上面有掛action,點下去的時候,要把hidden的css加回這個區塊 (2) 輪播圖區塊的垂直置中,要在swiper-wrapper的地方,加上items-center
_carousel.html.erb
> <div class="fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-95">
> <div class="relative w-full p-20 rounded-lg">
> <div class="">
> <i class= "absolute text-white cursor-pointer right-[200px] top-[50px] text-4xl fa-solid fa-x" data-action="click->carousel-pop-up#close"></i>
> </div>
>
> <div class="flex items-center justify-center">
> <div class="w-1/3">
> <div class="swiper-container" data-controller="carousel"
> data-carousel-options-value='{
> "pagination": { "el": ".swiper-pagination",
> "dynamicBullets": "true" },
> "navigation": { "nextEl": ".swiper-button-next",
> "prevEl": ".swiper-button-prev"},
> "effect": "fade",
> "fadeEffect": { "crossFade": "true" },
> "centeredSlidesBounds": false
> }'
> >
> // 這邊很重要,如果今天想要讓圖片垂直置中,要在這邊加上items-center
> <div class="flex items-center swiper-wrapper">
> <% house.images.each do |image| %>
> <div class="swiper-slide">
> <%= link_to image_tag(image), image.url, data: { lightbox: 'image-gallery' }, class: "object-contain w-full h-full", target: "_blank" %>
> </div>
> <% end %>
> </div>
> <!-- Add Pagination -->
> <div class="swiper-pagination"></div>
> <!-- Add Navigation -->
> <div class="mr-5 swiper-button-next">
> <div class="w-[60px] h-[60px] bg-white absolute opacity-90 rounded-full"></div>
> </div>
> <div class="ml-5 swiper-button-prev">
> <div class="w-[60px] h-[60px] bg-white absolute opacity-90 rounded-full"></div>
> </div>
> </div>
> </div>
> </div>
>
> </div>
> <div>
輪播圖區塊掛上的controller
可以這下面看到兩個action,一個是把輪播圖頁面的hidden刪掉,一個是把輪播圖頁面的hidden加回來
// carousel_pop_up_controller.js
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
static targets = [ 'page' ]
connect() {}
showPop() {
this.pageTarget.classList.remove("hidden")
}
close() {
this.pageTarget.classList.add("hidden")
}
}