-
Notifications
You must be signed in to change notification settings - Fork 18
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
src binding not finding svg file #2
Comments
Hello, Its not working like that. This Webpack loader only parses static files. It does not execute any Vue logic at this point. That happens later, when these files are served from server and parsed in client (browser). So in this loader its not possible to use Vue bindings, because binded variables in template would not get replaced prior to Vue execution in client (browser). Its probably good idea to mention it in readme file. You are probably looking for some kind of vue-plugin (that will dynamically inject SVGs to DOM based on your current data) and not webpack-loader. If you have any questions, feel free to ask. |
Thanks, @oliverfindl. I appreciate your response, and it all makes sense. I think it would be convenient to be able to use Vue bindings, but understand why it's not. |
Readme file updated. Closing this issue. |
I have a similar problem.
in js
and all working fine =) |
Hello, yes this will work fine, but you have to define all img tags in your source code. Eg.: It won't work, for resources fetched with ajax. Thanks |
this does not work at all, the |
Hello, Could you describe in more detail what exactly is not working? Even better if you could provide some dummy repo which has this issue replicable. Thanks |
Hello, i'm sorry I should have been more explicit. I think everything is working as intended, it's newbie78's workaround that is not working. |
Hello, I just tested this workaround and its still working for me. Template: <template>
<div class="root-wrapper">
<div v-html="image" class="logo-wrapper" />
</div>
</template> Script: export default {
name: "App",
data: () => ({
image: `<img svg-inline svg-sprite src="@/assets/logo.svg" class="logo" />`
})
}; Please can you try this example and give feedback if it works for you? Thanks |
My bad, this does work. I was trying to declare all my path in a <template>
<div class="root-wrapper">
<div v-html="getImage()" class="logo-wrapper" />
</div>
</template> export default {
name: "App",
methods: {
getImage() {
return '<img svg-inline svg-sprite src="@/assets/logo.svg" class="logo" />'
}
})
}; but this will not: <template>
<div class="root-wrapper">
<div v-html="getImage('someItem')" class="logo-wrapper" />
</div>
</template> export default {
name: "App",
methods: {
getImage(item) {
return '<img svg-inline svg-sprite src="@/assets/' + item + '.svg" class="logo" />'
}
})
}; In this second example, the SVG will be displayed but will not be inline. |
Hello, sure it wont work like that. This Webpack loader only parses static Vue SFC files ( Hope this brings some light into this issue. If you have any more questions, feel free to ask. Thanks |
Yes, I understood that from your first answer to this post, I'm just a little slow ;) thank you for the additional explanation anyway ! |
This working if data create in component? But vuex also not working? |
Hello, If you mean using variables via Vuex If you mean workaround using img tags directly in Vue data (or in this case in Vuex store state), this won't work because as mentioned above in my last answer, this loader parses only static Vue SFC files ( As mentioned in my first answer, you guys are probably looking for some kind of vue-plugin (that will dynamically fetch and inject SVGs to DOM based on your current data) and not webpack-loader. If you have any more questions, feel free to ask. Thanks. |
I am trying to do something like this:
and is not working |
Hello, as mentioned above, you can't use Vue bindings/variables with this loader. For more info please read all comments above. Thanks |
<template>
<div v-html="img"></div>
</template> export default {
props: {
name: {
type: String,
required: true
}
},
computed: {
path() {
// return `@images/icons/${this.name}.svg`
// OR
return require(`@images/icons/${this.name}.svg`)
},
img() {
return `<img svg-inline src="${this.path}" />`
}
}
} Does not work. I also tried return `@images/icons/${this.name}.svg` <img svg-inline="" src="@images/icons/dog.svg"> This line does not work at all, because Vue cannot even understand what it is. It can not find the file. I have to use only |
Hello, I will try to explain it one more time as simple as possible. This Webpack loader only parses static files. That means, it takes all your As for using If you have any more questions, feel free to ask. Thanks |
Can |
The point was that the following works, thanks to require with expression. <template>
<img :src="path" />
</template>
<script>
export default {
computed: {
path() {
return require('shared/icons/' + this.name + '.svg')
},
},
}
</script> Was wondering if someone the same mechanism could be leveraged in vue-svg-inline-loader. |
Hello, your example works in client/browser using custom Webpack require function, which is injected into your bundle. Therefore Vue can evaluate your variable and call this function to fetch correct svg file. In other words, this Webpack require function is just syntax sugar for loading resources with ajax. Imagine something like this (just a concept): export default {
computed: {
async path() {
try {
return await (await fetch('shared/icons/' + this.name + '.svg')).text();
} catch(e) {
console.error(e);
}
}
}
}; Looking at your example, I think even this could work: <div v-html="require('shared/icons/' + name + '.svg')"></div> But still, all this action happens in client/browser. Loader performs this action at build time without any Vue logic available. Only input for this loader is literally your single Whole point of this loader is, to get your svg files injected right into your built source code instead of img tags. Your example just downloads those files and then injects them into rendered html. Actually, I'm currently working at such Vue plugin, which would solve this particular issue, although at cost of performance compared to this loader. If you have any more questions, feel free to ask. Thanks |
You seem to have misunderstood the purpose of my example. It actually uses no ajax, but a simple |
Hello, sorry I really misunderstood it. But still, you need to keep in mind scope of Webpack and scope of Webpack plugin, which got access only to vue files without any hierarchy or relations. Input for this loader is your By current approach (swap img tag with svg tags if possible) with vue-directive (or without, if you set strict mode to false in options). This approach results in minimal/no changes to your files. Creating behavior similar to Webpack
I don't think, any of variants above is worth of coding as it would introduce much more complex logic to this loader (which I try to keep as simple as possible) and much larger file size per file (except variant 3, which would be only syntax sugar for something, that is possible right now). If you have some other (non-breakable) solution in mind, feel free to explain it here. Thanks |
Hey Oliver, given that most things in a Vue component will be dynamic (rare that you need a one-shot inline SVG) isn't that limiting the usefulness of the plugin? |
Hello, while it is true, that majority of use cases are based on displaying svg image is based on dynamic rules, Webpack runs before any Vue logic is able to execute (excluding SSR, which is minority of use cases). Therefore there is no simple way to know, which svg files should Webpack include into bundle. You can read my last message in this issue for more details and possible solutions. I'm currently working on Vue plugin, which will target this issue, of course with cost of performance. For your concerns about usefulness of this loader, currently you have more approaches you can use to inline your svg files:
At time I was writing this plugin, I had to solve situation, where I had to show one of 3 possible svg images about 100+ times (was user configurable). So at that time, it was pretty straightforward to me to do If you have any more questions, feel free to ask. Thanks |
All clear, appreciate the response! I am thinking if there's a pure-CSS way to handle this without involving JS at all. (as in, use SVG as background-image) |
This extension helped me out in the end. It takes a different approach but does the job. |
Hello, as for pure CSS solution, I know only about using icofonts (built from your svgs), but I don't like this approach. If you have any more questions, feel free to ask. Thanks |
Hi,
anyone can help please? i have been stuck on this for weeks :( |
Hello, I explained this issue multiple times here already... Please read whole tread. As for your example I made similar plugin vue-svg-inline-plugin, which aimed to solved this issue, but also failed at this task... However, at least it works with first dynamic value in If there would be some interest, I could create different version, that would work with dynamic source value, but it will have some other issues because of its nature (no placeholder images, missing images until they are fetched from server, jumping content, etc.). If you have some more (specific) questions, feel free to ask here. Thanks. |
Oh, thanks Oliver, my savior! yeap, I did look through all the comment before i posted this question, just trying to ask its there any possibility hahaha, but I think your new plugin should be suit in my case, since I just need to use it once. once again thanks for your efforts @oliverfindl |
Hello there, I'm not sure if this is an issue with the loader or merely a lack of my understanding. It appears that when I attempt to dynamically load an SVG using the
v-bind:src
approach on the image tag, the loader cannot find it.Loading SVG from src path
If I write it in normally
src="../../static/images/icon-basketball.svg"
it works.Loading SVG from build path
I've also tried this:
But it ends up just loading up an image tag with the SVG as it's src instead of inlining the SVG.
Any ideas?
The text was updated successfully, but these errors were encountered: