首页 > 解决方案 > 在 Vue JS 上显示和隐藏 Carousel 元素在点击时显示大 Carousel

问题描述

我有 2 个 div,每个 div 都有一个轮播组件,如果你点击第一个 div 上的小轮播图片,我会显示带有大图片的轮播,如果你点击应用程序的其余部分,大轮播会关闭,而带有小图片的轮播会关闭背部。一切正常,直到您离开组件window.go(-1)然后回来,代码不起作用。我试图猜测原因,但无法获得线索。一旦我转到页面上的其他链接,我就会删除事件侦听器,当我出于某种原因返回时,我会 this.body = document.getElementById("app")得到整个#app,包括我的 2 个 div,即使我使用event.stopPropagation并检查它们ev.target !== this.carouselBig
为什么在重新渲染组件之前 div 会被正确替换?我什至删除了侦听器并在 mount 上重新创建了新的侦听器

<template>
  <div v-if="images">
    <div
      id="carouselSmall"
      v-show="!showBigImages"
      class="block"
      style="width:400px; max-width:100%; border:1px solid #ccc; margin:10px auto; border-radius:3px;"
    >
      <el-carousel type="card" height="100px">
        <el-carousel-item v-for="item in images" :key="item.small">
          <img :src="item.small" @click="displayBigImages()">
        </el-carousel-item>
      </el-carousel>
    </div>
    <div
      id="carouselBig"
      v-show="showBigImages"
      class="block"
      style="width:100%; border:1px solid #ccc; margin:10px auto; border-radius:3px;"
    >
      <el-carousel type="card" height>
        <el-carousel-item v-for="image in images" :key="image.original">
          <img :src="image.original">
        </el-carousel-item>
      </el-carousel>
    </div>
  </div>
</template>
<script>
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);

import common from "./Config";
import { Carousel, CarouselItem } from "element-ui";
Vue.use(Carousel);
Vue.use(CarouselItem);
export default {
  props: ["images"],
  data() {
    return {
      carouselBig: document.getElementById("carouselBig"),
      carouselSmall: document.getElementById("carouselSmall"),
      body: document.getElementById("app")
    };
  },
  computed: {
    showBigImages() {
      return this.$store.state.showBigImages;
    }
  },
  methods: {
    displayBigImages() {
      this.$store.commit("setshowBigImagesM", true);
    },
hideBigCarousel(destroy) {
      this.carouselBig = document.getElementById("carouselBig");
      this.carouselSmall = document.getElementById("carouselSmall");
      this.body = document.getElementById("app");

      let stopEvent = ev => {
        ev.stopPropagation();
      };

      let onBodyClick = ev => {
        if (ev.target !== this.carouselBig) {
          this.$store.commit("setshowBigImagesM", false);
        }
      };

      if (destroy) {
        this.carouselBig.removeEventListener("click", stopEvent, false);
        this.carouselSmall.removeEventListener("click", stopEvent, false);
        this.body.removeEventListener("click", onBodyClick, false);
      } else {
        this.carouselBig.addEventListener("click", stopEvent, false);
        this.carouselSmall.addEventListener("click", stopEvent, false);
        this.body.addEventListener("click", onBodyClick, false);
      }
    }
  },
  mounted() {
    window.onload = () => {
      this.hideBigCarousel();
    };
  },
  beforeDestroy() {
    this.hideBigCarousel(true);
  }
};
</script>

在此处输入图像描述

在此处输入图像描述

标签: javascriptvuejs2

解决方案


这只是建议。你需要检查这个,或者如果你给 jsfiddle 类似的东西,我会检查它。
首先,从数据中删除所有不是数据的东西。并使用ref. v-if="images"需要更改为v-show,因为该 div 内的 ref 将不起作用。我删除了一些清除,你可以在你的代码中返回它。

<template>
  <div v-show="images">
    <div ref="carouselSmall"
         v-show="!showBigImages"
         class="block"
    >
      <el-carousel type="card" height="100px"></el-carousel>
    </div>
    <div ref="carouselBig"
         v-show="showBigImages"
         class="block"
    >
      <el-carousel type="card" height></el-carousel>
    </div>
  </div>
</template>

<script>
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);

import common from "./Config";
import { Carousel, CarouselItem } from "element-ui";
Vue.use(Carousel); // you need use them inside all components? So, replace this code to main.js
Vue.use(CarouselItem);

export default {
  props: ["images"],
  data() {
    return {
    };
  },
  computed: {
    showBigImages() {
      return this.$store.state.showBigImages;
    }
  },
  methods: {
    displayBigImages() {
      this.$store.commit("setshowBigImagesM", true);
    },
    hideBigCarousel(destroy) {
      const carouselBig = this.$refs.carouselBig;
      const carouselSmall = this.$refs.carouselSmall;
      const body = document.getElementById("app"); // maybe better use this.$root?

      let stopEvent = (ev) => {
        ev.stopPropagation();
      };

      let onBodyClick = (ev) => {
        // contains check that element inside carouselBig
        if (!carouselBig.contains(ev.target)) {
          this.$store.commit("setshowBigImagesM", false);
        }
      };

      if (destroy) {
        carouselBig.removeEventListener("click", stopEvent, false);
        carouselSmall.removeEventListener("click", stopEvent, false);
        body.removeEventListener("click", onBodyClick, false);
      } else {
        carouselBig.addEventListener("click", stopEvent, false);
        carouselSmall.addEventListener("click", stopEvent, false);
        body.addEventListener("click", onBodyClick, false);
      }
    }
  },
  mounted() {
     this.hideBigCarousel();
  },
  beforeDestroy() {
    this.hideBigCarousel(true);
  }
};
</script>

推荐阅读