Vue3 动态加载静态资源

文章目录

Vue3 动态加载静态资源

效果图

代码实现

方式一: new URL()+computed

vue 复制代码
<script setup>
import {computed, ref} from "vue";

const seasons = ref(["spring", "summer", "autumn", "winter"]);
const currentSeason = ref("spring");

const imageUrl = computed(() => {
  return new URL(`../assets/images/${currentSeason.value}.png`, import.meta.url).href;
});

function handleClick(season) {
  currentSeason.value = season;
}
</script>

<template>
  <div class="container" :style="{'background-image':`url(${imageUrl})`}">
    <div class="season-tabs">
      <button v-for="season in seasons" :key="season"
              class="season-btn"
              :class="{'season-btn-active': currentSeason === season}"
              @click="handleClick(season)"
      >
        {{ season }}
      </button>
    </div>
  </div>
</template>

<style scoped>
.container {
  width: 100vw;
  height: 100vh;
  background-size: cover;
  background-position: center;
  display: flex;
  justify-content: center;
  align-items: center;
}

.season-tabs {
  display: flex;
  gap: 12px;
}

.season-btn {
  padding: 10px 24px;
  border: none;
  border-radius: 4px;
  background-color: #fff;
  font-size: 16px;
  cursor: pointer;
}

.season-btn-active {
  background-color: #409eff;
  color: #fff;
}
</style>

方式二: watch+ref

vue 复制代码
<script setup>
import {computed, ref, watch} from "vue";

const seasons = ref(["spring", "summer", "autumn", "winter"]);
const currentSeason = ref("spring");

const imageUrl = ref("");
watch(currentSeason, (newSeason) => {
  import(`../assets/images/${newSeason}.png`).then(m => {
    imageUrl.value = m.default;
  }).catch(e => console.error(e));
}, {immediate: true});

function handleClick(season) {
  currentSeason.value = season;
}
</script>

<template>
  <div class="container" :style="{'background-image':`url(${imageUrl})`}">
    <div class="season-tabs">
      <button v-for="season in seasons" :key="season"
              class="season-btn"
              :class="{'season-btn-active': currentSeason === season}"
              @click="handleClick(season)"
      >
        {{ season }}
      </button>
    </div>
  </div>
</template>

<style scoped>
.container {
  width: 100vw;
  height: 100vh;
  background-size: cover;
  background-position: center;
  display: flex;
  justify-content: center;
  align-items: center;
}

.season-tabs {
  display: flex;
  gap: 12px;
}

.season-btn {
  padding: 10px 24px;
  border: none;
  border-radius: 4px;
  background-color: #fff;
  font-size: 16px;
  cursor: pointer;
}

.season-btn-active {
  background-color: #409eff;
  color: #fff;
}
</style>

方式三:对象管理

vue 复制代码
<script setup>
import {computed, ref, watch} from "vue";

import spring from "@/assets/images/spring.png";
import summer from "@/assets/images/summer.png";
import autumn from "@/assets/images/autumn.png";
import winter from "@/assets/images/winter.png";
const seasons = ref(["spring", "summer", "autumn", "winter"]);
const currentSeason = ref("spring");

const seasonImages = {
  spring,
  summer,
  autumn,
  winter
};

const imageUrl = computed(() => seasonImages[currentSeason.value]);

function handleClick(season) {
  currentSeason.value = season;
}
</script>

<template>
  <div class="container" :style="{'background-image':`url(${imageUrl})`}">
    <div class="season-tabs">
      <button v-for="season in seasons" :key="season"
              class="season-btn"
              :class="{'season-btn-active': currentSeason === season}"
              @click="handleClick(season)"
      >
        {{ season }}
      </button>
    </div>
  </div>
</template>

<style scoped>
.container {
  width: 100vw;
  height: 100vh;
  background-size: cover;
  background-position: center;
  display: flex;
  justify-content: center;
  align-items: center;
}

.season-tabs {
  display: flex;
  gap: 12px;
}

.season-btn {
  padding: 10px 24px;
  border: none;
  border-radius: 4px;
  background-color: #fff;
  font-size: 16px;
  cursor: pointer;
}

.season-btn-active {
  background-color: #409eff;
  color: #fff;
}
</style>

源码下载

相关推荐
M--Y36 分钟前
LangGraph 工作流模式
开发语言·javascript·python·langchain·大模型·llm·langgraph
星栈1 小时前
视频即代码,Remotion 能做什么、不能做什么
前端·音视频开发
广州华水科技1 小时前
单北斗GNSS位移监测系统的应用与技术解析
前端
用户47949283569152 小时前
从一句话或代码仓到可交互 HTML:开源 Agent 画图技能 Archify v3.2 实测与选型边界
前端·后端·面试
风骏时光牛马4 小时前
生成一个AI多模态标题,仅输出一条标题,无额外文字、问句、备选、配图、文案等任何附加内容,不需要其他的任务服务 只要标题。
前端
wangruofeng5 小时前
从 GIF 到 AVIF:网页图片格式演进与 2026 年选型指南
前端·架构
清晨Coding6 小时前
为什么用 React Developer Tools 查看组件树这么乱?
前端·react.js
johnjincaaaa6 小时前
猿人学第 18 题「jsvmp 洞察先机」逆向通关实录
javascript·后端
鶴哥只手遮天6 小时前
《Electron 45.2.3 内核解剖》第 4 章 补丁体系:380 个补丁改了什么
前端·electron
FungLeo8 小时前
成为全栈·Vue 管理后台篇·分类树与标签管理:层级数据如何落到管理界面
前端·javascript·vue.js·分类树·naive ui·标签管理·前端数据结构