更新: 2017-06-19
新添加方法2 :
更新: 2017-06-23
简单封装 :
更新: 2017-07-03
发现需要使用的地方比较多, 最后封装成函数 :
-现-在的项目使用的是react-native
结合ant-Design- mobile
,
但是发现有些组件样式不好调,尤其是嵌套很多层的子组件的字体,颜色,
官方使用style={}
作为props
的方式传递, 但是嵌套很多层的子组件的部分样式没起作用(不知道为什么), 而且react-native
中样式基本不具备继承性,除了Text
, (想了解的同学可以看大神陈学家的https://segmentfault.com/a/1190000002658374)
1: 先说下解决方法的弊端:
- 类似web端更改class样式, 只能单个组件的更改, 不能解决更改全局的样式,
(有想做一键切换主题更改全局样式的这个方法暂时不行, 如果大家发现好的方法,欢迎大家提出)
- 方法1 只可以在原有的样式对象上更改,不能添加新的样式对象,
更新的方法2 可以添加新的样式属性
2: 说下解决方法:
方法1:
举个例子: 比如我们现在需要ant-Design- mobile
组件中的SegmentedControl
home.js中引入组件SegmentedControl
// home.js
import { SegmentedControl } from 'antd-mobile';
....
....
....
render() {
return(
<View style={Global.container}>
<SegmentedControl
selectedIndex={this.state.selectedIndex}
values={this.segmentedLabel}
onChange={this.onChange}
/>
{this.renderList()}
</View>
);
}
发现字体太小,想调整样式按照组件给的方法, 使用 style= {[fomtStyle: 100]}
传入样式 , 没有反应,
解决办法思路如下:
- 1: 去
node_modules\antd-mobile\lib\segmented-control\index.android.js
中源码, 发现字体组件使用的样式是itemText对象
return _react2["default"].createElement(_reactNative.TouchableWithoutFeedback, { key: idx, onPress: function onPress(e) {
return _this2.onPress(e, idx, value);
} }, _react2["default"].createElement(_reactNative.View, { style: [_style2["default"].item, itemRadius, {
backgroundColor: idx === selectedIndex ? tintColor : '#fff',
borderColor: tintColor 来看这里
}] }, _react2["default"].createElement(_reactNative.Text, { style: [_style2["default"].itemText, {
color: idx === selectedIndex ? '#fff' : tintColor
}] }, value)));
2: 然后去此组件的style/index.js
中可以看到这个对象名,
itemText: {
textAlign: 'center',
fontSize: _default2["default"].font_size_caption_sm
}
3: 在home.js
中引用style/index.js
, 然后更改对象itemText
的fontSize值
- 但是只可以在原有的样式对象上更改,不能添加新的样式对象,不知道为什么,
(谁如果知道为什么, 麻烦告诉下)
//引用`style/index.js`
let IndexStyle = require('../../node_modules/antd-mobile/lib/segmented-control/style/index.js');
class Home extends Component {
constructor(props){
super(props);
this.state = {
selectedIndex: 0,
textSize: 50,
};
// 看这里看这里 更改对象itemText的fontSize值
IndexStyle.itemText = {
fontSize: 30,
}
/* 想添加一个自己写的信样式对象上去, 结果没有起效果,
IndexStyle.bgColor = {
backgroundColor: 'red',
}
*/
this.segmentedLabel = ['待办', '已办'];
this.renderList = this.renderList.bind(this);
this.onChange = this.onChange.bind(this);
}
方法2:
同上 ,需要先去看源码, 需要改的样式,在源码中定位到名称
比如这里要更改InputItem ant-design-mobile中的InputItem 我们需要看下结构, 想更改的样式在组件哪一个cleassName下
比如我们更改marginLeft 左边的距离
我们需更改styles.container,
styles 则是 import InputItemStyle from './style/index';
所以在 上一级的style文件中找到文件index.tsx
在里面可以看到
![NO]B_@YDH@3IH.png](http://upload-images.jianshu.io/upload_images/3512128-762e9138d3511e73.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
我们就可以使用下面的方法来修改,
具体思路就是把所有的样式都拿回来, 扔进一个新的对象, 然后更改, 最后在塞回去
import variables from 'antd-mobile/lib/style/themes/default'; //可能你会用的到,可能不需要, 暂时贴在这, 如果需要就添加, 默认的样式主题
import InputItemStyle from 'antd-mobile/lib/input-item/style/index'; //引入要更改组件的样式,
// 定义一个新的样式对象
const newStyle = {};
// 把需要更改的组件的所有样式扔进新的样式对象, 然后更改对应的样式
function changeStyle () {
for (const key in InputItemStyle) {
if (Object.prototype.hasOwnProperty.call(InputItemStyle, key)) {
newStyle[key] = { ...StyleSheet.flatten(InputItemStyle[key]) };
if (key === 'container') {
newStyle[key].marginLeft = 15;
}
}
}
}
.................................
// 塞回去
<InputItem
key={index}
在这里:
styles={StyleSheet.create(newStyle)}
style={{marginLeft: 16,}}
disabled={true}
placeholder={'请输入'}
placeholderTextColor={'#999'}
labelNumber={6}
value={this.state.formData[item.code]}
type={item.style === 'number'? 'number': ''}
maxLength={10}
onChange={this.setInputValue.bind(this,item)}
editable={this.state.editable}
/>
我们不仅可以修改原有的样式, 还可以添加新的样式,
局限性就是只能在别人定义好的className 中做操作, 并且得去看源码
上面的方法可以自己做个封装, 方便多次使用
import variables from 'antd-mobile/lib/style/themes/default';
import InputItemStyle from 'antd-mobile/lib/input-item/style/index';
import TextareaItemStyle from 'antd-mobile/lib/textarea-item/style/index';
//简单封装
const newStyle = {}; //InputItem
const TextareaStyle = {}; // 大文本
function changeStyle (newObj,style, cssType, cssName,value) {
for (const key in style) {
if (Object.prototype.hasOwnProperty.call(style, key)) {
newObj[key] = { ...StyleSheet.flatten(style[key]) };
if (key === cssType) {
newObj[key][cssName] = value;
}
}
}
}
changeStyle(newStyle,InputItemStyle,'container','borderBottomColor','#fff') // 更改input的下边
changeStyle(newStyle,newStyle,'input','fontSize',16) // 再次更改input的字体, 所以把上次更改后的样式做为基本样式(style)扔进去
changeStyle(TextareaStyle,TextareaItemStyle,'input','fontSize',16)
在封装一次, 2017-07-03
import ModalStyle from 'antd-mobile/lib/modal/style/index';
import { StyleSheet } from 'react-native';
function changeStyle (newObj,style, data) {
for (const key in style) {
if (Object.prototype.hasOwnProperty.call(style, key)) {
newObj[key] = { ...StyleSheet.flatten(style[key]) };
if (data.length > 0){
data.map((item,index) => {
if( key === item.cssType ) {
item.val.map((items,indexs) => {
newObj[key][items.key] = items.value;
})
}
})
}
}
}
}
const newStyle = {};
let myStyle = [
{
cssType: 'body', // 要改的样式的类名字
val: [{key: 'paddingHorizontal', value: 0}] // 要更改或添加的样式 key 为样式名称, value为值
},
{
cssType: 'header',
val: [
{key:'textAlign', value: 'left'},
{key:'color', value: '#fff'},
{key:'borderTopLeftRadius', value: 5},
{key:'borderTopRightRadius', value: 5},
{key:'backgroundColor', value: '#036b74'},
{key:'paddingTop', value: 10},
{key:'paddingBottom', value: 10}
]
},
{
cssType: 'innerContainer',
val: [{key: 'paddingTop', value: 0}]
}
]
changeStyle(newStyle,ModalStyle,myStyle)
changeStyle(newStyle,ModalStyle,data)
newStyle
新命名的空对象,
ModalStyle
从 antd-mobile/xx/style
中引入的原样式对象,
cssType
要改的样式的类名字(cssType: 'innerContainer',)
, 和更改的css样式名称 key
, 及值 value
例: (val: [{key: 'paddingTop', value: 0}])
ok, 更改结束, 此方法基本就能满足平时样式更改,不仅可以更改原有样式, 还能添加样式.
希望阿杜的这个方法能帮到你, 如果大家有更好的方法欢迎您一定要提出, 谢谢