【问题标题】:Is it possible to bind SVG fill attribute that uses url() in VueJS?是否可以在 VueJS 中绑定使用 url() 的 SVG 填充属性?
【发布时间】:2020-03-15 00:04:14
【问题描述】:

我需要动态绑定 SVG 矩形元素的填充属性,但它不起作用。这是我的简单 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 属性引用它。

我之所以尝试这样做是因为我想避免在组件内部硬编码ids。由于我将在网页上有许多此组件的实例,因此会有多个具有相同 id 值的元素,这是不应该发生的。

【问题讨论】:

    标签: javascript html css vue.js svg


    【解决方案1】:

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

    理论

    将动态 css 类名绑定到 svg 并将填充物放入该类中。此链接显示如何使用 css 获取 css CSS - Style svg fill with class name

    我提出的解决方案假设是通过 props 将一些值传递给组件

    解决方案

    <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>
    

    【讨论】:

    • 抱歉,根据您的回答,我无法使其正常工作。请创建一个演示您的方法的代码笔示例吗? (你可以 fork 我的 codepen 示例并更改它)
    • @mlst 我已经更新了我的答案。你用的是什么版本的vue,你笔里的链接版本太旧了,所以不能绑定
    • 当我看到您的示例时,我意识到我需要将渐变定义移动到另一个 svg 元素以防止多个渐变 id。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-01
    • 1970-01-01
    • 2010-10-27
    • 1970-01-01
    • 2013-12-31
    • 2013-01-30
    相关资源
    最近更新 更多