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>

源码下载

相关推荐
莫石6 分钟前
坦克打无人机模拟(three-tile 地形)
前端
hunterandroid10 分钟前
[鸿蒙从零到一] HarmonyOS 任务调度与并发模型实战:taskpool、Worker 与可取消任务
前端
颜进强17 分钟前
前端看后端 14:什么是 CORS?
前端·后端
sugar__salt30 分钟前
Vue3 自定义指令与插槽(Slot)技术详解
前端·javascript·vue.js·前端框架·vue
Csvn39 分钟前
🎯 Flex 布局的 `min-width: auto` 陷阱:为什么内容总是撑破容器?
前端
果然_1 小时前
纯前端图片压缩怎么做?不用上传服务器,浏览器里跑完所有逻辑
前端
英勇无比的消炎药1 小时前
TinyRobot DropdownMenu 下拉菜单:三种触发方式与实现原理
vue.js
Csvn1 小时前
🖼️ OffscreenCanvas:把 Canvas 绘制搬出主线程,动画卡顿的终极解药
前端
用户69371750013841 小时前
了解一下 Agent Harness
android·前端·后端
swipe1 小时前
16|(前端转全栈)前端人排查后端问题:curl、traceId、日志、MySQL、Redis 怎么用?
前端·后端·面试