VueJS:使用反应变量修改 SVG 填充样式

Posted

技术标签:

【中文标题】VueJS:使用反应变量修改 SVG 填充样式【英文标题】:VueJS: Modify SVG fill style with reactive variables 【发布时间】:2019-12-08 01:19:39 【问题描述】:

我有一个看起来像这样的 SVG:

<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 120 121">
  <defs>
    <style>
      .cls-1fill:#fff.backgroundfill:#f00.trimfill:#0f0.foregroundfill:#00f
    </style>
    <mask id="mask" x="4" y="4"   maskUnits="userSpaceOnUse">
      <g id="mask-2">
        <path id="path-1" class="cls-1" d="M5 50a58 58 0 0 0 19 11l4-8q5 25-1 57c1 0 18 7 32 7s32-7 32-7q-5-31 0-57l4 8q13-5 19-11c-9-16-12-30-17-35q-6-4-24-11H47q-19 7-24 11c-5 5-7 17-18 35z"/>
      </g>
    </mask>
    <mask id="mask-2-2" x="5" y="4"   maskUnits="userSpaceOnUse">
      <g id="mask-2-3" data-name="mask-2">
        <path id="path-1-2" data-name="path-1" class="cls-1" d="M5 50a58 58 0 0 0 19 11l4-8q5 25-1 57c1 0 18 7 32 7s32-7 32-7q-5-31 0-57l4 8q13-5 19-11c-9-16-12-30-17-35q-6-4-24-11H47q-19 7-24 11c-5 5-7 17-18 35z"/>
      </g>
    </mask>
    <mask id="mask-3" x="3" y="4"   maskUnits="userSpaceOnUse">
      <g id="mask-2-4" data-name="mask-2">
        <path id="path-1-3" data-name="path-1" class="cls-1" d="M5 50a58 58 0 0 0 19 11l4-8q5 25-1 57c1 0 18 7 32 7s32-7 32-7q-5-31 0-57l4 8q13-5 19-11c-9-16-12-30-17-35q-6-4-24-11H47q-19 7-24 11c-5 5-7 17-18 35z"/>
      </g>
    </mask>
    <mask id="mask-4" x="5" y="4"   maskUnits="userSpaceOnUse">
      <g id="mask-2-5" data-name="mask-2">
        <path id="path-1-4" data-name="path-1" class="cls-1" d="M5 50a58 58 0 0 0 19 11l4-8q5 25-1 57c1 0 18 7 32 7s32-7 32-7q-5-31 0-57l4 8q13-5 19-11c-9-16-12-30-17-35q-6-4-24-11H47q-19 7-24 11c-5 5-7 17-18 35z"/>
      </g>
    </mask>
  </defs>
  <g id="Page-1">
    <path class="background" d="M5 50a58 58 0 0 0 19 11l4-8q5 25-1 57c1 0 18 7 32 7s32-7 32-7q-5-31 0-57l4 8q13-5 19-11c-9-16-12-30-17-35q-6-4-24-11H47q-19 7-24 11c-5 5-7 17-18 35z" id="Path-3"/>
    <g mask="url(#mask)">
      <path id="Path-7" class="trim" d="M28 54l-5-44L4 50l22 17 2-13z"/>
    </g>
    <g mask="url(#mask-2-2)">
      <path id="Path-7-Copy" class="trim" d="M91 54l5-44 19 39-23 18-1-13z"/>
    </g>
    <g mask="url(#mask-3)">
      <path id="Path-6" class="foreground" d="M6 46a68 68 0 0 0 21 12q2 2-1 3l-15-4-8-10z"/>
    </g>
    <g mask="url(#mask-4)">
      <path id="Path-6-Copy" class="foreground" d="M114 46a65 65 0 0 1-20 12q-2 1 1 3l22-11v-3z"/>
    </g>
    <path id="Path-4" class="foreground" d="M47 3h26l2 2a99 99 0 0 1-16 1 77 77 0 0 1-14-1z"/>
    <g id="Shirt-Collar">
      <path class="foreground" d="M60 3h13l2 1s1 4-7 7a36 36 0 0 1-8 2 36 36 0 0 1-8-2c-8-3-7-7-7-7l2-1z"/>
      <path id="Combined-Shape" class="background" d="M59 10c-11 0-10-6-10-6h23s1 6-11 6h-2z"/>
    </g>
  </g>
</svg>

这里有三个类 background trimforeground 我想在 VueJS 组件中进行响应式编辑。

我也有 50 个这样的 SVG,我也想切换它们,最好使用某种响应式 shirtId 属性。

但我不知道该怎么做。

我不能这样嵌入:

<img src="1.svg" />

因为那时我不能编辑这三个类。

看来我需要将它直接嵌入到组件中,所以我做到了:

https://codesandbox.io/s/vue-template-d2yi7

我在末尾的&lt;style&gt; 部分定义颜色:

<style>
    .cls-1fill:#fff
    .backgroundfill:#f00
    .foregroundfill:#00f
    .trimfill:#0f0
</style>

但这不是反应性的。

然后我尝试了这个:

https://codesandbox.io/s/vue-template-ddj72

现在可以使用backgroundStyle 属性设置背景颜色。

但这种方法意味着创建 50 个不同的组件,其中包含使用此内联样式标签编辑的每个 SVG。

我看过这个 SVG 加载器:https://github.com/visualfanatic/vue-svg-loader 但我看不出它对改变 css 属性有什么帮助。

我希望能够做到的最好是:

<my-custom-svg foreground="green" background="red" trim="blue" id="17"></my-custom-svg>

然后是 MyCustomSvg 加载 17.svg 并更改三个类的填充。

但我不知道这是否可能,也不知道如何从我现在的位置走到那一步。

【问题讨论】:

您可以将您的 定义为 Vue 组件,然后您将获得 Vue 的所有好处,但您必须对其进行转换。然后你也可以使用你想要的语法。 您也可以使用您提到的加载程序。这会将 完全导入 DOM。在父组件中,您将定义样式。请注意,如果您使用范围样式,您可能需要 /deep/ 选择器来定位这些元素。 【参考方案1】:

似乎CSS custom properties 可以提供帮助。

<style>
    .background  fill: var(--background); 
    .foreground  fill: var(--foreground); 
    .trim  fill: var(--trim); 
</style>

然后您可以根据道具更改自定义属性。

<template>
  <div :style="cssProps">
    <--! Your SVG here -->
  /div>
</template>

new Vue(
  el: '#app',
  pops: ['background', 'foreground', 'trim'],
  computed: 
    cssProps() 
      return 
        '--background': this.background,
        '--foreground': this.foreground,
        '--trim': this.trim
      
    
  
)

看看这个pen。

【讨论】:

有趣我从来没有见过这样的事情,-- 现在只是在玩

以上是关于VueJS:使用反应变量修改 SVG 填充样式的主要内容,如果未能解决你的问题,请参考以下文章

SVG图形的简单修改

svg circle标签可以填充图像吗

外部样式表中带有 fill:url(#id) 样式的 Firefox SVG,内联样式很好

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

如何使用外部 CSS 设置 SVG 样式?

输入元素中的vuejs svg元素对点击事件没有反应