介绍原始写法 & 及其改进写法一css
还有比较流行的 styled-components在RN中的使用 & 及其改进写法二前端
/** * 原写法 */
const styles1 = StyleSheet.create({
item1:{
width:100,
height:200,
backgroundColor:'#66CCFF',
},
item2:{
width:100,
height:200,
backgroundColor:'#66CCFF',
},
item3:{
width:50,
height:100,
top:50,
left:25,
backgroundColor:'#66CCFF',
}
});
console.log('styles1 :',styles1);
复制代码
原写法的缺点在于变量很差引入,很差体现样式间的关系,没有计算表达式等……node
看StyleSheet.create的代码,就是直接返回一个对象react
//在react native 0.44版本中
var StyleSheet = {
create: function(styles) {
return styles;
},
复制代码
那就能够不限于StyleSheet.create的写法,能够比较自由的返回一个对象了,下面给出一个个人简单例子:git
/** * 换一种写法,简单引入了变量表达式 * 虽然仍是没有像iOS中 view.center / autolayout之类的写法方便 * @returns {{}} */
function styles2Creator() {
let s = {};
let itemWidth = 100;
let itemHeight = 200;
//引用常量
s.item1 = {
width:itemWidth,
height:itemHeight,
backgroundColor:'#66CCFF',
};
//引用其余样式的值
s.item2 = {
width:s.item1.width,
height:itemHeight,
backgroundColor:`${s.item1.backgroundColor}`,
};
//计算表达式
s.item3 = {
width: s.item2.width / 2,
height: s.item2.height / 2,
top:s.item2.height / 4,
left:s.item2.width / 4,
backgroundColor:s.item1.backgroundColor,
};
//样式的继承
s.item4 = {
...s.item3,
backgroundColor:'#FF00CC',
};
//带参数
s.item5 = (top) => {
return {
...s.item3,
marginTop:top,
};
};
//带参数 + 缺省值
s.item6 = (top) => {
return {
...s.item3,
marginTop:top ? top : 10,
};
}
return s;
}
const style2 = styles2Creator();
//const style2 = StyleSheet.create(styles2Creator());
console.log('style2 :',style2);
复制代码
运行一下能够看到 log出来的style2和style1的属性。github
号称React 中的 CSS 最佳实践,使用行内样式,支持CSS。该第三方也也可用于RN。npm
react-native init
了个RN工程 写了个简单的例子:react-native
import React, {Component} from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
Image
} from 'react-native';
//须要 `npm install --save styled-components`
import styled from "styled-components/native";
//这里开始styled-components 式的样式:
//styled-components的格式为: const [自定义变量名] = styled.[相应的系统组件]`css表达式`;
//普通写法 (不大写开头会报错……
const ListContainerView = styled.View` width:360; height:280; background-color: #F0F2F5; `;
//扩展 (backgroundColor 和 background-color均可以
const ItemContainerView = ListContainerView.extend` backgroundColor: #66CCFF; flexDirection:row; `;
//带参数
const LeftImageContainerView = styled.View` height:${props => props.primary ? 280 : 180};; width:180; background-color: #77BB00; `;
//而后发现一个尴尬的事就是不知道怎么扩展自定义组件 好比JDImage
//带计算表达式
const LeftImageHeight = 280 - 10 *2;
const LeftImage = styled.Image` margin-top:10; margin-left:10; width:${180 - 10 *2}; height:${LeftImageHeight}; background-color: #FFFFFF; `;
//想要获取另外一个组件样式LeftImage的高度 不能直接使用 ${LeftImage.height}
//由于 LeftImage返回的是 ƒ StyledNativeComponent()方法……
const RightContainerView = styled.View` width:160; height:${LeftImageHeight}; background-color: #FF00CC; `;
export default class MyApp extends Component {
render() {
return (
<ItemContainerView > <LeftImageContainerView primary> {console.log('LeftImageContainerView.style:',LeftImageContainerView)} <LeftImage source={{uri:'http://static.runoob.com/images/demo/demo2.jpg'}}/> </LeftImageContainerView> <RightContainerView></RightContainerView> </ItemContainerView> ); } } AppRegistry.registerComponent('MyApp', () => MyApp); 复制代码
优势:sass
缺点和原始写法的差很少,还对自己不是前端开发的人来讲带来额外的学习成本…… 因此仍是不推荐……less
参考连接:
简单来说 styled-components 就是生成一个带样式的组件,彻底能够吸取这种写法 本身改进RN中 ,而不使用styled-components这个库
结合 写法一 和 styled-components的想法,给出一个简单例子:
import React, {Component} from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
Image
} from 'react-native';
//写法二
function stylesCreator() {
let s = {};
let width = 360.0, height = 280.0;
s.ListContainerView = {
width: width,
height: height,
backgroundColor: '#F0F2F5',
};
s.ItemContainerView = {
width: width,
height: height,
backgroundColor: '#66CCFF',
flexDirection:'row',
};
console.log('s.ItemContainerView :',s.ItemContainerView);
s.LeftImageContainerView = {
height:height,
width:width / 2,
backgroundColor: '#77BB00',
};
s.LeftImage = {
marginTop:10,
marginLeft:10,
width: 180 - 10 *2,
height: s.LeftImageContainerView.height - 10*2,
backgroundColor: `#FFFFFF`,
};
s.RightContainerView = {
width: width / 2,
height: s.LeftImage.height,
backgroundColor: '#FF00CC',
};
return s;
}
const styles = stylesCreator();
//const styles = StyleSheet.create(stylesCreator());
//而后再结合 styled-components:
// 模拟 styled-components API
const styled = (Component, styler) => (props) => {
const style = typeof styler === 'function' ? styler(props) : styler;
return <Component {...props} style={[ style, props.style ]} />
}
// styled components
//一样能够完成组件(带样式)的继承 const RightContainerView = styled(LeftImageContainerView,styles.RightContainerView);
const ListContainerView = styled(View,styles.ListContainerView);
const ItemContainerView = styled(View,styles.ItemContainerView);
const LeftImageContainerView = styled(View,styles.LeftImageContainerView);
const LeftImage = styled(Image,styles.LeftImage);
const RightContainerView = styled(View,styles.RightContainerView);
export default class MyApp extends Component {
render() {
return (
<ItemContainerView >
<LeftImageContainerView primary>
{console.log('LeftImageContainerView.style:',LeftImageContainerView)}
<LeftImage source={{uri:'http://static.runoob.com/images/demo/demo2.jpg'}}/>
</LeftImageContainerView>
<RightContainerView></RightContainerView>
</ItemContainerView>
);
}
}
AppRegistry.registerComponent('MyApp', () => MyApp);
复制代码
emmm ,无需引入第三方库 感受好多了。缺点固然是不支持原CSS写法。
在0.45版本中运行改进写法一时,你可能看到style2在控制台的输出相似为:
//const style2 = StyleSheet.create(styles2Creator());
style2 :
{item1: 12, item2: 13, item3: 14, item4: 15, item5: 16, …}
item1:12
item2:13
item3:14
item4:15
item5:16
item6:17
__proto__:Object
复制代码
这是怎么肥事!个人item对象怎么变成数字了!
别急,在0.45版本后StyleSheet代码有所改变(其实我没看具体哪一个小版本改的 _(:зゝ∠)_
), StyleSheet.create改为:
//react native : 0.45.1
create<S: Styles>(obj: S): StyleSheet<S> {
const result: StyleSheet<S> = {};
for (var key in obj) {
StyleSheetValidation.validateStyle(key, obj);
result[key] = ReactNativePropRegistry.register(obj[key]);
}
return result;
},
复制代码
//react native0.45.1 ReactNativePropRegistry.js
var objects = {};
var uniqueID = 1;
var emptyObject = {};
class ReactNativePropRegistry {
static register(object: Object): number {
var id = ++uniqueID;
if (__DEV__) {
Object.freeze(object);
}
objects[id] = object;
return id;
}
//多的就不看了……内容很少各位有兴趣本身看
复制代码
经过看ReactNativePropRegistry代码,StyleSheet将样式对象储存在objects
中,并返回uniqueID
好比取回原来的item,就能够这样作:
import ReactNativePropRegistry from '../node_modules/react-native/Libraries/Renderer/src/renderers/native/ReactNativePropRegistry';
console.log("ReactNativePropRegistry.getByID(12): ",ReactNativePropRegistry.getByID(12));
console.log("ReactNativePropRegistry.getByID(style2. item1): ",ReactNativePropRegistry.getByID(style2. item1));
复制代码
就能够经过 ReactNativePropRegistry.getByID就能够取得样式对象了。这可能对于以前的改进写法形成了一点小麻烦,不过还能够用~
还能够用 StyleSheet.flatten(style )取得样式对象;
其余参考阅读: