介绍原始写法 & 及其改进写法一
还有比较流行的 styled-components在RN中的使用 & 及其改进写法二
1.原写法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
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);
|
原写法的缺点在于变量不好引入,不好体现样式间的关系,没有计算表达式等……
2.改进写法一
看StyleSheet.create的代码,就是直接返回一个对象
1 2 3 4 5
| var StyleSheet = { create: function(styles) { return styles; },
|
那就可以不限于StyleSheet.create的写法,可以比较自由的返回一个对象了,下面给出一个我的简单例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
|
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();
console.log('style2 :',style2);
|
运行一下可以看到 log出来的style2和style1的属性。
3. styled-components
号称React 中的 CSS 最佳实践,使用行内样式,支持CSS。该第三方也也可用于RN。
react-native init
了个RN工程 写了个简单的例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
| import React, {Component} from 'react'; import { AppRegistry, StyleSheet, Text, View, Image } from 'react-native';
import styled from "styled-components/native";
const ListContainerView = styled.View` width:360; height:280; background-color: #F0F2F5; `;
const ItemContainerView = ListContainerView.extend` backgroundColor: #66CCFF; flexDirection:row; `;
const LeftImageContainerView = styled.View` height:${props => props.primary ? 280 : 180};; width:180; background-color: #77BB00; `;
const LeftImageHeight = 280 - 10 *2; const LeftImage = styled.Image` margin-top:10; margin-left:10; width:${180 - 10 *2}; height:${LeftImageHeight}; background-color: #FFFFFF; `;
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);
|
优点:
- react推荐的行内样式 css in js;
- 方便前端同学的写法 可以完全使用CSS的书写习惯
缺点和原始写法的差不多,还对本身不是前端开发的人来说带来额外的学习成本…… 所以还是不推荐……
参考链接:
4.改进写法二
简单来讲 styled-components 就是生成一个带样式的组件,完全可以吸收这种写法 自己改进RN中 ,而不使用styled-components这个库
结合 写法一 和 styled-components的想法,给出一个简单例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
| 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 styled = (Component, styler) => (props) => { const style = typeof styler === 'function' ? styler(props) : styler; return <Component {...props} style={[ style, props.style ]} /> }
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写法。
5. react native 0.45
在0.45版本中运行改进写法一时,你可能看到style2在控制台的输出类似为:
1 2 3 4 5 6 7 8 9 10 11
|
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改成:
1 2 3 4 5 6 7 8 9
| 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; },
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| 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,就可以这样做:
1 2 3
| 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就可以取得样式对象了。这可能对于之前的改进写法造成了一点小麻烦,不过还可以用~
其他参考阅读: