Vue Loader

Vue loader的作用

Vue-loader配置处理资源路径(资源url转换为webpack模块请求)
e.g. src="../image.png" => require("../image.png");
Vue-loader默认处理了video,source,img,image,use,所以我们才可以在配置attr时使用webpack路径,比如<image src="@/assets/images/xxx.png" />
https://vue-loader.vuejs.org/guide/asset-url.html

Vue loader配置

那我们该怎么给自定义component配置呢?

方法1 webpack.config.js

直接配在webpack.config.js,plugins中引入VueLoaderPlugin,然后module.rules里面指定test到什么表达式时load什么loader
https://vue-loader.vuejs.org/guide/#manual-setup

   plugins: [
     new VueLoaderPlugin()
   ],
   module: {
     rules: [
       {
         test: /\.vue$/,
         loader: 'vue-loader'
       }
     ]
   }, 

方法2 vue.config.js

可是本项目用的是vue cli,要自定义webpack配置要怎么办呢? 欸,这个vue-cli文档里写了,可让我好找了一翻
在vue.config.js里chainWebpack,来修改webpack的config
https://cli.vuejs.org/guide/webpack.html#modifying-options-of-a-loader

  chainWebpack: (config) => {
    config.module
      .rule("vue")
      .use("vue-loader")
      .tap((options) => {
        // 这里我们配置,转换v-img组件的src属性
         options.transformAssetUrls = {
             //blah blah blah
             "v-img": "src",
         }
        return options
      });
  },

动态绑定attr的问题

我在方法2改写options之前打印了一下,实际可以看到,vue-loader的transformAssetUrls中已经包含了v-img

在实际使用中,我们发现以下场景

<v-img src="@/assets/images/inventory/item.png" />  // 1.图片显示正常
<v-img :src="@/assets/images/inventory/' + item.image" />  // 2.图片不显示

在场景1中,我们证实了v-img的src属性确实被webpack捕捉到并require了
但是为什么场景2中又不行了呢? Evan在这里说明了情况

Because the imagePath is only rendered by Vue at runtime, Webpack has no chance of rewriting it. In your JS, use require('~assets/' + this.country.name + '.jpg') instead. This allows Webpack to return the correct static path.

因为是动态绑定的,imageUrl是runtime被渲染的,static的webpack无法捕捉然后转换成require(),所以动态src的情况下,我们还是得用requireΣ(っ °Д °;)っ

<v-img :src="require('@/assets/images/inventory/' + item.image)" />  // 3. 图片显示正常