You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue.js图片src无响应:按时段切换图片需手动刷新

问题分析与解决方案

你的图片无法响应式切换的核心原因是没有定时更新schedule状态,Vue的响应式系统依赖数据变化触发视图更新,而当前代码只有在页面加载或手动刷新时才会计算一次时段,后续时间变化时schedule不会自动更新。另外还有几个代码实践上的问题需要修正:

核心问题点

  1. schedule状态仅在getSchedule方法被调用时更新,但模板中调用getSchedule(currentHour())只会在组件初始化和重渲染时执行,不会定时触发,导致时段变化后状态未更新。
  2. 计算属性getSrc中直接修改data里的src,违反了计算属性的纯函数原则(计算属性不应产生副作用)。
  3. public文件夹的路径不需要包含./public,Vue会将public目录作为静态资源根目录,直接使用/文件名即可访问。

修复步骤

1. 定时更新时段状态

在mounted钩子中添加定时器,定时(比如每分钟)检查当前小时并更新schedule,确保状态随时间变化自动更新:

mounted() {
  // 初始化加载XML和时段
  this.loadScheduleConfig();
  // 每分钟更新一次时段
  this.interval = setInterval(() => {
    this.updateSchedule();
  }, 60000);
},
beforeUnmount() {
  // 组件销毁时清除定时器,避免内存泄漏
  clearInterval(this.interval);
},
methods: {
  // 提取加载XML的逻辑为单独方法
  loadScheduleConfig() {
    axios.get("/screen-schedule-config.xml")
      .then(response => {
        let xmlobj = response.data;
        let domParser = new DOMParser();
        let xmlDocument = domParser.parseFromString(xmlobj, "text/xml");
        let imagePath = xmlDocument.getElementsByTagName("assets");
        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");
      })
  },
  currentHour() {
    return new Date().getHours();
  },
  // 更新时段状态的方法
  updateSchedule() {
    const hour = this.currentHour();
    if (hour >= 0 && hour < 12) {
      this.schedule = "s1";
    } else if (hour >= 12 && hour < 19) {
      this.schedule = "s2";
    } else {
      this.schedule = "s3";
    }
  }
}

2. 修改模板依赖响应式状态

模板中直接使用schedule状态判断,不再调用方法,确保响应式触发:

<template>
  <div class="mainDisplay">
    <div class="imgContainer" v-if="schedule === 's1'">
      <img class="banner" :src="getSrc" alt="Morning Cappucino">
    </div>
    <div class="imgContainer" v-else-if="schedule === 's2'">
      <img class="banner" :src="getSrc" alt="Afternoon Latte">
    </div>
    <div class="imgContainer" v-else-if="schedule === 's3'">
      <img class="banner" :src="getSrc" alt="Evening Hot Chocolate">
    </div>
  </div>
</template>

3. 修正计算属性为纯函数

计算属性getSrc直接返回对应时段的图片路径,不修改data中的src:

computed: {
  getSrc() {
    switch(this.schedule) {
      case 's1':
        return this.morningSrc;
      case 's2':
        return this.afternoonSrc;
      case 's3':
        return this.eveningSrc;
      default:
        return '';
    }
  }
}

4. 修正public资源路径

确保XML中配置的图片路径为根目录相对路径,比如/morning-banner.jpg,而不是./public/morning-banner.jpg,因为Vue会将public目录下的资源编译到根路径。

完整修正后的代码

<template>
  <div class="mainDisplay">
    <div class="imgContainer" v-if="schedule === 's1'">
      <img class="banner" :src="getSrc" alt="Morning Cappucino">
    </div>
    <div class="imgContainer" v-else-if="schedule === 's2'">
      <img class="banner" :src="getSrc" alt="Afternoon Latte">
    </div>
    <div class="imgContainer" v-else-if="schedule === '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: "",
      afternoonSrc: "",
      eveningSrc: "",
      schedule: "",
      interval: null
    }
  },
  mounted() {
    this.loadScheduleConfig();
    this.updateSchedule();
    this.interval = setInterval(() => {
      this.updateSchedule();
    }, 60000);
  },
  beforeUnmount() {
    clearInterval(this.interval);
  },
  methods: {
    loadScheduleConfig() {
      axios.get("/screen-schedule-config.xml")
        .then(response => {
          let xmlobj = response.data;
          let domParser = new DOMParser();
          let xmlDocument = domParser.parseFromString(xmlobj, "text/xml");
          let imagePath = xmlDocument.getElementsByTagName("assets");
          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");
        })
    },
    currentHour() {
      return new Date().getHours();
    },
    updateSchedule() {
      const hour = this.currentHour();
      if (hour >= 0 && hour < 12) {
        this.schedule = "s1";
      } else if (hour >= 12 && hour < 19) {
        this.schedule = "s2";
      } else {
        this.schedule = "s3";
      }
    }
  },
  computed: {
    getSrc() {
      switch(this.schedule) {
        case 's1':
          return this.morningSrc;
        case 's2':
          return this.afternoonSrc;
        case 's3':
          return this.eveningSrc;
        default:
          return '';
      }
    }
  }
}
</script>

内容的提问来源于stack exchange,提问作者Daniel Rogerson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 04:25:37