是否可以在 Vue.js 中使用夜光?

is it possible to use luminous in Vue.js?

我正在尝试用 vue.js 和 Laravel 创建照片网站,并在点击照片时使用 luminous 来放大照片。 我的照片存储在 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

<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 中,并将函数放在挂载部分。
<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中,并将函数放在mounted部分。
<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 几乎相同,但第一张图片完全符合我的预期。但是,其他图片即使是新标签也不会打开任何东西。

很抱歉咆哮。 我被这个问题困扰了一个星期。我真的需要别人的帮助。 感谢您的配合。

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 调用提供任何内容。也许您可以尝试调试它以找到您的问题。