[vue&webpck学习笔记] webpack项目的img路径动态绑定

背景

这是一个由vue-cli+webpack构建的项目,在开发的过程中我需要给<img>动态绑定路径,可是我发现怎么无法解析路径,代码如下

1
2
3
4
<div v-for="item in bookList">
<img :src='../assets/'+item.img">
// ……
</div>

最后浏览器渲染的结果是这样的,感觉是直接当做字符串处理,而没有对地址进行解析

解决过程

  1. 一开始我在想会不会是相对路径写错了,可是当不是动态绑定:src的时候,路径前缀是没有问题的。
  2. 然后我把图片放在static/img目录下,并把路径前缀改为/static/img/xx.png的时候,图片可以显示成功
  3. 我又尝试在data绑定路径或者methods中返回路径,使用相对路径../assets还是不能获取图片,但是获取static文件下的静态资源是可以的
    这时我想到了之前一个没有使用webpack打包的项目中,用:src绑定相对路径可以的,无论是在img标签直接绑定路径,还是用data绑定变量返回路径,都是成功获取图片的。
    所以我在想应该是webpack打包文件的某些编译过程导致不是我们所希望的结果。
    然后,我在webpack文档找到了webpack是如何处理这些资源的。

    解决方法

  • 方法一:把图片放在static文件夹下,使用的时候用其绝对路径,即/static/xxx
  • 方法二:使用require(‘../xxx/xxx’)
    • 在img标签中直接require,或在data/函数中返回
    • 需要计算路径的时候,可以使用字符串拼接的方式如<img :src="require('../assets/' + xxx)">

      原因分析

      看完上述文档链接基本就可以解决啦,这里简单划一下重点~
  1. webpack怎么处理静态资源文件?

    • 图片等静态资源并不是JavaScript。所以,在*.vue组件中所有模板和css中的资源都是由vue-html-loader and css-loader解析路径的,比如<img src="./logo.png">background: url(./logo.png)中的相对路径会被webpack处理为模块依赖module dependency
    • 当然静态资源并不是一定需要放在src/assets中,你也可以和组件所在目录放在一起。不同写法的路径的解析规则可以看上述文档单元中的Asset Resolving Rules~
    • 上面提到静态资源文件需要由file-loader解析路径,所以需要在JavaScript中返回路径的时候,需要用require('xxx')引入文件。但是当需要计算路径的时候会在构建的时候加入资源所在路径(如下图的./bg)中所有图片,因为它不知道你运行的时候需要用到哪些图片
      1
      2
      3
      4
      background () {
      return require('./bgs/' + this.id + '.jpg')
      //也可在html标签绑定路径的时候用require()
      }
  2. 在上面的解决过程中为什么文件放在staticsrc/assets会有不同效果?
    刚刚学构建webpack项目的时候,经常会看到网上一些教程会把图片等资源放在static或者src/assets目录下,两个都是放静态资源文件的,有什么区别呢?

    • static文件夹下的资源文件才是真正的静态资源,它只能用绝对路径,而且它的路径不会被webpack处理解析,而是直接按 绝对路径找到所需文件。
    • static文件夹之外,其他路径都是需要使用相对路径,并使用相应loader解析路径。其中就包括src/assets下的文件。
  3. loader是什么?和 Plugin有什么不同
    • loaders是在打包构建过程中用来处理源文件的(JSX,Scss,Less..),一次处理一个;
      • babel-loader(转化es6)
      • css-loader(使用类似@import 和 url(…)的方法实现 require()的功能)
      • style-loader(将所有的计算后的样式加入页面中,与前者一起作用能够把样式表嵌入webpack打包后的JS文件中)
    • Plugin(插件)是用来拓展webpack功能,它们并不直接操作单个文件,会在整个构建过程中生效,执行相关的任务,并直接对整个构建过程其作用
      • extract-text-webpack-plugin(合并为一个单独的CSS文件,而不是内联到js文件后面。而js文件和css文件在浏览器中并行加载,运行时间更快)
  4. 关于alias
    在搜索答案的时候,我有看到很多人说问题的出现是因为路径写错了。原因是使用alias配置了相对路径后,在使用配置的路径别名时(如下述'assets')时需要在前面加~,如<img class="logo" src="~assets/logo.png">。因为vue-html-loader and css-loader会把非根目录地址默认解析为当前目录。(如把src="assets/logo.png"中的assets,默认是该组件所在目录下的assets文件夹)

    1
    2
    3
    4
    5
    alias: {
    'src': path.resolve(__dirname, '../src'),
    'assets': path.resolve(__dirname, '../src/assets'),
    'components': path.resolve(__dirname, '../src/components')
    }

    其实alias配置只是相当于给上述路径取了一个别名,并不是必须的。