Creating/Manipulating SVG in Vue project

2019-03-06 02:45发布

I'm new to Vue.js and need to create a Vue component to create and manipulate SVG. From my understanding it's not best to use JQuery in a Vue component. However I would like to because it's so straightforward to select elements.

Here is my Vue component, but I'm not sure how to make it functional. (Note: the SVG will be coming from a web service so I need to append it to the DOM programmatically.)

<div id="app">
  <p>Hover mouse over the lights to turn them on.</p>
  <p>(How do I make this work??)</p>
  <div id="svg-div" v-html="svg" />
</div>

new Vue({
  el: '#app',
  data: {
    svg: `
      <svg width="50" height="120">
          <rect x="10" y="10" width="40" height="120" style="fill:black" />
          <circle cx="30" cy="30" r="15" fill="red" opacity=".3"/>
          <circle cx="30" cy="65" r="15" fill="yellow" opacity=".3"/>
          <circle cx="30" cy="100" r="15" fill="lightgreen" opacity=".3"/>
      </svg>`
  }
})

Here is a working example (non Vue) using JQuery.

var svg = `
<svg width="50" height="120">
  <rect x="10" y="10" width="40" height="120" style="fill:black" />
  <circle cx="30" cy="30" r="15" fill="red" opacity=".3"/>
  <circle cx="30" cy="65" r="15" fill="yellow" opacity=".3"/>
  <circle cx="30" cy="100" r="15" fill="green" opacity=".3"/>
</svg>
`;

$('#svg-div').html(svg);

$('circle').mouseenter(function() {
	$(this).attr('opacity', '1');
});

$('circle').mouseleave(function() {
	$(this).attr('opacity', '.3');
});
 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>Hover mouse over the lights to turn them on.</p>
<div id="svg-div" />

2条回答
Viruses.
2楼-- · 2019-03-06 03:11

I just found this package, that will inline an svg for you, and give you access to some basic properties. It won't do everything you need, but it looks to be a very useful start.

查看更多
▲ chillily
3楼-- · 2019-03-06 03:24

You can just directly bind the parts of the svg that you want to be dynamic. Here is a simple tutorial. You need to get the 'markup' of your svg out of javascript variables and into a template element.

Here's a working codesandbox. Looks very cool.

Here's what one of your dynamic circle elements looks like...

<circle cx="30" cy="30" r="15" fill="red" :opacity="redO" @mouseenter="redO = 1" @mouseleave="redO = .3"/>

Your requirement to load the svg via webservice will complicate things. It's not the loading - the challenge is to inject the bindings into the source of the svg. You can do this with Dom methods and setAttribute(). setAttribute() will let you set whatever attributes you like, starting with : and @, so you're essentially transforming your svg into a vue template with javascript. This code will be brittle, and vulnerable to changes in the structure of the svg, but it will get you out of a hole. You need to do all the attribute injecting before you initialize Vue

查看更多
登录 后发表回答