原文地址: vue单文件中引用路径的处理
若有错误,欢迎指正!
vue单文件的开发过程当中,在单文件模版中可能会涉及到文件路径的处理,好比 <img>
, style 中的 background 的处理等。下文中讨论了几种不一样场景下的 <img>
的 src 处理,解释了在使用 vue+webpack 的开发过程当中如何正确的引用静态资源(好比图片的处理)。javascript
以下所示,在下面的单文件组件中给出了不一样场景下引用图片路径的示例(图片静态资源存放在 src/assets/small.png ):html
<template> <div id="app"> <!-- 1. 模版中src选项直接写相对路径 --> <img src="./assets/small.png" alt="图片相对路径测试"> <!-- 2. 模版中src选项绑定相对路径字符串 --> <img :src="relative_img" alt="图片相对路径测试"> <!-- 3. 模版中src选项绑定html绝对路径字符串 --> <img :src="absolute_img" alt="图片绝对路径测试"> <!-- 4. 模版中src选项绑定手动加载的图片资源 --> <img :src="smallImg" alt="图片资源测试"> </div> </template> <script> import smallImg from './assets/small.png'; export default { name: 'app', data() { return { smallImg: smallImg, relative_img: './assets/small.png', absolute_img: '/static/img/small.png', }; }, } </script>
上述代码片断给出了四种场景下使用 img 标签在 vue 单文件组件中引用图片资源的方式。固然,这四种方式并非均可以正确的加载图片资源。vue
状况一:java
在模版中直接以相对路径绑定到src属性,这种状况下能够正确加载图片资源。咱们知道,在 webpack 处理 vue 单文件组件的过程当中,主要是 vue-loader 来作针对 *.vue 文件的处理。vue-loader 的文档中 vue-loader 的资源路径处理一节给出了 vue-loader 是如何处理模版中的资源路径的。好比: <img src="">
, background: url()
, @import
等都将被做为模块依赖处理。也就是说这几种状况下 vue-loader 自动处理路径的资源引用以及最后的路径替换。其中对 img 的处理以下:webpack
<img src="./logo.png">
将会被 vue 模版编译器编译为:web
createElement('img', { attrs: { src: require('./logo.png') }})
这也就解释了为何状况一能够正确显示图片内容,是由于 vue-loader 自动帮咱们作了资源引入以及路径替换问题。vue-cli
状况二:数组
在模版中给 src 属性绑定了相对路径字符串变量,这种状况下图片没法正常显示。缘由在于 vue-loader 没法识别变量是否为路径字符串,所以也就不存在 vue-loader 自动引入资源以及路径替换的问题了。这种状况下,编译后的模版依然为相对路径字符串。很显然,没有相应的资源引入以及错误的路径,是没法正确的展现图片的。app
状况三:测试
不少人在相对路径没法正确显示的同时,尝试进行了使用绝对路径变量引入,显然这种状况下也是不能显示图片的,由于图片资源未被手动引入。注意: 不少同窗尝试手动引入资源而后按照绝对路径变量绑定 src,发现 dist/static/img/
路径下确实有了被引用的资源,可是 vue-cli webpack 模版中 url-loader 对于 img 类型的文件在加载时,添加了 hash 值的处理。在这种状况下,即便咱们绑定的是绝对路径变量,由于没法正确匹配被添加 hash 值的图片文件,咱们仍是没法正确的引用到图片。在这种须要手动引入图片的状况下,推荐状况四的处理方式。
状况四:
在模版中 src 属性直接绑定手动引入的图片资源,这种状况下能够正确的显示图片。这样的方式也是 vue-loader 在处理自动引入路径对应的资源时使用的办法。
综上,在 vue 单文件组件中,正确的显示一个图片的关键:
以上两点缺一不可。状况一以及状况四最后之因此可以正确的显示了图片,就在于两种状况下知足了以上两个条件。状况一中 vue-loader 自动帮咱们作了这个事情,状况四咱们手动作了这个事情。
开发中可能遇到的问题:
开发中可能会遇到循环渲染一个图片列表的场景,根据上面的总结,咱们能够构造一个图片信息对象数组,好比:
<template> <div id="app"> <!-- 1. 模版中 src 选项直接写相对路径 --> <img src="./assets/small.png" alt="图片相对路径测试"> <!-- 2. 模版中 src 选项绑定相对路径字符串 --> <img :src="relative_img" alt="图片相对路径测试"> <!-- 3. 模版中 src 选项绑定绝对路径字符串 --> <img :src="absolute_img" alt="图片绝对路径测试"> <!-- 4. 模版中 src 选项绑定手动加载的图片资源 --> <img :src="smallImg" alt="图片测试"> <!-- 5. 循环加载图片资源示例 --> <img v-for="image in imgList" :key="image.id" :src="image.src" :alt="image.title"> </div> </template> <script> import smallImg from './assets/small.png'; import bigImg from './assets/big.jpg'; export default { name: 'app', data() { return { smallImg: smallImg, relative_img: './assets/small.png', absolute_img: '/static/img/small.png', imgList: [ { id: 1, title: 'test1', src: require('./assets/logo1.png') }, { id: 2, title: 'test2', src: require('./assets/logo2.png') }, { id: 3, title: 'test3', src: require('./assets/logo3.png') }, ], }; }, } </script>
这样咱们就能够完美的显示咱们循环渲染的图片了。