0

我正在尝试使用 vue.js 和 Laravel 创建照片网站,并在单击时使用发光放大照片。我的照片存储在 AWS S3 存储桶中。

我的 vue.js 结构如下所示。

1.PhotoComponent.vue

  • 这个组件实际上是在渲染每张照片。
<template>
    <div class="photo">
        <a class="luminous" :href="item.url">
            <img class="photo_image" :src="item.url" :alt="`photo taken by ~~`">
        </a>
    </div>
</template>

<script>
export default {
    name: "PhotoComponent.vue",
    props: {
        item: { // this item has photo info(like url)
            type: Object, 
            required: true
        }
    },
}
</script>

<style scoped>
 
</style>

2.PhotoListComponent.vue

  • 这个组件正在制作一个 PhotoComponent.vue 列表。
<template>
    <div class="photo-list">
        <div class="grid">
            <PhotoComponent
                class="grid_item"
                v-for="photo in photos"
                :key="photo.id"
                :item="photo"
            ></PhotoComponent>
        </div>
        <PaginateComponent :current-page="currentPage" :last-page="lastPage"></PaginateComponent>
    </div>
</template>

<script>
import {OK} from '../util';
import PhotoComponent from "./PhotoComponent";
import PaginateComponent from "./PaginateComponent";

export default {
    name: "PhotoListComponent.vue",
    components: {
        PhotoComponent,
        PaginateComponent
    },
    props: {
        page: {
            type: Number,
            required: false,
            default: 1,
        }
    },
    data() {
        return {
            photos: [],
            currentPage: 0,
            lastPage: 0
        }
    },
    methods: {
        async fetchPhotos() { // I get each photo information through this method.
            const response = await axios.get(`/api/photos/?page=${this.page}`);

            if (response.status !== OK) {
                this.$store.commit('error/setCode', response.status);
                return false;
            }
            this.photos = response.data.data;
            this.currentPage = response.data.current_page;
            this.lastPage = response.data.last_page;
        },
    },
    watch: {
        $route: {
            async handler() {
                await this.fetchPhotos();
            },
            immediate: true,
        }
    },
}
</script>

<style scoped>

</style>

到目前为止,我尝试了三件事。

  1. 将 new Luminous() 放入 PhotoComponent 中,并将函数放入 mount 部分。
<template>
    <div class="photo">
        <a class="luminous" :href="item.url">
            <img class="photo_image" :src="item.url" :alt="`photo taken by ~~`">
        </a>
    </div>
</template>

<script>
import { Luminous } from 'luminous-lightbox';
export default {
    name: "PhotoComponent.vue",
    props: {
        item: { // this item has photo info(like url)
            type: Object, 
            required: true
        }
    },
   methods: {
       luminous() {
           new Luminous(document.querySelector(".luminous"));
       }
   },
  mounted: {
    this.luminous();
  }
}
</script>

在这种情况下,第一张图片有效,但 "" 打开的数量与 PhotoComponent.vue 一样多。例如,如果我在 PhotoListComponent 中列出 9 张图片并单击第一张照片,“”会打开 9 次。但是,其他图片根本不起作用,但会打开新标签。

  1. 将 new LuminousGallery() 放入 PhotoListComponent 中,并将函数放入已安装部分。
<template>
    <div class="photo-list">
        <div class="grid">
            <PhotoComponent
                class="grid_item"
                v-for="photo in photos"
                :key="photo.id"
                :item="photo"
            ></PhotoComponent>
        </div>
        <PaginateComponent :current-page="currentPage" :last-page="lastPage"></PaginateComponent>
    </div>
</template>

<script>
import {OK} from '../util';
import PhotoComponent from "./PhotoComponent";
import PaginateComponent from "./PaginateComponent";
import {LuminousGallery} from 'luminous-lightbox';

export default {
    name: "PhotoListComponent.vue",
    components: {
        PhotoComponent,
        PaginateComponent
    },
    props: {
        page: {
            type: Number,
            required: false,
            default: 1,
        }
    },
    data() {
        return {
            photos: [],
            currentPage: 0,
            lastPage: 0
        }
    },
    methods: {
        async fetchPhotos() { // I get each photo information through this method.
            const response = await axios.get(`/api/photos/?page=${this.page}`);

            if (response.status !== OK) {
                this.$store.commit('error/setCode', response.status);
                return false;
            }
            this.photos = response.data.data;
            this.currentPage = response.data.current_page;
            this.lastPage = response.data.last_page;
        },
        luminous() {
            new LuminousGallery(document.querySelectorAll('.luminous'));
        },
    },
    watch: {
        $route: {
            async handler() {
                await this.fetchPhotos();
            },
            immediate: true,
        }
    },
  mounted: {
    this.luminous();
  }.
}
</script>

在这种情况下,每当单击照片时都会打开一个新选项卡,这意味着发光功能不起作用。

  1. 未安装,但在这些组件中添加点击事件。

例如...

<template>
    <div class="photo">
        <a class="luminous" :href="item.url" @click.prevent="luminous">
            <img class="photo_image" :src="item.url" :alt="`photo taken by ~~`">
        </a>
    </div>
</template>

<script>
import { Luminous } from 'luminous-lightbox';
export default {
    name: "PhotoComponent.vue",
    props: {
        item: { // this item has photo info(like url)
            type: Object, 
            required: true
        }
    },
   methods: {
       luminous() {
           new Luminous(document.querySelector(".luminous"));
       }
   },
}
</script>

在这种情况下,结果与模式 1 几乎相同,但第一张图片完全符合我的预期。但是,其他图片即使是新标签也不会打开任何东西。

抱歉吐槽了。我被这个问题困扰了一个星期。我真的需要别人的帮助。谢谢您的合作。

4

1 回答 1

1

Konnichiwa @wadakatu,来自@imgix 的 Fred(Luminous 的维护者)。

您应该能够使您的所有解决方案发挥作用。

对于 1/ 我认为您需要能够仅定位该组件中存在的图像,所以这样的事情可以工作:

<template>
  <div class="photo">
    <a class="luminous" :href="item.url">
      <img class="photo_image" :src="item.url" :alt="`photo taken by ~~`" />
    </a>
  </div>
</template>

<script>
import { Luminous } from "luminous-lightbox";
export default {
  name: "PhotoComponent.vue",
  props: {
    item: {
      // this item has photo info(like url)
      type: Object,
      required: true,
    },
  },
  methods: {
    luminous() {
      // only look for relevant elements *inside* this component. Should only match one element
      new Luminous(this.$el.querySelector(".luminous"));
    },
  },
  mounted() {
    this.luminous();
  },
};
</script>

对于 2/ 我认为可能存在代码实际上没有找到图像元素的问题,因此没有为LuminousGallery调用提供任何内容。也许您可以尝试调试它以找到您的问题。

于 2021-02-08T09:07:38.583 回答