小程序店铺装修-icon图标svg变色

793 阅读2分钟

环境:mpx框架搭建的小程序;功能:图标根据后端设置的颜色变色

首先使用的svg图标是去除底色的图标,并且是存在项目本地的文件。如果ui提拱的图标是有底色的svg,可以登录阿里巴巴字体矢量网站,去里面上传该svg,上传时,会有选项:把底色去除。上传成功后,再下载下来就是去除底色的svg。回到正文,那如何让svg变色呢?众所周知,目前小程序并不支持svg图标,也不支持字体图标,那是如果实现这个效果的呢?详情见下文。

首先建立一个公共组件,使用backgroundImage来实现该功能。

<template minapp='native' xlang='wxml'>
  <view
    class="m-icon {{iconClass}} mini-class"
    bindtap="_tap"
    style='background-image:url("{{backgroundImage}}");{{miniStyle}}'
  ></view>
</template>

js部分

properties: {
      icon: {
        type: String,
        value: '',
        observer: function(d) {
          // svg
          if (d && !this.data.backgroundImage) {
            this.setData({
              backgroundImage: svgIcon(d, this.data.color)
            })
          }
          // 不同icon命名
          if (d) {
            let className = iconClassName(d)
            if (className) {
              this.setData({
                iconClass: className
              })
            }
          }
        }
      },
      color: {
        type: String,
        value: '',
        observer: function(d) {
          // svg
          if (d && this.data.icon) {
            this.setData({
              backgroundImage: svgIcon(this.data.icon, d)
            })
          }
        }
      },
      miniStyle: {
        type: String,
        value: '',
        observer: function(e) {
          //样式
        }
      }
    },
    data: {
      backgroundImage: '',
      iconClass: ''
    },
    methods: {
      _tap(e) {
        this.triggerEvent('minitap', e)
      }
    }

声明一个类,svgIcon类来处理相关方法。

class SVGCON {
  constructor() {}

  svgXml(n, c) {
    let name = n;
    let data = "";
    let casualData = this[name]();
    let newArray = [];
    let color = "black";
    let newFill = "";
    // 颜色转换
    if (c && c.indexOf("#") >= 0) {
      color = c.replace("#", "%23");
    } else if (c) {
      color = c;
    }
    newFill = "fill=" + "'" + color + "'";
    // 更新颜色,加入fill=color(svg去掉fill=color相关代码)
    // 查找svg中的path数量
    newArray = casualData.split("></path>");
    casualData = "";
    for (let i = 0; i < newArray.length; i++) {
      if (i == newArray.length - 1) {
      } else {
        newArray[i] = newArray[i] + " " + newFill + "></path>";
      }
      casualData = casualData + newArray[i];
    }

    // 转换成svg+xml
    data = casualData;
    data = data.replace("<", "%3C");
    data = data.replace(">", "%3E");
    data = "data:image/svg+xml," + data;
    //双引号展示不出来,需要转换成单引号
    data = data.replace(/\"/g, "'");

    return data;
  }

  plus() {
    // 加号
    return "svg文件代码";
  }
}
export { SVGCON };

接下来就是使用这个类

let newSvg = new SVGCON();

function svgNameSwtich(t){
    // 名字以-划分
    let name = t;
    let newArray = name.split('-');
    let switchName = '';
    for(let i = 0; i < newArray.length; i++){
        if(i != 0){
            let word = newArray[i];
            newArray[i] = word.substring(0,1).toUpperCase()+word.substring(1);
        }
        switchName = switchName + newArray[i]
    }
    return switchName;
}

export function svgIcon(t,c){
    let name = '';
    if(t){
        // t转换成对应的svg函数名
        name = svgNameSwtich(t);
        return newSvg.svgXml(name,c);
    }
}

export function iconClassName(t){
    let classType = t;
    let className = '';
    switch (classType){
        case 'loading':
            className = 'm-icon-loading'
            break;
        default:
            break;
    }
    return className;
}