解决VUE3使用Ant-Design的图标组件<a-icon>使用报错,自己做个<b-icon>

浏览器控制台报错:不识别a-icon

网上推荐使用循环遍历每一个组件,进行注册

在main.js写这个循环,多少有点奇怪

并且我在下方这行代码就已经报错了,不太懂这个语法。

const  icons: any = Icons;

 一筹莫展之际,我决定自己写一个a-icon组件。

<template>
  <span ref="icon" v-html="code" style="font-size: 25px;overflow:hidden;"></span>
</template>

<script>
export default {
  name: "AIcon",
  props: {
    type: String,
    theme: String,
    line:String,//双色图标的线条颜色,使用主题为双色图标时才有效
    fill:String,//双色图标的填充颜色,使用主题为双色图标时才有效
    component:String,
  },
  data() {
    return {
      code: "",
      path: "",
    }
  },
  methods: {
    /**
     * 更新svg属性,同步span的长度,高度,颜色,根据需要自行添加
     * @param code
     * @returns {string|*}
     */
    updateAttributes(code){
      let span=this.$refs.icon;
      if(code.indexOf('style="')<0){
        code=this.insertCode(code,'<svg ',`style="width:${span.style.fontSize};height:${span.style.fontSize};"`)
      }else{
        code=this.insertCode(code,'style="',`width:${span.style.fontSize};height:${span.style.fontSize};`)
      }

      let color="";
      if(this.theme==='twoTone'){
        if(this.line!=null){
          code=code.replaceAll('fill="#333"','fill="'+this.line+'"');
        }else{
          code=code.replaceAll('fill="#333"','fill="#1890ff"');
        }

        if(this.fill!=null){
          code=code.replaceAll('fill="#E6E6E6"','fill="'+this.fill+'"');
        }else{
          code=code.replaceAll('fill="#E6E6E6"','fill="#e6f7ff"');
        }
        return code;
      }else if(span.style.color==null){
        color='#ffffff';
      }else if(span.style.color.length<1){
        color='#ffffff';
      }else{
        color=span.style.color;
      }
      return code.replaceAll("<path",`<path fill="${color}"`);
    },
    /**
     * 指定代码后面插入需要的代码
     * @param text
     * @param str
     * @param insert
     * @returns {string}
     */
    insertCode(text,str,insert){
      let p=text.indexOf(str);
      return text.substring(0,p+str.length)+" "+insert+" "+text.substring(p+str.length,text.length);
    }
  },
  mounted() {
    //如果有自定义svg代码,就展示自定义svg图形
    if(this.component!=null){
      this.code=this.updateAttributes(this.component);
    }else{
      //主题其实就是svg路径,没有主题,默认就是这个线条的svg
      if (this.theme == null || this.theme.length < 1) this.path = "outlined";
      else this.path = this.theme;
      //通过下载指定路径svg资源代码,进行处理
      this.$axios({
        method: 'get',
        url: require("@ant-design/icons-svg/inline-namespaced-svg/" + this.path.toLowerCase() + "/" + this.type + ".svg")
      }).then((response) => {
        this.code=this.updateAttributes(response.data);
      });
    }

  }


}
</script>

<style scoped>


</style>

在main.js引入这个组件,作为全局组件即可,

import AIcon from './components/AIcon'
const app = createApp(App);
app.component("a-icon",AIcon);

代码中正常使用即可

  <a-icon type="menu" style="color: #ffffff;font-size:22px;"/>
  <a-icon type="up-circle" theme="twoTone" />
  <a-icon type="right-circle" theme="twoTone" />
  <a-icon type="up-square" theme="twoTone" />

 就长这样子,效果差不太多,哈哈哈哈,目前根据需要,只实现了type、theme、component这三个属性

另外可以通过设置<a-icon >的style样式:

a-icon的font-size会转换为svg图形的width,height

a-icon的color会转换为svg图形的fill属性

对于双色图标,这里给组件增加了两个属性:

line="#000000"  设置双色图标的线条颜色

fill="#FFFFFF"  设置双色图标的填充颜色

默认为ant-design的网站展示原色。

根据需要可以自己再开发一些功能

2022/5/14 更新

之前写的a-icon用起来不是很舒服,因为<span>的默认布局,毕竟还是比不上img,还需要很多css代码来调整,于是乎,找到了一种把svg代码放入img中展示的操作。比上一版的更好用些。代码如下:

<template>
  <img ref="icon"  :src="code">
</template>

<script>
import icons from "@/view/desktop/icons";
export default {
  name: "BIcon",
  props: {
    local:String,
    type: String,
    theme: String,
    line:String,//双色图标的线条颜色,使用主题为双色图标时才有效
    fill:String,//双色图标的填充颜色,使用主题为双色图标时才有效
    component:String,
  },
  data() {
    return {
      icons:null,
      code: "",
      path: "",
    }
  },
  created() {
    this.icons=icons;
  },
  methods: {
    getCode() {
      if (this.code === "") return "";
      let b64 = window.btoa(unescape(encodeURIComponent(this.code)));
      return "data:image/svg+xml;base64," + b64;
    },


    /**
     * 更新svg属性,同步span的长度,高度,颜色,根据需要自行添加
     * @param code
     * @returns {string|*}
     */
    updateAttributes(code){
      let span=this.$refs.icon;
      let color="";
      if(this.theme==='twoTone'){
        if(this.line!=null){
          code=code.replaceAll('fill="#333"','fill="'+this.line+'"');
        }else{
          code=code.replaceAll('fill="#333"','fill="#1890ff"');
        }

        if(this.fill!=null){
          code=code.replaceAll('fill="#E6E6E6"','fill="'+this.fill+'"');
        }else{
          code=code.replaceAll('fill="#E6E6E6"','fill="#e6f7ff"');
        }
        return code;
      }else if(span.style.color==null){
        return code;
      }else if(span.style.color.length<1){
        return code;
      }else{
        color=span.style.color;
      }
      return code.replaceAll("<path",`<path fill="${color}"`);
    },
    /**
     * 指定代码后面插入需要的代码
     * @param text
     * @param str
     * @param insert
     * @returns {string}
     */
    insertCode(text,str,insert){
      let p=text.indexOf(str);
      return text.substring(0,p+str.length)+" "+insert+" "+text.substring(p+str.length,text.length);
    }
  },
  mounted() {
    if(this.local!=null&&this.local.length>0){
      this.code=this.updateAttributes(this.icons[this.local]);
      this.code=this.getCode();
    }else if(this.component!=null){//如果有自定义svg代码,就展示自定义svg图形
      this.code=this.updateAttributes(this.component);
      this.code=this.getCode();
    }else{
      //主题其实就是svg路径,没有主题,默认就是这个线条的svg
      if (this.theme == null || this.theme.length < 1) this.path = "outlined";
      else this.path = this.theme;
      //通过下载指定路径svg资源代码,进行处理
      this.$axios({
        method: 'get',
        url: require("@ant-design/icons-svg/inline-namespaced-svg/" + this.path.toLowerCase() + "/" + this.type + ".svg")
      }).then((response) => {
        this.code=this.updateAttributes(response.data);
        this.code=this.getCode();
      });
    }


  }


}
</script>

<style scoped>

</style>

新增一个小功能,引入自定义的svg代码

创建一个js文件,格式如下:

export default {
    user_icon: `<svg>.....................</svg>` ,
    text_icon: `<svg>.....................</svg>` ,
}

在b-icon中引入,于是乎,这样用

     <b-icon  local="text_icon" ></b-icon>

当前,也需要在main.js文件中引入b-icon

app.component("b-icon",BIcon);

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值