vue中动态加载图片报错

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vue中动态加载图片报错相关的知识,希望对你有一定的参考价值。

参考技术A 动态加载或进行逻辑操作显示的图片,直接放static文件下可以避免404报错

原因:

assets: 在项目编译的过程中会被webpack处理解析为模块依赖,只支持相对路径的形式,如< img src=”./logo.png”>和background:url(./logo.png),”./logo.png”是相对资源路径,将被webpack解析为模块依赖

static:在这个目录下文件不会被webpack处理,简单就是说存放第三方文件的地方,不会被webpack解析。它会直接被复制到最终的打包目录(默认是dist/static)下。必须使用绝对路径引用这些文件,这是通过config.js文件中的build.assetsPublic和build.assertsSubDirectory链接来确定的。

Vue 动态图片加载路径问题和解决方法

最近在做一个树形结构的组件,使用了Vue和element UI中el-tree组件。因为树中每个节点都需要显示一个图标图片,并且需要根据后台传入的数据类型动态地显示,所以图片的路径需要动态地加载。下面是核心组件代码:

 <el-tree :data="data" class="tree-view" node-key="id" :props="defaultProps" @node-click="click" :default-checked-keys="[1]">
            <span class="custom-tree-node" slot-scope="{node, data}">
            <img v-if="data.iconSkin != undefined" :src="data.iconSkin" style="margin-right: 0.3em; " />
            <span @click="getChildNodes(data.id) ">{{ node.label }}</span>
            </span>
</el-tree>

后台交互使用了vuex和axios,本篇文章后台数据没有问题,所以不做展示了。后台传入的数据结构是这样的:

{
    "id": "2|299|0",
    "open": false,
    "maxStatus": 0,
    "iconSkin": "res1",
    "name": "test",
    "children": [],
    "parent": false
}

Vue中动态加载图片需要使用require,这个很多文章都有介绍。具体可以参考这篇文章vue的 v-for 循环中图片加载路径问题

一开始我认为直接在后台传入完整的js语句就能加载,所以我把后台传入的数据iconSkin写成了完整的路径。也就是require(@/assets/resourceimage/res1.png),具体代码跟最上面的代码片段一致。

本来以为这样就能加载成功了,打开chrome查看发现图片裂开了,也就是图片获取失败了。检查HTML元素,发现图片的路径是字符串。

这是因为js在解析对象的时候并不会把字符串当成js对象去解析,因此解析出的路径显示成了字符串。在多次尝试和查资料以后我找到了几个解决方案

方案一:在src路径写require

这个方案比较简单,<img v-if="data.iconSkin != undefined" :src="require(@/assets/resourceimage/${data.iconSkin}.png)" style="margin-right: 0.3em; " />

只要保证数据是正确的,这个方案是完全可以的。

方案二:使用computed

computed是Vue里的计算属性,computed会在state数据更新时自动计算。

    computed: mapState({
        tree: function(state) {
            const data = state.resTree.treeResult;
            if (data != null) {
                const result = state.resTree.treeResult;
                return result.data;
            }
        }
    })

但是注意,此时不能使用方案一那样的形式了,应该将computed的数据绑定在组件上,然后通过v-for的方式进行调用。以element-UI的el-tree组件为例,我们可以这样写:

<el-tree :data="tree" class="tree-view" node-key="id" :props="defaultProps" >
            <span class="custom-tree-node" slot-scope="{node, tree}">
                <img :src="getUrl(`${node.icon}`)" style="margin-right: 0.3em; " />
                <span>{{node.label}}</span>
            </span>
        </el-tree>
<script>
methods: {
    getUrl(url) {
        return require(`@/assets/resourceimage/${url}.png`);
    }
}
</script>

这个用法比较简单,它把computed的计算结果——也就是tree绑定到el-tree的data上,这样就可以使用内部的node使用tree中的数据了。

切记不要使用下面的记住写法:

  1. require(‘@/assets/resourceimage/‘+${node.icon}‘+‘.png‘);
  2. require(‘@/assets/resourceimage/‘+{{node.icon}}‘+‘.png‘);

以上是关于vue中动态加载图片报错的主要内容,如果未能解决你的问题,请参考以下文章

vue加载组件报错说提前加载

Vue 动态图片加载路径问题和解决方法

vue:路由懒加载Loading chunk 1 failed.

VUE坑(3)static文件夹中图片动态加载的问题

vue动态加载视频问题

vue 动态路由 component引入报错?