vue3项目使用指令方式修改img标签的src地址

大家好,我是1024小神,技术群 / 私活群 / 股票群 或 交朋友 都可以私信我。 如果你觉得本文有用,一键三连 (点赞、评论、关注),就是对我最大的支持~

因为项目要添加一个新的功能,就是在pad上的网页需要打开摄像头扫码的能力,而且是在局域网访问的,所以就需要后端地址启动在https的地址上,这个时候所有的静态资源都变成了https链接,这个时候一个unity同事在游戏中访问图片地址的时候就访问不了,有解决方案,但是要修改的地方有点多,但是扫码又必须使用https的链接,所以备选方案就是后端启动两个服务,一个http转为给游戏提供http的图片链接,https转为pad提供扫码能力。

但是这个时候问题就来了:pad + server + game 三者之间的通讯是使用proto协议传输的,其中就包含图片地址,这个图片地址是只有http链接字段的,不想再添加一个https的字段,会很麻烦,添加的话大家所有人都要修改代码,这个就只有我这个前端自己来解决了,那就是将所有图片链接中http替换为https,并将端口9091替换为9090,那全局那么多img标签呢,怎么做?

方案1:全局组件替换

创建一个全局的图片组建,然后将项目中的所有img标签改成这个全局组件,不推荐:因为要创建函数和全局组件,还要修改项目中所有的img标签,麻烦

javascript 复制代码
<!-- components/SecureImg.vue -->
<template>
  <img :src="secureSrc" v-bind="$attrs">
</template>

<script setup>
import { computed } from 'vue'

const props = defineProps({
  src: String
})

