1. 程式人生 > 其它 >vue3 專案使用 FancyApp 輪播圖元件封裝

vue3 專案使用 FancyApp 輪播圖元件封裝

  1. 下載 @fancyapps/ui

    npm install @fancyapps/ui -S
    
  2. 新建元件src/components/FancyApp.vue, 檔案程式碼如下:

    <template>
      <div class="fancy-app">
        <div :id="mainId" class="main-carousel carousel w-10/12 max-w-5xl mx-auto">
          <div
            class="carousel__slide"
            v-for="item in gallery"
            :key="item.id || item.uid"
            :data-src="item.src"
            :data-fancybox="dataFancyBox"
            :data-caption="item.caption"
          >
            <img :src="item.src" />
          </div>
        </div>
    
        <div :id="ThumbId" class="thumb-carousel carousel max-w-xl mx-auto">
          <div
            class="carousel__slide"
            v-for="item in gallery"
            :key="item.id || item.uid"
          >
            <img class="panzoom__content" :src="item.src" />
          </div>
        </div>
      </div>
    </template>
    
    <script>
    import { Fancybox, Carousel } from "@fancyapps/ui";
    import "@fancyapps/ui/dist/fancybox.css";
    
    export default {
      name: "fancy-app",
      props: {
        gallery: {
          type: Array,
          required: true,
        },
        dataFancyBox: {
          type: String,
          default: "gallery",
        },
      },
      setup() {
        let guid = () => {
          function S4() {
            return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
          }
          return (
            S4() +
            S4() +
            "-" +
            S4() +
            "-" +
            S4() +
            "-" +
            S4() +
            "-" +
            S4() +
            S4() +
            S4()
          );
        };
        return {
          mainId: "mainCarousel",
          guid,
        };
      },
    
      beforeMount() {
        let that = this;
        let guid = that.guid();
        let mainIdStr = "mainCarousel";
        let ThumbIdStr = "thumbCarousel";
        that.mainId = mainIdStr + guid;
        that.ThumbId = ThumbIdStr + guid;
      },
    
      mounted() {
        let that = this;
        // Initialise Carousel
        const mainCarousel = new Carousel(
          document.querySelector("#" + that.mainId),
          {
            Dots: false,
          }
        );
        // Thumbnails
        new Carousel(document.querySelector("#" + that.ThumbId), {
          Sync: {
            target: mainCarousel,
            friction: 0,
          },
          Dots: false,
          Navigation: false,
          center: true,
          slidesPerPage: 1,
          infinite: false,
        });
    
        // Customize Fancybox
        Fancybox.bind(`[data-fancybox=${that.dataFancyBox}]`, {
          Carousel: {
            on: {
              change: (that) => {
                mainCarousel.slideTo(mainCarousel.findPageForSlide(that.page), {
                  friction: 0,
                });
              },
            },
          },
        });
      },
    
      methods: {},
    };
    </script>
    
    <style>
    .main-carousel {
      width: 600px;
      margin: 0 auto 1rem auto;
    
      --carousel-button-color: #170724;
      --carousel-button-bg: #fff;
      --carousel-button-shadow: 0 2px 1px -1px rgb(0 0 0 / 20%),
        0 1px 1px 0 rgb(0 0 0 / 14%), 0 1px 3px 0 rgb(0 0 0 / 12%);
    
      --carousel-button-svg-width: 20px;
      --carousel-button-svg-height: 20px;
      --carousel-button-svg-stroke-width: 2.5;
    }
    
    .main-carousel .carousel__slide {
      width: 100%;
      padding: 0;
    }
    
    .main-carousel .carousel__button.is-prev {
      left: -1.5rem;
    }
    
    .main-carousel .carousel__button.is-next {
      right: -1.5rem;
    }
    
    .main-carousel .carousel__button:focus {
      outline: none;
      box-shadow: 0 0 0 4px #a78bfa;
    }
    
    .thumb-carousel .carousel__slide {
      opacity: 0.5;
      padding: 0;
      margin: 0.25rem;
      width: 96px;
      height: 64px;
    }
    
    .thumb-carousel .carousel__slide img {
      width: 100%;
      height: calc(100% - 4px);
      object-fit: cover;
      border-radius: 4px;
    }
    
    .thumb-carousel .carousel__slide.is-nav-selected {
      opacity: 1;
    }
    </style>
    
  3. 在另一個頁面中,引入元件示例:

    <template>
      <div class="fancy-app-test">
        <FancyApp :gallery="gallery" :dataFancyBox="dataFancyBox"></FancyApp>
      </div>
    </template>
    
    <script>
    import FancyApp from "@/components/FancyApp.vue";
    
    export default {
      setup() {
        return {
            // 圖片資料格式:
          gallery: [
            {
              src: "https://lipsum.app/id/2/800x600",
              thumb: "https://lipsum.app/id/2/80x80",
              caption: "First image",
            },
            {
              src: "https://lipsum.app/id/3/800x600",
              thumb: "https://lipsum.app/id/3/80x80",
              caption: "Second image",
            },
            {
              src: "https://lipsum.app/id/4/800x600",
              thumb: "https://lipsum.app/id/4/80x80",
              caption: "Third image",
            },
          ],
            
            // 這個可不填
          dataFancyBox: "gallery",
        };
      },
      components: {
        FancyApp,
      },
    };
    </script>
    
  4. 搞定啦!

A little hug, little gift. All of little something. these are our meories.