Vuejs image src 不是反应式的



我正在使用Vuejs,有3个图像,时间表决定显示哪个图像。在Computed部分加载了适当的src,这样图像就会反应性地循环,但除非我手动刷新,否则它仍然不会更改图像。

<template>
<div class="mainDisplay">
<!--Image div for morning schedule-->
<div class="imgContainer" v-if="getSchedule(currentHour()).includes('s1')">
<img class="banner" :src="getSrc" alt="Morning Cappucino">
</div>
<!--Image div for afternoon schedule-->
<div class="imgContainer" v-else-if="getSchedule(currentHour()).includes('s2')">
<img class="banner" :src="getSrc" alt="Afternoon Latte">
</div>
<!--Image div for evening schedule-->
<div class="imgContainer" v-else-if="getSchedule(currentHour()).includes('s3')">
<img class="banner" :src="getSrc" alt="Evening Hot Chocolate">
</div>
</div>
</template>

<script>
import axios from 'axios';
export default {
data() {
return {
morningCaption: " ",
afternoonCaption: " ",
eveningCaption: " ",
morningSrc: "./public",
afternoonSrc: "./public",
eveningSrc: "./public",
schedule: "",
src: "",
}
},
mounted() {
//xml file calling
axios.get("/screen-schedule-config.xml")
.then(response => {
//parse xml data 
let xmlobj = response.data;
let domParser = new DOMParser();
let xmlDocument = domParser.parseFromString(xmlobj, "text/xml");
// set image path
let imagePath = xmlDocument.getElementsByTagName("assets");
//set image src paths
this.morningSrc = imagePath[0].querySelector("asset").getAttribute("path");
this.afternoonSrc = imagePath[0].querySelectorAll("asset")[1].getAttribute("path");
this.eveningSrc = imagePath[0].querySelectorAll("asset")[2].getAttribute("path");
}
)
},
methods: {
//get current hour
currentHour() {
const currentDate = new Date();
const hour = currentDate.getHours();
return hour
},
//get schedule for sequence 
getSchedule(hour) {
let schedule = "";
if (hour >= 0 && hour < 12) {
schedule = "s1";
} else if (hour >= 12 && hour < 19) {
schedule = "s2";
} else {
schedule = "s3";
}
return this.schedule = schedule
}
},
// computed property allows you to have logic that is dependent on reactive data.
computed: {
getSrc() {
if (this.schedule.includes("s1")) {
this.src = this.morningSrc
} else if (this.schedule.includes("s2")) {
this.src = this.afternoonSrc
} else if (this.schedule.includes("s3")) {
this.src = this.eveningSrc
}
return this.src
}
}
}
</script>

我的图像路径来自公共文件夹,我已经知道这与此有关。非常感谢。

我刚刚遇到了一个问题,对我来说,这是因为服务器总是将图像命名为original.ext,所以它没有响应,因为文件名总是原始的.jpg

在不更改服务器以使用更合理的文件名的情况下,我的解决方案是简单地在文件名上附加一个时间戳。

例如,在我的应用程序中,有两个加载用户数据的功能:登录功能和检查访问令牌功能。这两个都向服务器发出请求,服务器返回具有图像字段的用户对象,即使文件本身发生变化,该字段的文件名也保持不变。

我的修复方法是将用户对象设置为正常,但也存储用户数据设置的时间戳,例如:

this.user = response.data.user;
this.refreshed_user_at = (new Date()).valueOf();

这使我能够对文件名进行版本设置,使其在文件名保持不变和时间戳更改时具有反应性:

<img :src="`${auth.user.image}?v=${auth.refreshed_user_at}`">

这就产生了DOM元素:

<img src="http://www.com/original.jpg?v=1779384756845">

我认为这里最初的问题是另一个问题。根据我的经验,当Vue JS中的文件名更改时,img src是被动的,因此问题只能与getSrc在其内部使用的值更改时不更新有关,因此文件名不会更改。我认为这里的问题更有可能与v-if="getSchedule(currentHour()).includes('s1')"有关,因为条件是方法调用的结果,而这些条件不是被动的。我更希望看到一个使用计算道具来代替条件的解决方案。

很难推荐一个快速解决方案,因为我不明白用户体验的目标是什么。该组件似乎缺乏与何时调用this.getSchedule(currentHour())相关的逻辑。

也许你可以简单地称之为一秒钟一次:

data() {
return {
intervalId: null,
};
},
mounted() {
this.intervalId = setInterval(() => {
this.getSchedule(this.currentHour());
}, 1000);
},
beforeDestroy() {
clearInterval(this.intervalId);
},

我最喜欢的解决方案可能是将getSchedulegetSrc合并为一个计算的prop,该prop读取当前小时并返回正确的文件名,然后放入一个setInterval函数,该函数每秒将当前小时设置为组件状态一次。然后,如果合并后的函数是一个计算道具,它将在每次小时更改时自动更新文件名。

最新更新