父组件动态向子组件传本地图片,子组件要如何正确加载传值的图片?

父组件向子组件传值本地图片地址,子组件无法转成base64格式,且正确加载
// 子组件

<img :src="up ? icons.toggleUp : icons.toggleDown" />
@Prop({
    required: false,
    default: () => {
        return {
            toggleDown: require('./images/toggle-down.png'),
            toggleUp: require('./images/toggle-up.png'),
            
        }
    }
})icons!:Icon

// 父组件

<template>
    <mb-industrival-tv :icons="icons"/>   
</template>
<script lang="ts">
import { Icon } from "@/maxbase-ui/components/industrial-tv/types/icon.interface";
import { Component, Emit, Vue, Watch, Prop } from "vue-property-decorator";

@Component({})
export default class IndustrialTVClass extends Vue {

    icons: Icon = {
        toggleUp: require('@/assets/images/add_btn.png'),
        toggleDown: require('@/assets/images/ack-icon.png')
    }

}
</script>

子组件解析出来的图片中,prop中的传值并未解析成base64格式
image.png

请问父组件要采用哪种传值方式,子组件才可以显示父组件传过来的图片。

阅读 879
avatarAI BotBETA

你的问题在于你试图在父组件中动态地引入图片,并期望子组件可以正确地解析这些图片。然而,require 函数在编译时执行,它不能用于运行时动态地引入图片。

一种解决方案是,你可以将图片转换为 base64 格式,并在父组件中将其作为字符串传递。子组件可以直接使用此字符串作为 img 标签的 src。

以下是如何实现这个解决方案的步骤:

  1. 转换图片为 base64 格式:你可以使用 Node.js 的 fs 模块和 to-buffer 模块来将图片转换为 base64 格式。下面是一个示例代码:
const fs = require('fs');
const toBuffer = require('to-buffer');

function imageToBase64(imagePath) {
    return new Promise((resolve, reject) => {
        const reader = fs.createReadStream(imagePath);
        let data = '';

        reader.on('data', (chunk) => {
            data += chunk;
        });

        reader.on('end', () => {
            resolve(Buffer.from(data).toString('base64'));
        });

        reader.on('error', (err) => {
            reject(err);
        });
    });
}

// 使用这个函数来转换你的图片
imageToBase64('@/assets/images/add_btn.png')
    .then(base64Image => {
        console.log(base64Image);  // 打印出 base64 格式的图片
    })
    .catch(err => {
        console.error(err);
    });
  1. 在父组件中传递 base64 图片:一旦你有了 base64 格式的图片,你就可以在父组件中将其作为字符串传递给子组件。
// 父组件
export default class IndustrialTVClass extends Vue {
    icons: Icon = {
        toggleUp: this.getImageAsBase64('@/assets/images/add_btn.png'),
        toggleDown: this.getImageAsBase64('@/assets/images/ack-icon.png')
    }

    private async getImageAsBase64(imagePath: string): Promise<string> {
        return new Promise<string>((resolve, reject) => {
            imageToBase64(imagePath)
                .then(base64Image => {
                    resolve(base64Image);
                })
                .catch(err => {
                    reject(err);
                });
        });
    }
}
  1. 在子组件中显示图片:子组件可以直接使用父组件传递的 base64 字符串作为 img 标签的 src。
<template>
    <img :src="up ? icons.toggleUp : icons.toggleDown" />
</template>

<script lang="ts">
import { Component, Vue, Prop } from "vue-property-decorator";

interface Icon {
    toggleDown: string;
    toggleUp: string;
}

@Component({})
export default class ChildComponent extends Vue {
    @Prop({
        required: false,
        default: () => {
            return {
                toggleDown: '',
                toggleUp: '',
            };
        }
    }) icons!: Icon;
}
</script>

这样,你就可以在子组件中正确地显示父组件传递的图片了。不过需要注意的是,base64 格式的图片可能会导致你的应用程序体积增大,因此如果你的应用程序中有很多图片,或者图片文件很大,那么这种方法可能会导致性能问题。在这种情况下,你可能需要考虑使用其他方法,例如使用 CDN 来托管你的图片,并在父组件中直接传递图片的 URL。

3 个回答
  1. 直接使用传递下来的URL地址显示,需要确保URL地址正确。
  2. 父级这边 require 之后处理成 base64 的形式去 prop

一般来说静态资源,并且你不需要做处理的话,直接放到 public 这种静态资源目录就可以,并不需要放到 src/assets 目录下。除非说你想要把这些资源在 webpack/vite 当中做小图转 base64 处理之类。

一般是webpack的url-loader会对图片进行处理 比如一些小图片转成base64 可以配置文件大小

我觉得没必要转64,你既然是传给子组件仅仅为了显示图片而已。
直接拼接一个

process.env.VUE_APP_BASEURL+'/assets/images/add_btn.png'
//VUE_APP_BASEURL为你链接后端的地址。

或者父组件只传给子组件一个标识(1为upIcon;2为downIcon),把图片路径放在子组件css里。然后用div v-if v-else搞起。

当然不懂你的业务,我只是不想死磕图片转64位编码,怎么简单怎么来。仅供参考。

=========2024/5/11补充回复=========

如果你是要研究,我理解就是icon库中还缺少你所需的图标,UI给你两个,则需要你自己转base64,然后合并甩给子组件用。
1、你系统里有个icon库,你console也都是base64格式。没问题

import { Icon } from "@/maxbase-ui/components/industrial-tv/types/icon.interface";

2、你采用该方法只是单纯的合并对象,icon库有没有负责自动转base64,不清楚。

icons: Icon = {
    toggleUp: require('@/assets/images/add_btn.png'),
    toggleDown: require('@/assets/images/ack-icon.png')
}
同等与Object.assign({}, obj1, obj2);

3、我理解系统里应该有一个封装好的imgToBase64的方法,需要你调一下转成base64然后合并

this.imgToBase64(url)
参考链接:https://blog.csdn.net/weixin_44360943/article/details/131163252
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题