如何组合多个内联样式对象?

Posted

技术标签:

【中文标题】如何组合多个内联样式对象?【英文标题】:How to combine multiple inline style objects? 【发布时间】:2015-07-10 20:09:20 【问题描述】:

在 React 中,您可以清楚地创建一个对象并将其指定为内联样式。即下面提到的。

var divStyle = 
  color: 'white',
  backgroundImage: 'url(' + imgUrl + ')',
  WebkitTransition: 'all', // note the capital 'W' here
  msTransition: 'all' // 'ms' is the only lowercase vendor prefix
;

var divStyle2 = fontSize: '18px';

React.render(<div style=divStyle>Hello World!</div>, mountNode);

如何组合多个对象并将它们分配在一起?

【问题讨论】:

【参考方案1】:

如果你使用 React Native,你可以使用数组表示法:

<View style=[styles.base, styles.background] />

查看我的详细信息blog post。

【讨论】:

遗憾的是,您不能在常规 React 中执行此操作。 如果您使用的是 React-Native,这应该是公认的答案 您可以通过添加样式名称/值来稍微修改现有的内联样式。例如,&lt;View style=this.state.error == false ? styles.base : [styles.base, backgroundColor: 'red'] /&gt; 对于两种静态样式,在渲染函数之外执行StyleSheet.compose() 可能更有效。它将生成一个新的静态样式表,该样式表只会通过网桥发送一次。 (此建议不适用于在运行时更改的样式,或者内联而不是样式表中的样式。)【参考方案2】:

您可以使用扩展运算符:

 <button style=...styles.panel.button,...styles.panel.backButton>Back</button

【讨论】:

我收到“语法错误:意外标记”,指向第一个展开运算符中的第一个点。 @Izkata 你是在 react 还是 react native 中这样做,你能发布你的 sn-p React,类似于&lt;div style= ...LEGEND_STYLE.box_base, ... 'background': '#123456' /&gt; 无论如何我都将其更改为使用像 &lt;div style=LEGEND_STYLE.box_gen('#123456') 这样的辅助函数,所以对我来说没什么大不了的 即使对象只有一个键值对也可以使用,即使扩展运算符只对可迭代对象有效!你能解释一下为什么吗? developer.mozilla.org/en-US/docs/Web/javascript/Reference/…【参考方案3】:

您可以使用Object.assign() 来做到这一点。

在你的例子中,你会这样做:

ReactDOM.render(
    <div style=Object.assign(divStyle, divStyle2)>
        Hello World!
    </div>,
    mountNode
);

这将合并两种样式。如果有匹配的属性,第二个样式将替换第一个样式。

正如 Brandon 所说,如果您想在不应用 fontSize 的情况下重用 divStyle,则应该使用 Object.assign(, divStyle, divStyle2)

我喜欢用它来制作具有默认属性的组件。例如,这是一个带有默认 margin-right 的小无状态组件:

const DivWithDefaults = ( style, children, ...otherProps ) =>
    <div style=Object.assign( marginRight: "1.5em" , style) ...otherProps>
        children
    </div>;

所以我们可以这样渲染:

<DivWithDefaults>
    Some text.
</DivWithDefaults>
<DivWithDefaults className="someClass" style= width: "50%" >
    Some more text.
</DivWithDefaults>
<DivWithDefaults id="someID" style= marginRight: "10px", height: "20px" >
    Even more text.
</DivWithDefaults>

这会给我们结果:

<div style="margin-right:1.5em;">Some text.</div>
<div style="margin-right:1.5em;width50%;" class="someClass">Some more text.</div>
<div style="margin-right:10px;height:20px;" id="someID">Even more text.</div>

【讨论】:

此解决方案可能会滥用Object.assign(),从而导致一些不良后果。请参阅the answer here 一个更可靠的解决方案。 您的回答展示了一种滥用 Object.assign() 的方法。这对某些人来说可能是有用的信息,但不适用于我的示例。这个例子没有将默认值存储在对象中,对其进行变异,然后在其他地方重用变异的对象。 不同意。您在答案中解决了使用Object.assign() 的两种不同方式。第一个,在前几句话中,是我发现的滥用的一个例子(即,如果 OP 做了你在第一个 code 块中的建议,他/她会变异 divStyle)。第二种方式 - 即,将它包装在一个函数中,就像你拥有的那样,将起作用,但答案并没有明确表明你正在 解决 Object.assign() 的常见“问题” wrt 不变性(虽然我个人认为为每个默认组件编写自定义无状态函数有点麻烦)。 哦,好的。确实如此。如果他想在不应用 fontSize 的情况下重用 divStyle ,则首先需要空对象。我会更新答案。 Object.assign() 是迄今为止实现连接的最方便的方法:)【参考方案4】:

