背景
这是一个由vue-cli+webpack构建的项目,在开发的过程中我需要给<img>
动态绑定路径,可是我发现怎么无法解析路径,代码如下1234<div v-for="item in bookList"> <img :src='../assets/'+item.img"> // ……</div>
最后浏览器渲染的结果是这样的,感觉是直接当做字符串处理,而没有对地址进行解析
解决过程
- 一开始我在想会不会是相对路径写错了,可是当不是动态绑定
:src
的时候,路径前缀是没有问题的。 - 然后我把图片放在
static/img
目录下,并把路径前缀改为/static/img/xx.png
的时候,图片可以显示成功 - 我又尝试在data绑定路径或者methods中返回路径,使用相对路径
../assets
还是不能获取图片,但是获取static
文件下的静态资源是可以的
这时我想到了之前一个没有使用webpack打包的项目中,用:src
绑定相对路径可以的,无论是在img标签直接绑定路径,还是用data绑定变量返回路径,都是成功获取图片的。
所以我在想应该是webpack打包文件的某些编译过程导致不是我们所希望的结果。
然后,我在webpack文档找到了webpack是如何处理这些资源的。解决方法
- 方法一:把图片放在
static
文件夹下,使用的时候用其绝对路径,即/static/xxx
- 方法二:使用require(‘../xxx/xxx’)
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
)中所有图片,因为它不知道你运行的时候需要用到哪些图片1234background () {return require('./bgs/' + this.id + '.jpg')//也可在html标签绑定路径的时候用require()}
- 图片等静态资源并不是JavaScript。所以,在
在上面的解决过程中为什么文件放在
static
和src/assets
会有不同效果?
刚刚学构建webpack项目的时候,经常会看到网上一些教程会把图片等资源放在static
或者src/assets
目录下,两个都是放静态资源文件的,有什么区别呢?static
文件夹下的资源文件才是真正的静态资源,它只能用绝对路径,而且它的路径不会被webpack处理解析,而是直接按 绝对路径找到所需文件。- 除
static
文件夹之外,其他路径都是需要使用相对路径,并使用相应loader解析路径。其中就包括src/assets
下的文件。
- 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文件在浏览器中并行加载,运行时间更快)
- loaders是在打包构建过程中用来处理源文件的(JSX,Scss,Less..),一次处理一个;
关于
alias
在搜索答案的时候,我有看到很多人说问题的出现是因为路径写错了。原因是使用alias
配置了相对路径后,在使用配置的路径别名时(如下述'assets'
)时需要在前面加~
,如<img class="logo" src="~assets/logo.png">
。因为vue-html-loader and css-loader会把非根目录地址默认解析为当前目录。(如把src="assets/logo.png"
中的assets,默认是该组件所在目录下的assets文件夹)12345alias: {'src': path.resolve(__dirname, '../src'),'assets': path.resolve(__dirname, '../src/assets'),'components': path.resolve(__dirname, '../src/components')}其实
alias
配置只是相当于给上述路径取了一个别名,并不是必须的。