使用作用域 CSS 创建 SVG 组件



我正在创建将渲染出各种SVG的React组件:

const Close = ({
fill, width, height, float,
}) => (
<svg width={ `${width}px` } height={ `${height}px` } viewBox="0 0 14.48 14.48" style={ { float: `${float}`, cursor: 'pointer' } }>
<title>x</title>
<g id="Layer_2" data-name="Layer 2">
<g id="Background">
<line style={ { fill: 'none', stroke: `${fill}`, strokeMiterlimit: 10 } } x1="14.13" y1="0.35" x2="0.35" y2="14.13" />
<line style={ { fill: 'none', stroke: `${fill}`, strokeMiterlimit: 10 } } x1="14.13" y1="14.13" x2="0.35" y2="0.35" />
</g>
</g>
</svg>
);

能够提供各种归因于此组件的组件以控制尺寸、颜色等非常方便......

然而,我没有一个好的解决方案是以 DRY 的方式处理样式。请注意,line元素对style具有相同的值。我目前将它们内联编写,因为如果我添加嵌入式样式表,那么我会与我在页面上其他地方渲染的其他 SVG 发生类名冲突(我们的 SVG 软件一遍又一遍地使用相同的类(。

<style scoped>已从规范中删除:https://github.com/whatwg/html/issues/552

Edge: https://caniuse.com/#feat=shadowdomv1 尚不支持 Shadow DOM

。范围样式还有其他选择吗?

为了结合两全其美,您可以创建一个外部样式文件,就像对 CSS 一样,但使用导出的样式对象。然后,您可以将其导入到需要它的任何文件中。

例如,主文件:

import React, { Component } from 'react';
import { render } from 'react-dom';
import * as Styles from './svgstyles';
class App extends Component {
render() {
return (
<div>
<svg width="100" height="200" viewBox="0 0 100 200">  
<rect x="0" y="0" width="10" height="10" style={Styles.style1} />
<rect x="15" y="0" width="10" height="10" style={Styles.style2} />
<rect x="30" y="0" width="10" height="10" style={Styles.style3} />
<rect x="45" y="0" width="10" height="10" style={Styles.style4} />
<rect x="0" y="15" width="10" height="10" style={Styles.style4} />
<rect x="15" y="15" width="10" height="10" style={Styles.style3} />
<rect x="30" y="15" width="10" height="10" style={Styles.style2} />
<rect x="45" y="15" width="10" height="10" style={Styles.style1} />
</svg>
</div>
);
}
}
render(<App />, document.getElementById('root'));

还有一个外部样式文件:

export const style1 = {
stroke: 'red',
strokeWidth: "1",
fill: "blue",
}
export const style2 = {
stroke: 'red',
strokeWidth: "1",
fill: "green",
}
export const style3 = {
stroke: 'red',
strokeWidth: "1",
fill: "yellow",
}
export const style4 = {
...style3,
fill: "pink",
}

现场示例在这里

如果你只是想干掉代码,你可以创建一个样式对象并重用它:

const Close = ({
fill, width, height, float,
}) => {
const style = { fill: 'none', stroke: `${fill}`, strokeMiterlimit: 10 }
return (
<svg width={ `${width}px` } height={ `${height}px` } viewBox="0 0 14.48 14.48" style={ { float: `${float}`, cursor: 'pointer' } }>
<title>x</title>
<g id="Layer_2" data-name="Layer 2">
<g id="Background">
<line style={ style } x1="14.13" y1="0.35" x2="0.35" y2="14.13" />
<line style={ style } x1="14.13" y1="14.13" x2="0.35" y2="0.35" />
</g>
</g>
</svg>
);
}

这也会导致性能的小幅提高,因为在每个渲染周期中创建的对象更少。

实际上,如果我在你的位置上,我当然使用字体而不是 SVG,但对于您的确切问题,我更喜欢在我的箭头函数中使用常量变量,如下所示:

import React from 'react';
const Close = ({ fill, width, height, float }) => {
const constStyle = { fill: 'none', stroke: `${fill}`, strokeMiterlimit: 10 };
return (
<svg
width={`${width}px`}
height={`${height}px`}
viewBox="0 0 14.48 14.48"
style={{ float: `${float}`, cursor: 'pointer' }}
>
<title>x</title>
<g id="Layer_2" data-name="Layer 2">
<g id="Background">
<line style={constStyle} x1="14.13" y1="0.35" x2="0.35" y2="14.13" />
<line style={constStyle} x1="14.13" y1="14.13" x2="0.35" y2="0.35" />
</g>
</g>
</svg>
);
};
export default Close;

甚至,我将线尺寸变量设为props,但我不知道您的情况到底是什么。

希望这个答案对你有帮助。

最新更新