问题描述
使用自定义SVG图标时希望设置图标的宽高等属性,在 Ant Design Vue 的文档中找到如下描述:
Icon
中的component
组件的接受的属性如下
注意这里是 component
的属性,而不是 Icon
的属性,所以加到 Icon
标签上并不起作用,后面会有测试结果。
我对 Vue.js
还处于刚入门的水平,不知道这里是不是有一种语法可以给这个 component
设置参数,所以只能按自己的想法胡乱做了一些尝试,果然都不起作用。还望各位大佬不吝赐教。
相关代码
<template>
<a-icon :component="logo" class="logo" />
</template>
<script>
import Vue from "vue";
import { Icon } from "ant-design-vue";
import LogoSvg from "@/assets/logo.svg";
Vue.use(Icon);
Vue.component("logo-svg", LogoSvg);
export default {
name: "MainFrame",
data() {
return {
logo: "logo-svg"
};
}
};
</script>
输出结果:
<i data-v-65cc6c6a="" class="logo anticon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class="">...</svg>
</i>
你期待的结果
<i data-v-65cc6c6a="" class="logo anticon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="56" height="56" fill="currentColor" aria-hidden="true" focusable="false">...</svg>
</i>
自己尝试过哪些方法
方法一 将属性加到 Icon
标签上
<a-icon :component="logo" class="logo" :width="56" :height="56" />
输出结果:
<i data-v-65cc6c6a="" class="logo anticon" width="56" height="56">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class="">...</svg>
</i>
属性添加到了Icon标签上,并未出现在svg标签上。
方法二 直接使用 SVG
,不使用 Icon
<logo-svg class="logo" :width="56" :height="56" />
输出结果:
<svg data-v-65cc6c6a="" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="56" height="56" class="logo">...</svg>
原有属性被覆盖,表明属性本身是有效的。
方法三 重新定义一个组件对 svg
做一次封装
Vue.component("my-logo", {
render: h =>
h("logo-svg", {
attrs: {
width: 56,
height: 56,
foo: "bar"
}
})
});
export default {
name: "MainFrame",
data() {
return {
logo: "my-logo"
};
}
};
输出结果:
<i data-v-65cc6c6a="" class="logo anticon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="1em" height="1em" foo="bar" class="" fill="currentColor" aria-hidden="true" focusable="false">...</svg>
</i>
新增的属性 foo: "bar"
出现在了 svg
标签中,但 width
和 height
未能覆盖原有值。
应该是需要透传。也就是外侧组件先要接收width和height在传给内部组件:
<template>
// AIcon接收宽高
<a-icon :component="my-logo" :width="56" :height="56" class="logo" />
</template>
<script>
// AIcon在渲染时会自动将width,height, fill, class属性注入在子组件上,你要做的就是在子组件中接收这些参数,并正确赋值
Vue.component("my-logo", {
template: `<svg :with="{{width}}" height="{{height}}">...</svg>`,
data() {
// 接收width,height
return {
width:this.$options.width,
height: this.$options.height,
}
}
});
export default {
name: "MainFrame",
data() {
return {
logo: "my-logo",
};
}
};
</script>
###
把 Icon
的源码翻出来看了一下,逻辑不是太复杂。看起来并没有可以设置 component
属性的设计,反而是用一套默认设置对 component
的属性进行了覆盖,这也是为什么方法三得到那样结果的原因。
核心的代码如下:
// 默认属性
export var svgBaseProps = {
width: '1em',
height: '1em',
fill: 'currentColor',
'aria-hidden': 'true',
focusable: 'false'
};
// 合并出完整参数
var innerSvgProps = {
attrs: _extends({}, svgBaseProps, {
viewBox: viewBox
}),
'class': svgClassString,
style: svgStyle
};
// 渲染时传入参数,对svg原有参数进行覆盖
if (Component) {
return h(
Component,
innerSvgProps,
[children]
);
}
所以在当前版本下应该是无法修改内部 component
的参数。
我也遇到了同样到问题,但是看了vue-svg-loader的仓库的Example usage问题解决了
仓库地址:https://www.npmjs.com/package...