实现思路,将svg的html字符串的URI编码,作为view的背景图。无需任何插件。

  1. 封装svg资源。新建文件夹assets,在assets文件夹下新建svg文件夹用于放置svg文件,在assets文件夹下新建svg.js用于放置svg的html字符串。
icon——svg——aaabbb.svg
    |——svg.js
svg.js

function Svg2DataUrl (svg) {
  // 将被设置到 dataset 中的属性还原出来
  svg = svg.replace(/data-(.*?=(['"]).*?\2)/g, '$1');

  // 将被设置到 data-xlink-href 的属性还原出来
  svg = svg.replace(/xlink-href=/g, 'xlink:href=');

  // 将 dataset 中被变成 kebab-case 写法的 viewBox 还原出来
  svg = svg.replace(/view-box=/g, 'viewBox=');

  // 清除 SVG 中不应该显示的 title、desc、defs 元素
  svg = svg.replace(/<(title|desc|defs)>[\s\S]*?<\/\1>/g, '');

  // 为非标准 XML 的 SVG 添加 xmlns,防止视图层解析出错
  if (!/xmlns=/.test(svg)) svg = svg.replace(/<svg/, "<svg xmlns='http://www.w3.org/2000/svg'");

  // 对 SVG 中出现的浮点数统一取最多两位小数,缓解数据量过大问题
  svg = svg.replace(/\d+\.\d+/g, (match) => parseFloat(parseFloat(match).toFixed(2)));

  // 清除注释,缓解数据量过大的问题
  svg = svg.replace(/<!--[\s\S]*?-->/g, '');

  // 模拟 HTML 的 white-space 行为,将多个空格或换行符换成一个空格,减少数据量
  svg = svg.replace(/\s+/g, " ");

  // 对特殊符号进行转义,这里参考了 https://github.com/bhovhannes/svg-url-loader/blob/master/src/loader.js
  svg = svg.replace(/[{}\|\\\^~\[\]`"<>#%]/g, function (match) {
    return '%' + match[0].charCodeAt(0).toString(16).toUpperCase();
  });

  // 单引号替换为 \',由于 kbone 的 bug,节点属性中的双引号在生成 outerHTML 时不会被转义导致出错
  // 因此 background-image: url( 后面只能跟单引号,所以生成的 URI 内部也就只能用斜杠转义单引号了
  svg = svg.replace(/'/g, "\\'");

  // 最后添加 mime 头部,变成 Webview 可以识别的 Data URI
  return '"data:image/svg+xml,' + svg.trim() + '"';
}

// 已挂载到vue.$svg

export default {
  aaabbb: Svg2DataUrl('\
  <svg id="" data-name="" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">\
    <rect id="矩形_5315" data-name="矩形 5315" width="20" height="20" fill="none" opacity="0.1"/>\
    <path id="" d="M139." fill="#000"/>\
  </svg>\
  ')
}

并且将svg.js导出的对象挂载到全局,便于全局使用

main.js

import svg from '@/assets/svg.js'
Vue.prototype.$svg = svg

至此svg资源便已经封装好。

2.封装svg换色函数

globalMethods.js

// svg更换颜色
  changeSvgColor (url, color) {
    //转义后的#等于%23,利用正则表达式,替换所有%23后6位为新的十六进制六位数。
    let res = url.replace(/%22%23[a-zA-Z0-9]{3,6}/g, color.replace("#", "%22%23"))
    return res
  }

并将其挂载到全局函数

main.js

import globalMethods from '@/utils/globalMethods.js'
Vue.prototype.$gm = globalMethods

3.封装svg组件。在components文件夹下新建 components\cus-svg\cus-svg.vue 组件。

<template>
  <view class="icon" :style="[style]"></view>
</template>

<script>
export default {
  props: {
    icon: {
      type: String,
      default: '',
    },
    size: {
      type: String,
      default: '30',
    },
    color: { // 16进制
      type: String,
      default: '#999',
    }
  },
  computed: {
    style () {
      return {
        width: `${this.size}rpx`,
        height: `${this.size}rpx`,
        backgroundImage: `url(${this.$gm.changeSvgColor(this.$svg[this.icon], this.color)})`
      }
    }
  }
}
</script>

<style lang="scss" scoped>
.icon {
  background-size: contain;
  background-repeat: no-repeat;
}
</style>

最后就可以使用啦

<cus-svg :color="['#a2aab1', '#0081ff', '#e5383b', '#a2aab1'][item.status]" class="icon" icon="grantAuth" size="33" />
Logo

前往低代码交流专区

更多推荐