I made a component in vue that splits into 3 boxes (I say views and 1 is the main view).
---------
| | 2 |
| 1 |---|
| | 3 |
---------
Initially I have an object that HAS multiple images, and MAY HAVE videos and/or 360 tours.
In box 1, I start by displaying the image gallery.
In box 2 there is a button. If the object has videos, the button is enabled. If I click on the button, the video is placed in box 1, and now box 2 has a preview of the image gallery (with a button that, when clicked, puts it back in view 1)
Box 3 behaves exactly the same as box 2, but with 360 traversal (it's an embedded HTML)
Right now my component is behaving fine and displaying things as it should. But now I want to add one more functionality and I don't know how to deal with it.
I want that, when the user interacts with the component, (for example by browsing the gallery, or playing the video, or browsing the 360 gallery) and then changes views, that they do not lose where they were.
Example: In the gallery, I could keep a variable currentIndex
for example, and I verify in what position it is, and when I change the view (to video or 360) and return to the image gallery, when it is raised, indicate that start at the index.
I did this and it worked, however I can't keep a state of the 360 gallery, it inevitably restarts.
What happens is that, since divs
they have the v-if statement, they conditionally render and mount or unmount their content.
I would like to find a solution (with some CSS) that makes the component load the images, videos, 360 gallery only the first time they are respectively added to view 1.
Then, when exchanging one view with another, the ones are not conditionally replaced (as it happens now), but one main view is superimposed on another. (this way you would never lose the current state of traversal 360)
Then if I unmount the component, there they should be unmounted.
Is it possible to do this without disassembling a lot of what I already did?
Thank you very much.
Here is the component:
<template>
<div class="container-multimedia">
<div class="col-9 container-principal" v-if="mostrando == 1">
<Galleria :value="arrImgs" :numVisible="5" :activeIndex="activeIndex" :showThumbnails="false" :showItemNavigators="true">
<template #item="slotProps">
<img
class="img-galeria"
:src="slotProps.item.image"
:alt="slotProps.item.image"
/>
</template>
<template #thumbnail="slotProps">
<img
class="img-thumb"
:src="slotProps.item.thumb"
:alt="slotProps.item.image"
/>
</template>
</Galleria>
</div>
<div class="col-9 container-principal" v-else-if="mostrando == 2">
<galeria-video :videos="arrVids" />
</div>
<div class="col-9 container-principal" v-else-if="mostrando == 3">
<galeria-360 :keyVid="arr360[0].key" />
</div>
<div class="col-3 barra-lateral">
<div class="container-1 multimedia" v-if="mostrando == 1">
<div v-if="!arrVids.length" class="content-multimedia no-contenido">
<!-- No hay video. No funciono. -->
<div class="boton circular">
<i><icon-base width="25" height="25" icon-name="Videos"><IconVideos /></icon-base></i>
</div>
</div>
<div v-else @click="setMostrando(2)" class="content-multimedia normal">
<!-- CLICK ACA PARA VER LA GALERIA DE VIDEOS -->
<div class="boton circular">
<i><icon-base width="25" height="25" icon-name="Videos"><IconVideos /></icon-base></i>
</div>
</div>
</div>
<div class="container-1 multimedia" v-else-if="mostrando == 2" @click="setMostrando(1)">
<!-- CLICK ACA PARA VER LA GALERIA DE IMAGENES -->
<div class="content-multimedia normal">
<div class="boton circular">
<i><icon-base width="25" height="25" icon-name="Fotos"><IconFotos /></icon-base></i>
</div>
</div>
</div>
<div class="container-1 multimedia" v-else-if="mostrando == 3">
<div v-if="!arrVids.length" class="content-multimedia no-contenido">
<!-- No hay video. No funciono. -->
<div class="boton circular">
<i><icon-base width="25" height="25" icon-name="Videos"><IconVideos /></icon-base></i>
</div>
</div>
<div v-else @click="setMostrando(2)" class="content-multimedia normal">
<!-- CLICK ACA PARA VER LA GALERIA DE VIDEOS -->
<div class="boton circular">
<i><icon-base width="25" height="25" icon-name="Videos"><IconVideos /></icon-base></i>
</div>
</div>
</div>
<!-- CASOS: 1) Hay fotos, videos y recorrida 360 -->
<div class="container-2 multimedia" v-if="mostrando == 1">
<div v-if="!arr360.length" class="content-multimedia no-contenido">
<!-- No hay recorrido 360. No funciono. -->
<div class="boton circular">
<i><icon-base width="30" height="30" icon-name="360º"><Icon360 /></icon-base></i>
</div>
</div>
<div v-else @click="setMostrando(3)" class="content-multimedia normal">
<!-- CLICK ACA PARA VER EL RECORRIDO EN 360 -->
<div class="boton circular">
<i><icon-base width="30" height="30" icon-name="360º"><Icon360 /></icon-base></i>
</div>
</div>
</div>
<div class="container-2 multimedia" v-if="mostrando == 2" @click="setMostrando(3)">
<div v-if="!arr360.length" class="content-multimedia no-contenido">
<!-- No hay recorrido 360. No funciono. -->
<div class="boton circular">
<i><icon-base width="30" height="30" icon-name="360º"><Icon360 /></icon-base></i>
</div>
</div>
<div v-else @click="setMostrando(3)" class="content-multimedia normal">
<!-- CLICK ACA PARA VER EL RECORRIDO EN 360 -->
<div class="boton circular">
<i><icon-base width="30" height="30" icon-name="360º"><Icon360 /></icon-base></i>
</div>
</div>
</div>
<div class="container-2 multimedia" v-if="mostrando == 3" @click="setMostrando(1)">
<!-- CLICK ACA PARA VER LA GALERIA DE IMAGENES -->
<div class="content-multimedia normal">
<div class="boton circular">
<i><icon-base width="25" height="25" icon-name="Fotos"><IconFotos /></icon-base></i>
</div>
</div>
</div>
</div>
</div>
<multimedia-full-screen :item="item"/>
</template>
<script>
import IconBase from '@/components/IconBase.vue';
import IconFavoritos from '@/assets/iconos/icono-favorito.vue';
import IconVideos from '@/assets/iconos/icono-videos.vue';
import Icon360 from '@/assets/iconos/icono-360.vue';
import IconFotos from "@/assets/iconos/icono-fotos.vue";
import IconPantallaCompleta from "@/assets/iconos/icono-pantalla-completa.vue";
import { ref } from "@vue/reactivity";
import Galleria from "primevue/galleria";
import Galeria360 from "../../../Galeria/Galeria360.vue";
import GaleriaVideo from "../../../Galeria/GaleriaVideo.vue";
import { useStore } from 'vuex';
import MultimediaFullScreen from './MultimediaFullScreen.vue';
import $ from 'jquery'
export default {
components: {
IconBase,
IconFavoritos,
IconVideos,
Icon360,
IconFotos,
IconPantallaCompleta,
Galleria,
Galeria360,
GaleriaVideo,
MultimediaFullScreen,
},
props: ["item"],
setup(props) {
const item = ref(null);
item.value = props.item;
const store = useStore()
const arrImgs = ref([]);
const arrVids = ref([]);
const arr360 = ref([]);
const activeIndex = ref(0);
// Variable para saber qué estoy mostrando: 1- imagenes. 2- video. 3-360
const mostrando = ref(1);
const setMostrando = (val) => {
mostrando.value = val;
};
// Obtengo imagenes
item.value.imagenes.map((e) => {
let obj = {
image: e.image,
thumb: e.thumb,
};
arrImgs.value.push(obj);
});
// Obtengo videos
if (item.value.videos.length) {
item.value.videos.map((e) => {
let obj = {
id: e.id,
titulo: e.title,
descripcion: e.description,
provider: e.provider,
key: e.key_video,
url: e.url,
player_url: e.player_url,
};
if (e.provider == "matterport") {
arr360.value.push(obj);
} else if (e.provider == "youtube") {
arrVids.value.push(obj);
}
});
}
const abrirGaleriaFullScreen = () => {
store.dispatch("propiedadPopup/galeriaFullScreenAction", true);
setTimeout(() => {
$("#toolbar1").focus();
}, 100);
};
return { arrImgs, arrVids, arr360, mostrando, setMostrando, activeIndex, abrirGaleriaFullScreen, item };
},
};
</script>
You can use css modules
These allow you to apply a css class to an element in the following ways:
In your case, instead of using
v-if
to display your components you can use the css modules withdisplay: none;
: