是否可以在VueJS中绑定使用url()的SVG填充属性?

时间:2019-11-19 12:50:28

标签: javascript html css vue.js svg

我需要动态绑定SVG rect元素的fill属性,但是它不起作用。这是我简单的VueJS组件,以演示我正在尝试做的事情(也可以在codepen中找到)

<template>
<div>
  <!-- this works but id and fill attributes are hardcoded -->
  <svg class="green" width="100" height="50" version="1.1" xmlns="http://www.w3.org/2000/svg">
    <linearGradient id="gradient1">
      <stop stop-color="red" offset="0%" />
      <stop stop-color="blue" offset="100%" />
    </linearGradient>
    <rect width="100" height="50" fill="url(#gradient1)" />
  </svg>

  <!-- this doesn't work... -->
  <svg class="green" width="100" height="50" version="1.1" xmlns="http://www.w3.org/2000/svg">
    <linearGradient :id="myid">
      <stop stop-color="red" offset="0%" />
      <stop stop-color="blue" offset="100%" />
    </linearGradient>

    <rect width="100" height="50" :fill="myfill" />
  </svg>
</div>
</template>

<script>
new Vue({
  el: 'body',
  data: {
    title: 'Vuejs SVG binding example',
    myid: 'gradient2',
    myfill: 'url(#gradient2)'
  },
});
</script>

请注意,fill属性使用url(),该元素将元素ID作为参数使事情复杂化。据我所知,fill属性使用在同一组件中定义的linearGradient的唯一方法是通过元素id属性对其进行引用。

我尝试这样做的原因是因为我想避免对组件内部的id进行硬编码。由于我在网页上将有很多该组件的实例,因此不应有多个具有相同id值的元素。

1 个答案:

答案 0 :(得分:0)

是的,可以做想做的事情。我做了一些类似的事情,但只是一个div而没有svg。

理论

将动态CSS类名称绑定到svg,然后将其填充到该类中。该链接向我们展示了如何使用CSS CSS - Style svg fill with class name

我提出的解决方案假定通过道具将一些值传递给组件

解决方案

<template>
...

    <rect width="100" height="50" :class="myfill" />
...
</template>

<script>
new Vue({
  el: 'body',
  data: {
    title: 'Vuejs SVG binding example',
    myid: 'gradient2',
    myfill: somePropYouPassedIn
  },
});
</script>

修改第一个答案

尝试小提琴时,我认为您正在正确地编写代码,只是使用了旧版本的Vuejs(当我尝试使您的小提琴工作时,我会注意到这一点)。无论如何,我无法让您的笔使用vue,所以我在这里https://jsfiddle.net/nkalait/ohmzxb7L/

创建了一个全新的小提琴

代码

<div>
  {{ title }}
  <!-- this works but id and fill attributes are hardcoded -->
  <svg class="green" width="100" height="50" version="1.1" xmlns="http://www.w3.org/2000/svg">
    <rect width="100" height="50" :fill="gradient1" />
  </svg>

  <!-- this doesn't work... -->
  <svg class="green" width="100" height="50" version="1.1" xmlns="http://www.w3.org/2000/svg">
    <rect width="100" height="50" :fill="gradient2" />
  </svg>


  // I HAVE PUT THE GRADIENTS IN THERE OWN SVG
  <svg aria-hidden="true" focusable="false" style="width:0;height:0;position:absolute;">
    <linearGradient id="gradient1">
      <stop stop-color="yellow" offset="0%" />
      <stop stop-color="blue" offset="100%" />
    </linearGradient>
    <linearGradient id="gradient2">
        <stop stop-color="red" offset="0%" />
        <stop stop-color="green" offset="100%" />
    </linearGradient>
  </svg>
</div>