svg组件封装

Posted 游戏三昧的木笔

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了svg组件封装相关的知识,希望对你有一定的参考价值。

1. 定义子组件

<template>
  <!-- svg:图标外层容器节点,内部需要与use标签结合使用 -->
  <svg :style=" width, height ">
    <!-- xlink:href表示执行用哪一个图标,属性值要为#icon-图标名字 -->
    <!-- use标签fill属性可以设置图标的颜色 -->
    <use :xlink:href="prefix + name" :fill="color"></use>
  </svg>
</template>

<script setup lang="ts">
// 接受父组件传递过来的参数
defineProps(
  // xlink:href属性值前缀
  prefix: 
    type: String,
    default: "#icon-"
  ,
  // 提供使用的图标名字
  name: String,
  // 接受父组件传递的颜色
  color: 
    type: String,
    default: ""
  ,
  // 接受父组件传过来的宽高
  width: 
    type: String,
    default: "30px"
  ,
  height: 
    type: String,
    default: "30px"
  
);
</script>
<style scoped></style>

2. 父组件引用

<template>
  <div>
    <svg-icon width="40px" height="40px" name="home"></svg-icon>
  </div>
</template>

<script setup lang="ts">
// 引入子组件
import SvgIcon from "@/components/SvgIcon/index.vue";
</script>
<style scoped></style>

3. 效果

 

SVG defs 封装

【中文标题】SVG defs 封装【英文标题】:Svg defs encapsulation 【发布时间】:2018-07-06 14:52:24 【问题描述】:

我正在尝试在 React 组件中封装一个带有箭头的 SVG 行,而在 React 组件中没有任何全局 id,(但问题本身与 React 无关)。

例如小提琴https://jsfiddle.net/wzyzqhgh/1/

const LinkComponent = ( x1, y1, x2, y2, color ) => 
  const coordinates = calculateCoordinates(x1, y1, x2, y2)
  const linkStyle = calculateStyles(x1, y1, x2, y2)
  return (<svg style=linkStyle shapeRendering="geometricPrecision">
    <defs>
      <marker 
        id="arrow" 
        markerWidth=10 
        markerHeight=10 
        refX=9 
        refY=3 
        orient="auto" 
        markerUnits="strokeWidth"
      >
        <path d="M0,0 L0,6 L9,3 z" fill=color />
      </marker>
    </defs>
    <line
      x1=coordinates.x1
      y1=coordinates.y1
      x2=coordinates.x2
      y2=coordinates.y2
      strokeWidth=1
      stroke=color
      markerEnd="url(#arrow)"
    />
  </svg>)

这个组件在每次渲染时都会在本地定义一个marker,但似乎markerid 是全局的。所以当我这样做时:

ReactDom.render(
  (<div>
    <LinkComponent x1=10 y1=20 x2=100 y2=200 color="red" />
    <LinkComponent x1=10 y1=200 x2=200 y2=10 color="blue" />
  </div>),
  document.getElementById('test')
)

第一种颜色用于两个组件marker-end

问题:如何将markers 封装在单个svg 元素中,以免它们泄漏?除了id,还有其他方法可以在marker-* 属性中引用它们吗?如果不可以,不使用defs/markers如何实现类似的效果

【问题讨论】:

你没有。它只是 id 并且 id 是全局的。我想你可以单独绘制所有标记线。 【参考方案1】:

你有几个选择:

    将标记定义拉出到所有 LinkComponents 都引用的静态 SVG 中,或者

    每次生成一个随机的、唯一的id

    将颜色添加到 id,因此即使您有重复的标记定义,引用哪一个也没关系:

    id="arrow-color"
    

    不要使用标记。自己画箭头。

【讨论】:

添加颜色是一个不错的选择!你有关于如何在没有标记的情况下单独绘制箭头的资源吗?我首先使用标记的唯一原因是因为我不想自己计算线的角度并旋转箭头(三角形)。 看这个问答:***.com/questions/41737478/block-arrow-using-svg/…

以上是关于svg组件封装的主要内容,如果未能解决你的问题,请参考以下文章

vue中封装svg-icon组件并使用

SVG defs 封装

vue中使用svg-icon封装的组件来引用iconfont

自定SvgIcon公用组件

vue封装全屏组件无插件操作

vue封装全屏组件无插件操作