const secureSrc = computed(() => {
  if (!props.src) return ''
  return props.src.replace(/^http:\/\//i, 'https://')
})
</script>

然后在项目中全局注册:

javascript 复制代码
// main.js
import { createApp } from 'vue'
import App from './App.vue'
import SecureImg from './components/SecureImg.vue'

const app = createApp(App)
app.component('Img', SecureImg)
app.mount('#app')

方案2:使用Vue指令

创建一个指令,然后将所有img标签的src属性改为使用指令的方式。这个时候要改的就简单了,就是全局搜索<img src= 然后替换为 <img v-secure-src=即可实现。

javascript 复制代码
// directives/secureSrc.js
export const secureSrc = {
  beforeMount(el, binding) {
    if (binding.value && typeof binding.value === 'string') {
      el.src = binding.value.replace(/^http:\/\//i, 'https://')
    }
  },
  updated(el, binding) {
    if (binding.value && typeof binding.value === 'string') {
      el.src = binding.value.replace(/^http:\/\//i, 'https://')
    }
  }
}

// main.js
import { createApp } from 'vue'
import App from './App.vue'
import { secureSrc } from './directives/secureSrc'

const app = createApp(App)
app.directive('secure-src', secureSrc)
app.mount('#app')

如果img的src跟的是变量,直接使用指令跟上变量就可以了:

javascript 复制代码
<template>
  <div>
    <!-- 静态字符串 -->
    <img v-secure-src="'http://example.com/image1.jpg'" alt="image1">
    
    <!-- 动态变量 -->
    <img v-secure-src="imageUrl" alt="dynamic image">
    
    <!-- 响应式数据 -->
    <img v-secure-src="user.avatar" alt="user avatar">
  </div>
</template>

<script setup>
import { ref, reactive } from 'vue'

// 响应式数据
const imageUrl = ref('http://example.com/image2.jpg')
const user = reactive({
  avatar: 'http://example.com/avatar.jpg'
})

// 可以动态更新
setTimeout(() => {
  imageUrl.value = 'http://another-domain.com/new-image.jpg'
}, 3000)
</script>

方案3:使用指令参数

可以通过参数的形式,将url地址传递到指令里面,然后在指令里面修改:

javascript 复制代码
// directives/secureSrc.js
export const secureSrc = {
  beforeMount(el, binding) {
    if (binding.arg === 'url') {
      updateSrc(el, binding.value)
    }
  },
  updated(el, binding) {
    if (binding.arg === 'url') {
      updateSrc(el, binding.value)
    }
  }
}

function updateSrc(el, src) {
  if (src && typeof src === 'string') {
    el.src = src.replace(/^http:\/\//i, 'https://')
  } else {
    el.src = src || ''
  }
}

使用方式:

javascript 复制代码
<template>
  <div>
    <!-- 使用指令参数 -->
    <img v-secure-src:url="dynamicImageUrl" alt="dynamic image">
    <img v-secure-src:url="staticImageUrl" alt="static image">
  </div>
</template>

<script setup>
import { ref } from 'vue'

const dynamicImageUrl = ref('http://example.com/dynamic.jpg')
const staticImageUrl = 'http://example.com/static.jpg'
</script>

方法4:支持修饰符的指令

javascript 复制代码
// directives/secureSrc.js
export const secureSrc = {
  beforeMount(el, binding) {
    processSrc(el, binding)
  },
  updated(el, binding) {
    processSrc(el, binding)
  }
}

function processSrc(el, binding) {
  const src = binding.value
  let processedSrc = src
  
  if (src && typeof src === 'string') {
    // 强制HTTPS修饰符
    if (binding.modifiers.https) {
      processedSrc = src.replace(/^http:\/\//i, 'https://')
    }
    
    // 添加时间戳修饰符(避免缓存)
    if (binding.modifiers.nocache) {
      const separator = processedSrc.includes('?') ? '&' : '?'
      processedSrc += `${separator}_t=${Date.now()}`
    }
  }
  
  el.src = processedSrc || ''
}

使用方式:

javascript 复制代码
<template>
  <div>
    <!-- 只启用HTTPS转换 -->
    <img v-secure-src.https="imageUrl" alt="https only">
    
    <!-- 同时启用HTTPS和去缓存 -->
    <img v-secure-src.https.nocache="dynamicImage" alt="https and nocache">
  </div>
</template>

<script setup>
import { ref } from 'vue'

const imageUrl = ref('http://example.com/image.jpg')
const dynamicImage = ref('http://example.com/dynamic.jpg')
</script>

推荐方案

使用方法3(指令参数) 最为清晰,因为:

语义明确:v-secure-src:url 清楚地表示这是处理URL的

避免冲突:不会影响其他属性的处理

易于扩展:可以添加其他参数处理不同场景

这样无论src是静态字符串还是动态变量,都能正确工作,并且在数据更新时自动响应变化。
大家好,我是1024小神,技术群 / 私活群 / 股票群 或 交朋友 都可以私信我。 如果你觉得本文有用,一键三连 (点赞、评论、关注),就是对我最大的支持~

相关推荐
web小白成长日记8 小时前
企业级 Vue3 + Element Plus 主题定制架构:从“能用”到“好用”的进阶之路
前端·架构
APIshop8 小时前
Python 爬虫获取 item_get_web —— 淘宝商品 SKU、详情图、券后价全流程解析
前端·爬虫·python
风送雨9 小时前
FastMCP 2.0 服务端开发教学文档(下)
服务器·前端·网络·人工智能·python·ai
XTTX1109 小时前
Vue3+Cesium教程(36)--动态设置降雨效果
前端·javascript·vue.js
LYFlied9 小时前
WebGPU与浏览器边缘智能:开启去中心化AI新纪元
前端·人工智能·大模型·去中心化·区块链
Setsuna_F_Seiei10 小时前
2025 年度总结:人生重要阶段的一年
前端·程序员·年终总结
model200510 小时前
alibaba linux3 系统盘网站迁移数据盘
java·服务器·前端
han_11 小时前
从一道前端面试题,谈 JS 对象存储特点和运算符执行顺序
前端·javascript·面试
aPurpleBerry11 小时前
React 01 目录结构、tsx 语法
前端·react.js
jayaccc11 小时前
微前端架构实战全解析
前端·架构