关于图标资产的管理

关于图标资产的管理

关于图标资产的管理,大家可能也都是如下几种选择:

    1. iconfont建立一个项目,统一管理。
    1. 放本地项目assets里面(svg、png、jpg...)。
    1. 创建一个项目统一管理图标资产把svg改成组件形式,发布npm包 例如<el-icon name="i-home"/>

统一管理图标资产

前两种也就是最常见的,也就是不再赘述了,下面咱们展开说说第3种。咱们基于vue、js项目去展开说。

  1. 需要有一个el-icon组件,去载那些对应得icon组件。
  2. i-home 得需要支持单独引入。
  3. 都要支持一些属性得定义sizecolorsspin

el-icon 组件编写

创建global-component.js代码如下:

export default {
  name: 'ElIcon',
  functional: true,
  props: {
    name: {
      type: String,
      required: true,
      default: '',
    },
    size: {
      type: [String, Number],
      required: false,
      default: 16,
    },
    colors: {
      type: [String, Array],
       required: false,
      default: 16,
    },
    spin: {
      type: Boolean,
      required: false,
      default: false
    }
  },
  render(h, context) {
    return h(context.props.name, { props: context.props }, context.children);
  }
};

或者不使用render方法如下(global-component.vue):

<template>
  <div class="el-icon">
    <component
     :is="name" 
     v-bind="$attrs" 
     v-on="$listeners"
    />
  </div>
</template>

<script>
export default {
  name: 'ElIcon',
  props: {
    name: {
      type: String,
      required: true,
      default: '',
    },
    size: {
      type: [String, Number],
      required: false,
      default: 16,
    },
    colors: {
      type: [String, Array],
       required: false,
      default: 16,
    },
    spin: {
      type: Boolean,
      required: false,
      default: false
    }
  },
};
</script>

i-home 组件编写

再当前项目创建components文件夹,再创建home.vue文件如下:

<template>
<svg v-on="$listeners" v-bind="$attrs" :width="size" :height="size" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
  <path d="m8.328 1.106.325.231.037.029.031.028-.013-.014c-.002-.003-.001-.003 0-.004l-.003-.002.01.007.034.022.037.025a11.333 11.333 0 0 0 1.851.948c.5.2 1.034.334 1.564.413a7.122 7.122 0 0 0 .694.069l.537.009a.58.58 0 0 1 .566.583v1.447l.001.452L14 7.506V8.85C13.995 11.66 10.448 15 8 15c-2.45 0-6-3.346-6-6.156V3.45a.58.58 0 0 1 .566-.583l.548-.009a7.122 7.122 0 0 0 .683-.069 7.034 7.034 0 0 0 1.563-.413 11.46 11.46 0 0 0 1.454-.706c.254-.147.483-.296.529-.331l.322-.232a.569.569 0 0 1 .663 0Zm3.03 4.414a.75.75 0 0 0-1.061 0l-3.36 3.358L5.7 7.641a.75.75 0 0 0-1.06 1.06l1.767 1.768.077.068a.75.75 0 0 0 .984-.068l3.89-3.889a.75.75 0 0 0 0-1.06Z" fill-rule="evenodd"/>
</svg>
</template>

<script>
export default {
  name: 'Home',
  props: {
    size: {
      type: [String, Number],
      required: false,
      default: '16',
    },
    spin: {
      type: Boolean,
      required: false,
      default: false,
    }
  }
}
</script>

导出文件暴漏给vue install

再当前项目创建index.js导出该组件如下:

import ElIcon from './global-component.js'; // import ElIcon from './global-component.vue';
import Home from './components/home.vue'; 


const components = { // icon不可能就一个应该是多个得,放入一个对象里面
  Home,
};

const install = function(Vue, config = {}) { // 全局注册
  Vue.component(ElIcon.name, ElIcon); 
  components.forEach(component => {
    Vue.component(component.name, component);
  });
};

export default { install };
export {
  Home, // 支持单独引入使用
}

使用如下:

import Icons from 'custom-ioon'; // npm包名
Vue.use(Icons);

优化支持配置全局icon前缀,全局icon大小

如下:

import ElIcon from './global-component.js'; // import ElIcon from './global-component.vue';
import Home from './components/home.vue'; 


const components = { // icon不可能就一个应该是多个得,放入一个对象里面
  Home,
};


const componentHandler = (component, config = {
  perfix: 'i',
  size: 16,
}) => {
  const { size, perfix } = config;
  const componentName = `${perfix.toLocaleUpperCase()}${component.name}`;

  return {
    name: componentName,
    functional: true,
    props: {
      size: {
        type: [String, Number],
        default: size,
      },
    },
    render(h, context) {
      return h(component, {
        ...context.data,
        props: context.props,
      });
    }
  }
}



const install = function(Vue, config = {
  perfix: 'i',
  size: 16,
}) { // 全局注册
  Vue.component(ElIcon.name, ElIcon); 
  components.forEach(component => {
    const asComponent = componentHandler(component, config);
    Vue.component(asComponent.name, asComponent);
  });
};

export default { install };
export {
  Home, // 支持单独引入使用
}

全局使用:

import Icons from 'custom-ioon'; // npm包名
Vue.use(Icons, {
  perfix: 'el',
  size: 16,
});
<template>
<el-icon name="el-home"/>
</template>

局部使用:

<template>
 <Home />
</template>

<script>
import { Home } from 'custom-ioon'; 
export default {
  components: {
    Home,
  },
}
</script>

解决手动书写icon组件方案

正常流程不是像我们手动去创建文件组件得,一个一个写确实不是直接把svg引入项目更方便。正常流程应该如下:

  1. 有一个平台支持svg文件上传(可以使用svgo对原设计给的svg文件优化,截图如下:)。
  2. 上传完成后有一个发布按钮。
  3. 按照书写组件形式给生成一套项目代码,最后发布到npm上供使用。

为什么源码是svg没有选择编译成iconfont呢?

截图如下:

关于图标资产的管理
关于图标资产的管理
原链接:为什么要用SVG?- svg与iconfont、图片多维度对比

原文链接:https://juejin.cn/post/7236680350557552695 作者:三原

(0)
上一篇 2023年5月26日 上午10:20
下一篇 2023年5月26日 上午10:31

相关推荐

发表回复

登录后才能评论