Мне не удалось применить плавный переход к изображению с помощью Vue JS 3. Переход отлично работает с текстом, но изображение просто загружается и отображается, как обычно, без применения перехода.
Я пытался создать загрузчик изображений, который будет показывать счетчик загрузки до тех пор, пока изображение не будет загружено, а затем исчезать счетчик загрузки и изображение после загрузки изображения. В настоящее время счетчик загрузки исчезает, как и ожидалось, но изображение не исчезает.
Вот что у меня есть в элементе изображения:
<script setup>
import FadeTransition from '../transitions/fade-transition.vue';
import { reactive } from 'vue'
const props = defineProps({
imgUrl: String,
route: String
})
let getURL = function () {
return new URL(props.imgUrl, import.meta.url);
}
let show = reactive({showing: false});
let showImg = function () {
show.showing = true;
}
</script>
<template>
<div class = "frame">
<FadeTransition><div v-show = "!show.showing" class = "loader"></div></FadeTransition>
<RouterLink :to = "props.route"><FadeTransition><img v-show = "show.showing" class = "image" :src = "getURL()" @load = "showImg()"/></FadeTransition></RouterLink>
</div>
</template>
<style scoped>
.frame {
width: 33.3333%;
aspect-ratio: 1/1;
margin: 0px;
/*inline-block leaves space for descenders (e.g: letter y or g) so space between rows is wrong*/
display: inline-flex;
position: relative;
padding: 6px;
}
.image {
width: calc(100% - 12px);
height: calc(100% - 12px);
position: absolute;
}
.loader {
border: 4px solid var(--grey);
border-top: 4px solid var(--darkGrey);
border-radius: 50%;
width: 30px;
height: 30px;
animation: spin 5s linear infinite;
position: absolute;
left: calc(50% - 15px);
top: calc(50% - 15px);
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
</style>
и компонент FadeTransition:
<script>
</script>
<template>
<Transition name = "fade">
<slot></slot>
</Transition>
</template>
<style>
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.5s ease;
}
.fade-enter-from,
.fade-leave-to {
opacity: 0;
}
</style>
Я попытался заменить изображение на текстовый блок, который работает правильно, что привело меня к выводу, что проблема заключается в том, что переход неправильно применяется к изображению.
Как я могу заставить переход правильно применяться к изображению?
@MoritzRingler спасибо, теперь я включил всю SFC. Если я поменял изображение на текст, он работал нормально, просто кажется, что изображения не работают.





Хм, все, что я могу вам сказать, это то, что он отлично работает на детской площадке
Если imgUrl является реквизитом, я бы добавил наблюдатель, который сбрасывает компонент при изменении URL-адреса:
watch(
() => props.imgUrl,
() => {
show.showing = false
},
{immediate: true}
)
В противном случае анимация загрузки и исчезновение не будут запускаться при изменении URL-адреса после начальной загрузки.
В остальном выглядит вполне нормально.
Пожалуйста, дайте мне знать, если я что-то упустил.
Странно, у меня там тоже работает. Я думаю, единственная разница в том, что мое изображение и переход также завернуты в ссылку маршрутизатора, но я не вижу, какая разница? И я визуализирую весь компонент, используя v-for для галереи из множества изображений, но опять же я не понимаю, почему это имеет значение, потому что каждый компонент должен быть независимым. Спасибо за попытку!
Хм, если удалить RouterLink, он работает? Уверен, что это не то. Ставлю на пропавшего наблюдателя. Я добавил его в ссылку на игровую площадку, может быть, это поможет
Наблюдатель исправил! Спасибо! Можете ли вы объяснить, почему это так? Я новичок в Vue и раньше не встречал наблюдателей. Я предполагал, что каждый раз, когда компонент используется, он не зависит от каких-либо других экземпляров компонента.
Во-первых, здорово, что это работает! Когда вы меняете свойство (например, imgUrl), компонент не инициализируется повторно, поэтому без наблюдателя теперь у вас есть новый URL-адрес, но show.showing по-прежнему верно из последнего URL-адреса, поэтому изображение отображается сразу, без затухания. и нагрузка. Наблюдатель обнаруживает изменение и сбрасывает show.showing, поэтому он снова работает. В общем, всякий раз, когда свойство запускает изменение компонента, вам необходимо сбросить его с помощью наблюдателя, если только вы не используете новый компонент (что обычно не то, что вы хотите делать).
Кстати. всякий раз, когда ответ помог вам, не забудьте проголосовать за него и / или отметить его как принятый ответ - баллы баллы, лол, так работает сайт
Спасибо, пометил ответ как принятый. Не позволю мне проголосовать, так как я новичок, но я вернусь к этому, как только это позволит мне
Это работает, когда я пробую это, я предполагаю, что это должно быть ваше
showImg(). Можете ли вы добавить этот код к своему вопросу?