与 React Native 不同,我们不能在 React 中传递样式数组,比如

<View style=[style1, style2] />

在 React 中,我们需要在将样式传递给样式属性之前创建单个样式对象。喜欢:

const Header = (props) => 
  let baseStyle = 
    color: 'red',
  

  let enhancedStyle = 
    fontSize: '38px'
  

  return(
    <h1 style=...baseStyle, ...enhancedStyle>props.title</h1>
  );

我们使用 ES6 Spread operator 来组合两种样式。您也可以将Object.assign() 用于相同目的。

如果您不需要将样式存储在 var 中,这也可以使用

<Segment style=...segmentStyle, ...height:'100%'>
    Your content
</Segment>

【讨论】:

只是为了添加到您的最后一个 sn-p,...segmentStyle, height:'100%' 也可以。【参考方案5】:

Object.assign() 是一个简单的解决方案,但是(当前)top answer 的使用——虽然对于制作无状态组件来说很好,但会导致 OP 合并两个 state 对象的预期目标出现问题。

使用两个参数,Object.assign() 实际上会就地改变第一个对象,影响未来的实例化。

例如:

考虑一个盒子的两种可能的样式配置:

var styles =  
  box: backgroundColor: 'yellow', height: '100px', width: '200px',
  boxA: backgroundColor: 'blue',
;

所以我们希望我们所有的盒子都具有默认的“盒子”样式,但想用不同的颜色覆盖一些:

// this will be yellow
<div style=styles.box></div>

// this will be blue
<div style=Object.assign(styles.box, styles.boxA)></div>

// this SHOULD be yellow, but it's blue.
<div style=styles.box></div>

一旦Object.assign() 执行,'styles.box' 对象就会永久更改。

解决方案是将一个空对象传递给Object.assign()。这样做,您告诉该方法使用您传递的对象生成一个 NEW 对象。像这样:

// this will be yellow
<div style=styles.box></div>

// this will be blue
<div style=Object.assign(, styles.box, styles.boxA)></div>

// a beautiful yellow
<div style=styles.box></div>

这种对象就地变异的概念对于 React 至关重要,正确使用 Object.assign() 对于使用像 Redux 这样的库非常有帮助。

【讨论】:

您关于如何滥用 Object.assign 的示例并不是对(当前)最佳答案中如何使用 Object.assign 的有效表示。 谢谢,进行了编辑以反映(当前)哪个方面是滥用 那里有一段不错的代码。 Object.assign(, this.state.showStartOverBtn ? : this.hidden ,this.btnStyle) 条件句也很有效【参考方案6】:

Array notaion 是 React Native 中组合样式的最佳方式。

这显示了如何组合 2 个 Style 对象,

<Text style=[styles.base, styles.background] >Test </Text>

这显示了如何组合 Style 对象和属性,

<Text style=[styles.base, color: 'red'] >Test </Text>

这适用于任何 React Native 应用程序。

【讨论】:

问题是针对React,而不是React Native React 也可以使用相同的 React 从一开始就不支持数组,现在它不再工作了。 react 还不支持这样的组合样式。 不明白为什么这个响应有这么多的赞成票。回应题外话,这里我们谈论的是反应,而不是反应原生。 Reactjs 不支持此响应中所说的内容【参考方案7】:
    const style1 = 
        backgroundColor: "#2196F3", 
    
    
    const style2 = 
        color: "white", 
    

    const someComponent = () => 
        return <div style= ...style1, ...style2 >This has 2 separate styles</div> 
    
    

注意双花括号。传播运算符是您的朋友。

【讨论】:

绝对应该被接受为正确答案。救生员! 我同意@RobHern。这应该是公认的答案,它还允许添加其他内联样式,例如: style=...styles.title, color: backgroundDark ? "#fff" : "#000"【参考方案8】:

其实有一个正式的组合方式,如下所示:

<View style=[style01, style02] />

但是,有一个小问题,如果其中一个是由父组件传递的,并且它是通过组合形式的方式创建的,我们就有一个大问题:

// The passing style02 from props: [parentStyle01, parentStyle02]

// Now:
<View style=[style01, [parentStyle01, parentStyle02]] />

最后一行会导致 UI 错误,很明显,React Native 无法处理数组中的深层数组。所以我创建了我的辅助函数:

import  StyleSheet  from 'react-native';

const styleJoiner = (...arg) => StyleSheet.flatten(arg);

