简体   繁体   中英

Loading inline SVG in vuejs via prop into a component

I am trying to load an inline svg into my component.

App.vue

template

<vue-anime :url="'planetiaermma.svg'" />

anime.vue

  <div>
    <div v-html="this.loadSVG()"></div>
    <img :src="this.svgfile()" alt />
  </div>

  props: ["url"],

  methods: {
    svgfile() {
      var img = this.getImgUrl(this.url);
      return img;
    },
    getImgUrl(pic) {
      return require("../assets/" + pic);
    },

    loadSVG() {
      var img = this.getImgUrl(this.url);
      var svgraw;
      this.$nextTick(() => {
        fetch(img)
          .then(res => res.text())
          .then(svg => {
            svgraw = svg;
          });
      });
      return svgraw;
    },
    mounted() {
      this.loadSVG();
    }
  }
};

firing svgfile() into a :src works

firing loadSVG() should load it inline, does not seem to however, even though the return svgraw; is in a string of html/xml.

You can simply use something like vue-inline-svg for this:

npm install vue-inline-svg

and register the component globally in your main.js file:

import Vue from 'vue'
import App from './App.vue'
import InlineSvg from 'vue-inline-svg';

Vue.component('inline-svg', InlineSvg);

new Vue({
  render: h => h(App),
}).$mount('#app')

After that you can use the component anywhere inside your templates

Note: if you use vue-loader assets or vue-cli, then paths like '../assets/my.svg' will not be handled by file-loader automatically like vue-cli do for tag, so you will need to use it with require:

<template>
  <div>
    <inline-svg :src="require(`../assets/${url}`)" />
 <!-- You also can specify some props -->
 <!-- width="150" -->
 <!-- height="150" -->
 <!-- :fill="false" -->
  </div>
</template>

and get rid of that messy code.

I'm not sure what are you getting from getImgUrl() but could you try this?

mounted() {
   this.$nextTick(() => {
    this.loadSVG();
   });
}

You might also try this to be sure it's not from missing value:

<img v-if="svgURL" :src="svgURL" alt />


data() {
  return {
    svgURL: null
  }
}

mounted() {
  loadSVG() {
    this.svgURL = 'YOUR VALUE'
  }
}

Please avoid using this inside the template.

App.vue

<vue-anime :url="'planet.svg'" />

anime.vue component

<template>
  <div>
    <div v-html="mysvgfile"></div>
  </div>
</template>

 export default { props: ["url"], data() { return { mysvgfile: "" }; }, methods: { svgfile() { var img = this.getImgUrl(this.url); return img; }, getImgUrl(pic) { return require("../assets/" + pic); }, loadSVG() { var img = this.getImgUrl(this.url); var outer = this; this.$nextTick(() => { fetch(img) .then(res => res.text()) .then(svg => { outer.mysvgfile = svg; }); }); } }, mounted() { this.loadSVG(); } };

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM