Web Components: SVG Icon

定义组件

class Icon extends HTMLElement {
  constructor() {
    super();

    const props = {};
    props.name = this.getAttribute('name');

    const namespaceURI = 'http://www.w3.org/2000/svg';
    const svg = document.createElementNS(namespaceURI, 'svg');
    svg.classList.add('icon');
    svg.setAttribute('aria-hidden', 'true');
    const use = document.createElementNS(namespaceURI, 'use');
    use.setAttribute('xlink:href', `#${props.name}`);
    svg.appendChild(use);
    this.innerHTML = svg.outerHTML;
  }
}
customElements.define('svg-icon', Icon);

使用

<svg-icon name="icon-about"></svg-icon>

<svg id="__svg__icons__dom__" xmlns="http://www.w3.org/2000/svg" xmlns:link="http://www.w3.org/1999/xlink" style="position: absolute; width: 0px; height: 0px;">
<symbol class="icon" viewBox="0 0 1024 1024" id="icon-about">
  <path d="M512 992C246.912 992 32 777.088 32 512 32 246.912 246.912 32 512 32c265.088 0 480 214.912 480 480 0 265.088-214.912 480-480 480zm-59.072-512v236.32a54.144 54.144 0 1 0 108.288 0V480a54.144 54.144 0 1 0-108.288 0zm53.76-226.464c-14.72 0-27.232 4.544-37.568 15.136-11.04 9.856-16.192 22.72-16.192 38.656 0 15.136 5.152 28 16.192 38.624 10.336 10.592 22.848 15.904 37.6 15.904a57.6 57.6 0 0 0 39.04-15.168c10.304-10.592 15.456-23.456 15.456-39.36s-5.12-28.8-15.456-38.656c-10.304-10.56-23.584-15.136-39.04-15.136z"></path></symbol>
</svg>

另一个版本,使用 ShadowRoot

NtIcon.js

import BaseComponent from '../base';
import style from './index.css?inline' assert { type: 'css' };

class NtIcon extends BaseComponent {

  static componentName = 'nt-icon';

  static iconURL = 'http://localhost:5173/icons/index.js';

  static get observedAttributes() {
    return [ 'size' ];
  }

  async registerIcons() {
    const icons = await import( /* @vite-ignore */ this.constructor.iconURL );
    return icons;
  }

  get name() {
    return this.getAttribute( 'name' );
  }

  set name( value ) {
    this.setAttribute( 'name', value );
  }

  get size() {
    return this.getAttribute( 'size' );
  }

  set size( value ) {
    this.setAttribute( 'size', value );
  }

  attributeChangedCallback( prop, oldValue, newValue ) {
    if ( prop === 'size' ) {
      this.style.fontSize = `${ newValue }px`;
    }
  }

  constructor() {
    super();

    this.registerIcons().then( ( module ) => {
      const icons = module.default;
      const icon = icons.find( ( icon ) => icon.name === this.name );
      const shadowRoot = this.attachShadow( { mode: 'open' } );
      shadowRoot.innerHTML = `
      <svg id="icon" part="icon">
        <symbol viewBox="0 0 1024 1024" id="${ icon.name }">
          ${ icon.path }
        </symbol>
        <use xlink:href="#${ this.name }"></use>
      </svg>
      `;
      this.adoptStyleSheet( style, shadowRoot );
    } );
  }
}

export default NtIcon;

css

#icon {
  width: 1em;
  height: 1em;
  fill: currentColor;
}

base.js

export default class BaseComponent extends HTMLElement {
  static define(componentName = this.componentName, options = {}) {
    if ( !window.customElements.get( componentName ) ) {
      window.customElements.define( componentName, this );
    }
  }

  adoptStyleSheet( style, dom = this.shadowRoot) {
    const cssStyleSheet = new CSSStyleSheet();
    cssStyleSheet.replace( style );
    dom.adoptedStyleSheets = [ ...dom.adoptedStyleSheets, cssStyleSheet ];
  }

  attributeChangedCallback(prop, oldValue, newValue) {
    // TODO
  }

  connectedCallback() {
    // TODO
  }

  disconnectedCallback() {
    // TODO
  }

  adoptedCallback() {
    // TODO
  }

  constructor() {
    super();
  }
}

icon.js

export default [
  {
    name: 'wallet',
    path: '<path d="M516.6592 947.2c-313.4976 0-435.6608-75.3152-435.6608-268.6464 0-168.96 122.4192-280.8832 237.7728-349.0304q-17.8176-21.1456-36.3008-44.9536c-36.4032-44.6976-45.7216-94.6688-25.6-137.1136 20.48-43.5712 67.84-69.5808 126.0544-69.5808h272.128c50.8928 0 93.0816 25.6 112.64 68.2496 20.48 44.7488 11.9296 99.584-22.272 139.7248a2303.232 2303.232 0 0 1-39.8848 45.7728c125.184 81.5104 242.0224 213.6576 242.0224 345.6 0 96.9216-30.72 162.0992-96.256 205.1072C783.9744 926.72 677.5808 947.2 516.6592 947.2zM382.9248 139.3664C349.5424 139.3664 322.56 152.576 312.32 174.08c-9.6256 20.224-3.072 46.5408 17.8688 72.192l0.512 0.6144c20.48 26.1632 40.0384 49.92 58.7776 70.6048a30.72 30.72 0 0 1-8.3968 47.7696c-108.9024 57.6-238.7456 158.72-238.7456 313.5488 0 134.3488 59.648 207.2064 374.2208 207.2064 309.1456 0 369.6128-76.4416 369.6128-208.5376 0-101.2736-100.2496-229.6832-243.8144-312.32a30.72 30.72 0 0 1-6.912-47.7184c18.944-20.0704 39.68-43.3152 63.3856-71.2192 18.688-21.9648 23.9104-51.2 13.2608-74.1376-9.6768-20.992-29.952-32.5632-57.0368-32.5632z" fill="#3D3937" p-id="26266"></path><path d="M654.9504 602.6752v-38.0928a21.4528 21.4528 0 0 0-21.4016-21.4528h-37.2224l39.3728-36.608a21.4528 21.4528 0 0 0 1.0752-30.3104l-25.9584-27.904a21.504 21.504 0 0 0-30.3104-1.0752l-76.2368 70.9632L428.032 447.232a21.504 21.504 0 0 0-30.3104 1.0752L371.7632 476.16a21.504 21.504 0 0 0 1.0752 30.3104l39.3728 36.608h-37.2224a21.4528 21.4528 0 0 0-21.4016 21.4528v38.0928a21.4016 21.4016 0 0 0 21.4016 21.4528h88.7808v38.656H374.9888a21.4016 21.4016 0 0 0-21.4016 21.4528v38.0928a21.4528 21.4528 0 0 0 21.4016 21.4528h88.7808v36.4544a21.4528 21.4528 0 0 0 21.4528 21.4016h38.0928a21.4016 21.4016 0 0 0 21.4528-21.4016v-36.4544h88.7808a21.4528 21.4528 0 0 0 21.4016-21.4528v-38.0928a21.4016 21.4016 0 0 0-21.4016-21.4528H544.768v-38.6048h88.7808a21.4016 21.4016 0 0 0 21.4016-21.4528z" fill="#73CAFF" p-id="26267"></path>'
  },
  {
    name: 'favorite',
    path: '<path d="M328.7552 884.5312c-18.3296 0-36.5056-5.7344-52.0704-17.0496-27.4944-19.968-41.0112-53.248-35.2768-86.7328l22.4256-130.6624c2.7648-16.1792-2.56-32.7168-14.336-44.1856l-94.9248-92.5696c-24.3712-23.7568-32.9728-58.5728-22.4256-90.9312s37.9392-55.4496 71.5776-60.3648L334.8992 343.04a50.01216 50.01216 0 0 0 37.5808-27.2896L431.104 196.8128c15.0528-30.5152 45.5168-49.4592 79.5648-49.4592s64.4608 18.944 79.5136 49.4592l58.6752 118.8864a49.80224 49.80224 0 0 0 37.5808 27.2896l131.1744 19.0464c33.6384 4.9152 61.0816 28.0064 71.5776 60.3648s1.8944 67.1744-22.4256 90.9312l-94.9248 92.5696a49.7408 49.7408 0 0 0-14.336 44.1856l22.4256 130.6624c5.7344 33.536-7.7824 66.7648-35.2768 86.7328-27.4944 19.968-63.2832 22.5792-93.3888 6.7584l-117.3504-61.696a49.9712 49.9712 0 0 0-46.4384 0l-117.3504 61.696a89.1648 89.1648 0 0 1-41.3696 10.2912zM510.6688 208.8448c-5.12 0-17.664 1.4848-24.4224 15.2064L427.5712 342.8864a111.37024 111.37024 0 0 1-83.8144 60.928l-131.2256 19.0464c-15.104 2.2016-20.4288 13.7216-22.016 18.5344s-4.0448 17.2544 6.912 27.9552l94.9248 92.5184c26.2656 25.6 38.1952 62.4128 32 98.56l-22.4256 130.6624c-2.6112 15.0528 6.7072 23.6544 10.8544 26.6752s15.1552 9.1648 28.7232 2.0992l117.3504-61.696c32.4608-17.0496 71.168-17.0496 103.6288 0l117.3504 61.696c13.5168 7.1168 24.576 0.9216 28.7232-2.0992s13.4144-11.5712 10.8544-26.6752L696.9344 660.48a111.4112 111.4112 0 0 1 32-98.56l94.9248-92.5184c10.9568-10.6496 8.448-23.0912 6.912-27.9552s-6.8608-16.3328-22.016-18.5344l-131.1744-19.0464a111.2832 111.2832 0 0 1-83.8144-60.928l-58.6752-118.8864c-6.7584-13.7216-19.3536-15.2064-24.4224-15.2064z" fill="#474747" p-id="26450"></path><path d="M659.2 512.3072c-1.536 0-3.1232-0.1024-4.7104-0.3584l-56.9856-8.7552a95.872 95.872 0 0 1-69.632-48.4352l-28.8768-51.8656a30.73024 30.73024 0 0 1 11.8784-41.7792c14.848-8.2432 33.536-2.9184 41.7792 11.8784l28.8768 51.8656a35.01568 35.01568 0 0 0 25.2928 17.6128l56.9856 8.7552c16.7936 2.56 28.2624 18.2784 25.7024 35.0208a30.72 30.72 0 0 1-30.3104 26.0608z" fill="#45CFFF" p-id="26451"></path>'
  },
  {
    name: 'praise',
    path: '<path d="M717.7216 860.1088H392.96c-77.5168 0-140.544-63.0272-140.544-140.544V478.1568c0-39.2192 12.1344-76.6976 35.072-108.4928 0.8192-1.1264 1.6896-2.1504 2.6112-3.1744l140.0832-147.6608c17.152-22.784 42.1376-37.4272 70.5024-41.3696 29.0816-3.9936 57.8048 3.8912 80.7936 22.1696 45.312 36.0448 53.6576 100.6592 18.9952 147.0464l-28.416 37.9904 178.944-11.0592c43.5712-2.6624 84.992 14.4896 113.8688 47.104 28.8768 32.6144 40.9088 75.9296 32.9728 118.784-0.0512 0.2048-0.0512 0.3584-0.1024 0.512l-41.8304 205.4144c-12.4928 66.4576-70.5536 114.688-138.1888 114.688zM336.1792 407.1936a123.14112 123.14112 0 0 0-22.3232 70.912v241.408c0 43.6224 35.4816 79.104 79.104 79.104h324.7616c38.144 0 70.8096-27.1872 77.7728-64.7168 0.0512-0.2048 0.0512-0.3584 0.1024-0.512l41.8304-205.3632c4.352-24.0128-2.4064-48.2816-18.5856-66.6112a78.464 78.464 0 0 0-64.1024-26.5216l-222.6688 13.7728c-16.128 1.024-31.0272-7.2192-38.7584-21.504s-6.4512-31.232 3.2256-44.2368l54.6304-73.0624a44.71808 44.71808 0 0 0-8.0384-62.1568 44.6464 44.6464 0 0 0-34.1504-9.3696 44.7488 44.7488 0 0 0-30.3616 18.2272c-0.8192 1.1264-1.6896 2.1504-2.6112 3.1744l-139.8272 147.456z" fill="#474747" p-id="26281"></path><path d="M166.9632 839.1168c-16.9472 0-30.72-13.7728-30.72-30.72V418.4064c0-16.9472 13.7728-30.72 30.72-30.72s30.72 13.7728 30.72 30.72v389.9904c0 16.9984-13.7728 30.72-30.72 30.72z" fill="#45CFFF" p-id="26282"></path>'
  }
];

使用

import NtIcon from 'NtIcon.js';
NtIcon.define();
<nt-icon name="praise" sise="40"></nt-icon>
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值