通过在任何地方使用我的styleJoiner,您可以组合任何类型的样式并组合样式。即使undefined 或其他无用的类型也不会破坏样式。

【讨论】:

【参考方案9】:

您还可以像这样将类与内联样式结合起来:

<View style=[className, paddingTop: 25]>
  <Text>Some Text</Text>
</View>

【讨论】:

不,你不能那样做。这里说的是Reactjs(注意react native),不明白为什么这么赞【参考方案10】:

我发现这对我最有效。它按预期覆盖。

return <View style=...styles.local, ...styles.fromProps />

【讨论】:

【参考方案11】:

需要合并对象中的属性。 例如,

const boxStyle = 
  width : "50px",
  height : "50px"
;
const redBackground = 
  ...boxStyle,
  background: "red",
;
const blueBackground = 
  ...boxStyle,
  background: "blue",





 <div style=redBackground></div>
 <div style=blueBackground></div>

【讨论】:

这绝对是聪明的。【参考方案12】:

对于那些在 React 中寻找这个解决方案的人,如果你想在样式中使用扩展运算符,你应该使用:babel-plugin-transform-object-rest-spread。

通过 npm 模块安装它并像这样配置你的 .babelrc:


  "presets": ["env", "react"],
  "plugins": ["transform-object-rest-spread"]

那你就可以用like...

const sizing =  width: 200, height: 200 
 <div
   className="dragon-avatar-image-background"
   style= backgroundColor: blue, ...sizing 
  />

更多信息:https://babeljs.io/docs/en/babel-plugin-transform-object-rest-spread/

【讨论】:

【参考方案13】:

所以基本上我看错了。据我所知,这不是一个特定于 React 的问题,更多的是一个关于如何将两个 JavaScript 对象组合在一起的 JavaScript 问题(不破坏类似命名的属性)。

在这个 *** 答案中,它解释了它。 How can I merge properties of two JavaScript objects dynamically?

在 jQuery 中,我可以使用 extend 方法。

【讨论】:

【参考方案14】:

为了扩展@PythonIsGreat 所说的内容,我创建了一个全局函数来为我做这件事:

var css = function()
    var args = $.merge([true, ], Array.prototype.splice.call(arguments, 0));
    return $.extend.apply(null, args);

这将对象深度扩展为一个新对象,并允许可变数量的对象作为参数。这允许您执行以下操作:

return(
<div style=css(styles.base, styles.first, styles.second,...) ></div>
);

var styles = 
  base:
    //whatever
  ,
  first:
    //whatever
  ,
  second:
    //whatever
  

【讨论】:

【参考方案15】:

为了更进一步,您可以创建一个类似classnames 的辅助函数:

const styleRules = (...rules) => 
  return rules.filter(Boolean).reduce((result, rule) => 
    return  ...result, ...rule ;
  , );
;

然后在你的组件中有条件地使用它:

<div style=

  styleRules(
    divStyle,
    (window.innerWidth >= 768) && divStyleMd,
    (window.innerWidth < 768) && divStyleSm
  )

>Hello World!</div>

【讨论】:

【参考方案16】:

内联样式的方式:

<View style=[styles.red, fontSize: 25]>
  <Text>Hello World</Text>
</View>

<View style=[styles.red, styles.blue]>
  <Text>Hello World</Text>
</View>

  <View style=fontSize:10,marginTop:10>
  <Text>Hello World</Text>
</View>

【讨论】:

React 从一开始就不支持数组,现在它不再工作了。 以上评论是正确的,这个答案只适用于 React Native。可以做类似的事情 - 像这样,React 确实支持。【参考方案17】:

如果您想根据条件添加样式,我已经为此构建了一个模块 像这样:

multipleStyles(styles.icon,  [styles.iconRed]: true )

https://www.npmjs.com/package/react-native-multiple-styles

【讨论】:

【参考方案18】:

在 React 中有多种内联样式。

<div onClick=eleTemplate style='width': '50%', textAlign: 'center'/>

【讨论】:

这是通过什么方式提供多种样式的? 样式接受花括号内的对象,因此您可以将所有样式作为一个对象并将其分配给一个变量,如下所示。 const combineStyles = 'width': '50%', textAlign: 'center'

以上是关于如何组合多个内联样式对象?的主要内容,如果未能解决你的问题,请参考以下文章

Vue绑定class与绑定内联样式--v-bind

如何为多个条件编写内联 ng 样式

如何沿同一垂直线对齐多个标记的内联块输入控件? [关闭]

vue中内联样式

什么是内联对象

JS获取内联样式