最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Inline SVG in vuejs component - Stack Overflow

programmeradmin2浏览0评论

I have created a Vuejs project using @vue/cli version 3.0.0-beta.16 and in my Home.vue single file component I want to import and add inline SVG in the template but I am having trouble doing so.

The problem is vue cli is already using .svg file extension for file-loader like so:

webpackConfig.module
  .rule('svg')
    .test(/\.(svg)(\?.*)?$/)
    .use('file-loader')
      .loader('file-loader')
      .options({
        name: getAssetPath(options, `img/[name].[hash:8].[ext]`)
      })

I have already tried using the html-loader plugin for including svg in the template and it works fine if I clear the svg default use in my vue.config.js and add my own loader like this:

// vue.config.js

chainWebpack: config => {
    const svgRule = config.module.rule('svg')

    // clear all existing loaders.
    // if you don't do this, the loader below will be appended to
    // existing loaders of the rule.
    svgRule.uses.clear()

    // add replacement loader(s)
    svgRule
    .test(/\.(svg)$/)
    .use('html-loader')
    .loader('html-loader')
    .options({
    })
}

and in my template:

// Home.vue

<div v-html="require('./../assets/inline.svg')"></div>

But the problem is it also replaces svg src in the <img /> tags with inline svg code. What I want is use file-loader for <img src="something.svg" /> and use html-loader for require('./inline.svg'). How do I use multiple loaders for same rule in webpack? Or is it the right approach? Any help would be appreciated.

Edit I think the problem is I'm adding the both loaders the wrong way. This is how I add them in my file:

// vue.config.js

svgRule
.test(/\.(svg)$/)
.use('file-loader')
.loader('file-loader')
.options({
  name: getAssetPath(options, `img/[name].[ext]`)
})

svgRule
.test(/\.(svg)$/)
.use('html-loader')
.loader('html-loader')
.options({
  attrs: ['div:v-html']
})

I have created a Vuejs project using @vue/cli version 3.0.0-beta.16 and in my Home.vue single file component I want to import and add inline SVG in the template but I am having trouble doing so.

The problem is vue cli is already using .svg file extension for file-loader like so:

webpackConfig.module
  .rule('svg')
    .test(/\.(svg)(\?.*)?$/)
    .use('file-loader')
      .loader('file-loader')
      .options({
        name: getAssetPath(options, `img/[name].[hash:8].[ext]`)
      })

I have already tried using the html-loader plugin for including svg in the template and it works fine if I clear the svg default use in my vue.config.js and add my own loader like this:

// vue.config.js

chainWebpack: config => {
    const svgRule = config.module.rule('svg')

    // clear all existing loaders.
    // if you don't do this, the loader below will be appended to
    // existing loaders of the rule.
    svgRule.uses.clear()

    // add replacement loader(s)
    svgRule
    .test(/\.(svg)$/)
    .use('html-loader')
    .loader('html-loader')
    .options({
    })
}

and in my template:

// Home.vue

<div v-html="require('./../assets/inline.svg')"></div>

But the problem is it also replaces svg src in the <img /> tags with inline svg code. What I want is use file-loader for <img src="something.svg" /> and use html-loader for require('./inline.svg'). How do I use multiple loaders for same rule in webpack? Or is it the right approach? Any help would be appreciated.

Edit I think the problem is I'm adding the both loaders the wrong way. This is how I add them in my file:

// vue.config.js

svgRule
.test(/\.(svg)$/)
.use('file-loader')
.loader('file-loader')
.options({
  name: getAssetPath(options, `img/[name].[ext]`)
})

svgRule
.test(/\.(svg)$/)
.use('html-loader')
.loader('html-loader')
.options({
  attrs: ['div:v-html']
})
Share Improve this question edited Jun 13, 2018 at 12:37 Atta ur Rehman asked Jun 13, 2018 at 10:11 Atta ur RehmanAtta ur Rehman 911 gold badge1 silver badge7 bronze badges 1
  • Hope, It`s help: stackoverflow.com/questions/49383528/… – Irony Commented Jul 28, 2018 at 12:23
Add a comment  | 

4 Answers 4

Reset to default 6

You can add a leading ! in the require expression to "override" existing loaders set up by the webpack config.

<div v-html="require('!html-loader!./../assets/inline.svg')"></div>

This will work without changes to the vue.config.js (as long as html-loader is installed)


Also, instead of using html-loader look into svg-inline-loader in can add hashes to classes and ids, so you don't need to worry about name collisions if you have multiple inline svgs on your page.

If you don't have html-loader installed simply execute

yarn add -D html-loader

Then add the following object to the rules array in your webpack config file:

{
  test: /\.svg$/,
  use: [{ loader: 'html-loader' }]
}

And finally, you will be able to import svg files to your scripts with the inline loader.

require('!html-loader!./../assets/inline.svg')

// or directly in your v-html directive
<div v-html="require('!html-loader!./../assets/inline.svg')"></div>

You're almost there, just tell Webpack which loader to use:

<div v-html="require('html-loader!./../assets/inline.svg')"/>

You may want to use both webpack loaders, but also to tell your html loader to restrict to div elements with v-html with the following syntax in the loader options:

{
  attrs: ['div:v-html']
}

Docs for the html loader are found there.

发布评论

评论列表(0)

  1. 暂无评论