rax
目录
1. 配置+创建项目
2. 语法
3. 组件
1. 配置+创建项目
node.js官网下载
1、安装node.js(下载-双击安装)
2、下载Weex Playground APP
扫描预览
3、安装 rax-cli (Rax 提供的脚手架和集成开发工具)
npm install -g rax-cli
4、创建项目,并进入
rax init hello-world && cd hello-world
5、运行项目
npm run start
在浏览器中输入网址
或使用普通应用扫描第一个二维码
或使用Playground扫描第二个二维码
项目目录
运行结果
index.js首页文件内容
App.js文件内容
2. 语法
组件(components)
可复用的 UI 元素。
属性(Props)
组件的属性(修饰组件的唯一途径)。
状态(State)
根据 state 呈现不同的 UI 展示。
更改 state:this.setState({ value: 10 })。
state更改后调用render函数重新渲染UI。
事件(Events)
使用驼峰式命名指定要绑定的事件属性,例:
<TextInput onInput={ (event) => this.setState({ text: event.value }) } />
Flexbox 布局
弹性布局
样式
为style属性赋值CSS对象,带连词号(-)的属性需要用驼峰写法代替。
Rax不推荐使用内联方式。例:
<View style={{ width: 100, height: 100, backgroundcolor: 'skyblue' }} />
2.1 组件的生命周期
生命周期
渲染阶段
componentWillmount:
该方法在首次渲染之前调用,也是在 render 方法调用之前修改 state 的最后一次机会。
render:(对于一个组件来讲,render 方法是唯一一个必需的方法。)
该方法会创建一个虚拟 DOM,用来表示组件的输出。
render方法需要满足下面几点:
1、只能通过 this.props 和 this.state 访问数据(不能修改)
2、可以返回 null 或者任何 Rax 组件
3、可以返回一个顶级组件,也可以返回一组元素(数组)
4、不能改变组件的状态
5、不能修改真实节点的输出
componentDidMount:
该方法不会在服务端被渲染的过程中调用。该方法被调用时,页面中已经渲染出真实的节点。
存在阶段
componentWillReceiveProps:
组件的 props 属性可以通过父组件来更改,这时,此方法将会被调用。可以在这个方法里更新 state,以触发 render 方法重新渲染组件。
shouldComponentUpdate:
如果你确定组件的 props 或者 state 的改变不需要重新渲染,可以通过在这个方法里通过返回 false 来阻止组件的重新渲染,返回 false 则不会执行 render 以及后面的 componentWillUpdate,componentDidUpdate 方法。
该方法是非必须的,并且大多数情况下没有在开发中使用。
componentWillUpdate:
此方法和 componentWillMount 类似,在组件接收到了新的 props 或者 state 即将进行重新渲染前,componentWillUpdate(object nextProps, object nextState) 会被调用.
注意不要在此方面里再去更新 props 或者 state。
componentDidUpdate:
此方法和 componentDidMount 类似,在组件重新被渲染之后,componentDidUpdate(object prevProps, object prevState) 会被调用。
可以在这里访问并修改真实节点。
销毁阶段
componentWillUnmount:
每当 Rax 使用完一个组件,这个组件必须从容器环境中卸载后被销毁,此时该 方法会被执行,完成所有的清理和销毁工作。
在 componentDidMount 中添加的任务都需要再该方法中撤销,如创建的定时器或事件监听器。
Rax 是与 React 兼容的,所以 React 中支持的组件写法 Rax 也都支持。
例1:
import { createElement, render, Component } from 'rax';
import Text from 'rax-text';
class Hello extends Component {
render() {
return <Text>Hello {this.props.name}</Text>;
}
}
render(<Hello name="Taobao FED" />);
例2:
import { createElement, render, Component } from 'rax';
import Text from 'rax-text';
function Hello(props) {
return <Text>Hello {props.name}</Text>;
}
render(<Hello name="Taobao FED" />);
例3:
class Clock extends Component {
state = {
time: Date.now(),
};
componentDidMount() {
this.timer = setInterval(() => {
this.setState({ time: Date.now() });
}, 1000);
}
componentWillUnmount() {
clearinterval(this.timer);
}
render() {
const time = new Date(this.state.time).tolocaleTimeString();
return <Text>{ time }</Text>;
}
}
render(<Clock />);
2.2 事件
点击事件
例:
import {createElement, Component} from 'rax';
import scrollView from 'rax-scrollview';
import Touchable from 'rax-touchable';
import Text from 'rax-text';
class TouchDemo extends Component {
render() {
return (
<ScrollView>
<Touchable onPress={() => console.log('pressed')}>
<Text>Proper Touch Handling</Text>
</Touchable>
</ScrollView>
);
}
}
出现、消失事件
import {createElement, Component} from 'rax';
import View from 'rax-view';
import Touchable from 'rax-touchable';
import Text from 'rax-text';
class TouchDemo extends Component {
render() {
return (
<View onAppear={(ev) => {
console.log('appear');
}} onDisappear={(ev) => {
console.log('disappear');
}}>
<Text>hello world</Text>
</View>
);
}
}
滚动事件
throttle:
控制在滚动过程中,scroll事件被调用的频率(默认值为100),用于滚动的节流
loadMoreoffset:
设置加载更多的偏移 可以写作loadmoreoffset(默认值为100)
onLoadMore:
滚动区域还剩 loadmoreoffset 的长度时触发
例:
import {createElement, Component} from 'rax';
import ScrollView from 'rax-scrollview';
import Touchable from 'rax-touchable';
import Text from 'rax-text';
class TouchDemo extends Component {
render() {
return (
<ScrollView loadMoreOffset={300} onLoadMore={()=>{}}>
<Text style={{
color:'# ffffff',
margin:'5rem',
fontSize:'100rem',
backgroundColor:"blue"
}}>
Shake or press menu button for dev menuShake or press menu button for dev menu
Shake or press menu button for dev menuShake or press menu button for dev menu
Shake or press menu button for dev menuShake or press menu button for dev menu
Shake or press menu button for dev menuShake or press menu button for dev menu
</Text>
</ScrollView>
);
}
}
用户输入事件(获取焦点、输入)
例:
import {createElement, Component} from 'rax';
import TextInput from 'rax-textinput';
import Touchable from 'rax-touchable';
import Text from 'rax-text';
class TouchDemo extends Component {
render() {
return (
<TextInput
placeholder="Enter text to see events"
autoFocus multiline
onFocus={() => console.log('onFocus')}
onblur={() => console.log('onBlur')}
onInput={() => console.log('onInput')}
style={{
width: '1000rem',
height: '1000rem',
border: '1px solid # 000'
}}
/>
);
}
}
手势
例:
import {createElement, Component, render, findDOMNode, setNativeProps} from 'rax';
import View from 'rax-view';
import PanResponder from 'universal-panresponder';
const CIRCLE_SIZE = 80;
const CIRCLE_COLOR = 'blue';
const CIRCLE_HIGHLIGHT_COLOR = 'green';
const styles = {
circle: {
width: CIRCLE_SIZE,
height: CIRCLE_SIZE,
borderRadius: CIRCLE_SIZE / 2,
backgroundColor: CIRCLE_COLOR,
position: 'absolute',
left: 50,
top: 0,
},
container: {
flex: 1,
paddingTop: 64,
},
};
class PanResponderSample extends Component {
componentWillMount () {
this._panResponder = PanResponder.create({
onStartShouldSetPanResponder: this._handleStartShouldSetPanResponder,
onMoveShouldSetPanResponder: this._handleMoveShouldSetPanResponder,
onPanResponderGrant: this._handlePanResponderGrant,
onPanResponderMove: this._handlePanResponderMove,
onPanResponderRelease: this._handlePanResponderEnd,
onPanResponderTerminate: this._handlePanResponderEnd,
});
this._previousLeft = 20;
this._previousTop = 84;
this._circleStyles = {
style: {
left: this._previousLeft,
top: this._previousTop
}
};
}
componentDidMount () {
this._updatePosition();
}
render () {
return (
<View
style={styles.container}>
<View
ref='circle'
style={styles.circle}
{...this._panResponder.panHandlers}
/>
</View>
);
}
_highlight () {
if (this.refs.circle) {
setNativeProps(this.refs.circle, {
style: {
backgroundColor: CIRCLE_HIGHLIGHT_COLOR
}
});
}
}
_unHighlight () {
if (this.refs.circle) {
setNativeProps(this.refs.circle, {
style: {
backgroundColor: CIRCLE_COLOR
}
});
}
}
_updatePosition () {
if (this.refs.circle) {
setNativeProps(this.refs.circle, this._circleStyles);
}
}
_handleStartShouldSetPanResponder (e, gestureState) {
// Should we become active when the user presses down on the circle"https://upload-images.jianshu.io/upload_images/5111884-12e236ed5c70661b.png" alt="5111884-12e236ed5c70661b.png" />create方法参数说明-1
create方法参数说明-2
create方法参数说明-3
事件对象 event 中包含的属性
手势状态 gestureState 中包含的属性
2.3 样式
内联样式
在使用内联方式时,CSS 属性名只允许使用驼峰风格,不支持使用中划线。
例1:
<View style={styles.container}>
<Text>hello world</Text>
</View>
const styles = {
container: {
background: 'grey',
width: 375 推荐使用不加单位(1个单位的大小为屏幕宽度的 1/750)
}
};
例2(数组):
<View style={[styles.container, styles.custom]}>
<Text>hello world</Text>
</View>
const styles = {
container: {
background: 'grey',
width: '750rem'
},
custom: {
height: '100rem'
}
};
外部样式表(推荐)
foo.css文件
.container {
background-color: blue;
}
.container_title {
font-size: 20px;
}
foo.js文件
import styles from './foo.css';
function Foo() {
return <p style={styles.container}>
<span style={styles.container_title}>hello world</span>
</p>;
}
export default Foo;
Rax 中并不支持所有的 CSS 特性 ,已实现以下:
字体
@font-face {
font-family: icon;
src: url(//at.alicdn.com/t/font_pkm0oq8is8fo5hfr.ttf);
}
.text {
font-family: icon;
}
<span style={styles.text}>{'\uE601'}</span>
群组选择器
.a, .b {
color: red;
}
嵌套
默认不支持嵌套规则,如.a .b
可以通过在 webpack 中配置 transformDescendantCombinator 支持嵌套:
{
test: /\.css/,
loader: 'stylesheet"container">
<span className="container_title">hello world</span>
</p>;
}
export default Foo;
2.4 网络请求
Rax 支持 HTTP、jsonp 等多种网络请求方式。
Rax 实现了Fetch API,推荐使用 fetch 来发起异步网络请求。
Fetch 提供了获取资源的统一接口,通过定义 request 和 response 对象,将资源获取抽象成发送资源请求和获取资源响应两步,统一并简化了资源获取过程。
HTTP
Promise <Response> fetch(url[, options]);
options
method(String):资源请求方法('GET'|'POST')
headers(Object): 请求头
body(String):请求体
dataType(String):资源类型(仅在weex下支持,包括json和text两种)
mode(String):请求模式(cors, no-cors, same-origin 和 jsonp)
例:
fetch('./api.json', {
mode: 'same-origin',
dataType: 'json',
method: 'GET'
})
.then((response) => {
return response.json();
})
.then((data) => {
console.log(data);
})
.catch((err) => {
// handle exception
});
JSONP
确保已经在项目中安装universal-jsonp模块
npm install universal-jsonp --save
例:
import jsonp from 'universal-jsonp';
jsonp('http://domain.com/jsonp', { jsonpCallbackFunctionName: 'callback' })
.then((response) => {
return response.json();
})
.then((obj) => {
console.log(obj);
})
.catch((err) => {
// handle exception
});
2.5 环境信息
运行平台
navigator.platform // iOS or Android
navigator.product // weex
navigator.appName // TB
navigator.appVersion // 6.4.1
判断运行容器
import { isWeex, isWeb } from 'universal-env';
isWeex 是否是 weex 环境
isWeb 是否是 web 环境
获取屏幕信息
window.devicePixelRatio
screen.width
screen.height
screen.availWidth
screen.availHeight
screen.colordepth
screen.pixelDepth
3. 组件
- 基础组件
文本组件Text
安装
npm install rax-text --save
引入
import Text from 'rax-text';
<Text style={{
color: '#3c3c3c',
fontSize: '50rem'
}}>文本</Text>
<Text style={{
color: '#ff4200'
}}>混排</Text>
<Text numberOfLines={1} style={{
width: 300,
textOverflow: 'ellipsis',
}}>单行文本超出被截断的文本</Text>
<Text style={{textDecoration: 'underline'}}>
文本下划线
</Text>
<Text style={{textDecorationLine: 'none'}}>
无下划线
</Text>
<Text style={{textDecoration: 'line-through'}}>
文本删除线
</Text>
<Text style={{lineHeight: '120rem'}}>
行高 120rem,多行文本文本折行效果 多行文本文本折行效果
</Text>
<Text>
<Link style={{color:'blue'}} href="">
<Text>TAOBAO</Text>
</Link>
<Image style={{width:300, height:300}} source={{uri: '//www.fresher.ru/manager_content/images2/kadry-veka/big/2-1.jpg'}} />
<Text>富文本</Text>
</Text>
目前富文本不支持局部刷新,如果二次渲染会有布局错乱的问题。
参考解决方案是在 shouldComponentUpdate 的时机 return 掉避免二次渲染。
另外能用 flex 布局解决的,尽量不要用富文本
视图组件View
安装
npm install rax-view --save
引入
import View from 'rax-view';
例:
<View style={{
padding: 30,
width: 300,
height: 300,
backgroundColor:"yellow",
position: 'absolute',
top: 80,
left: 210,
}}/>
</View>
图片组件Image
安装
npm install rax-image --save
引入
import Image from 'rax-image';
属性
名称 类型 默认值 描述
source Object '' 设置图片的 uri
style Object '' 样式 图片不设置宽高则默认为0x0
resizeMode String '' 决定当组件尺寸和图片尺寸不成比例的时候如何调整图片的大小,contain、cover、stretch、center、repeat
使用2方式
<Image/>
<Image></Image>
本地图片
<Image source={require('./path/to/your/image.png')} resizeMode="cover"/>
网络图片
let image = {
uri: 'https://...'
};
<Image
source={image}
style={[styles.base, {
borderRadius: 200
}]}
resizeMode={Image.resizeMode.contain}
/>
链接Link
安装
npm install rax-link --save
引入
import Link from 'rax-link';
属性
名称 类型 默认值 描述
onPress Function null 响应点击事件(不再默认跳转)
<Link href={url}>这是一个链接</Link>
handlePress1 = () => {
this.setState({
timesPressed1: this.state.timesPressed1 + 1,
});
};
<Link onPress={this.handlePress1} href="https://github.com/alibaba/rax">Goto Github</Link>
图标icon
安装
npm install rax-icon --save
引入
import Icon, {createIconSet} from 'rax-icon';
const icon = 'https://.../xxx.png';
let iconfont = '//at.alicdn.com/t/font_pkm0oq8is8fo5hfr.ttf'
const IconFont1 = createIconSet({ hello: '\ue60f',world: '\uE65B' }, 'iconfont', iconfont);
const IconFont2 = createIconSet({}, 'iconfont', iconfont);
<Icon style={{width: 100, height: 100}} source={{uri: icon}}/>
<Icon style={{width: 100, height: 100}} fontFamily="iconfont" source={{uri:iconfont, codePoint: '\uE60f'}}/>
<IconFont1 name={'hello'}/>
<IconFont1 name={'world'}/>
<IconFont2 codePoint={'\uE60f'}/>
<IconFont2 codePoint={'\uE65B'}/>
属性说明:
名称 类型 默认值 描述
source.uri String '' 图片型icon的url,如果出现,则font和 codePoint两个属性失效
fontFamily String '' iconfont的字体
source.codePoint String '' iconfont的码点
方法说明:
参数1、map:对象,描述字符集映射,eg:{ hello: '\ue60f' }
参数2、name:字体名称,通常是 'iconfont'
参数3、url: 字体文件的 URL
IconFont是IconComponent类型,属性:name:字符的名称、codePoint:iconfont 的码点。
按钮Button
安装
npm install rax-button --save
引入
import Button from 'rax-button';
例:
handlePress = () => {
this.setState({
//。。。
});
};
<Button onPress={this.handlePress}>点我</Button>
<Button onPress={(evt) => { alert('你好'); }}>
<View>
<Text>点我</Text>
</View>
</Button>
可点击容器Touchable
安装
npm install rax-touchable --save
引入
import Touchable from 'rax-touchable';
例1:
import {createElement, Component, render} from 'rax';
import Touchable from 'rax-touchable';
render(<Touchable onPress={() => { alert('hello'); }}>Click Me</Touchable>);
例2:
//demo
import {createElement, Component, render} from 'rax';
import View from 'rax-view';
import Text from 'rax-text';
import TouchableHighlight from 'rax-touchable';
class App extends Component {
state = {
eventLog: [],
};
_appendEvent = (eventName) => {
var limit = 6;
var eventLog = this.state.eventLog.slice(0, limit - 1);
eventLog.unshift(eventName);
this.setState({eventLog});
};
render() {
return (
<View style={styles.root}>
<View style={styles.container}>
<TouchableHighlight
onPress={() => this._appendEvent('press')}
delayPressIn={400}
onPressIn={() => this._appendEvent('pressIn - 400ms delay')}
delayPressOut={1000}
onPressOut={() => this._appendEvent('pressOut - 1000ms delay')}
delayLongPress={800}
onLongPress={() => this._appendEvent('longPress - 800ms delay')}
style={{
width: '230rem',
height: '60rem',
paddingTop: '12rem',
paddingBottom: '12rem',
paddingLeft: '25rem',
paddingRight: '25rem',
alignItems: 'center',
justifyContent: 'center',
backgroundColor: '#efefef',
}}>
<Text>Touch Me</Text>
</TouchableHighlight>
<View style={styles.eventLogBox}>
{this.state.eventLog.map((e, ii) => <Text key={ii}>{e}</Text>)}
</View>
</View>
</View>
);
}
}
let styles = {
root: {
width: 750,
paddingTop: 20
},
container: {
padding: 20,
borderStyle: 'solid',
borderColor: '#dddddd',
borderWidth: 1,
marginLeft: 20,
marginRight: 20,
marginBottom: 10,
},
eventLogBox: {
padding: 10,
margin: 10,
height: 260,
borderWidth: 1,
borderColor: '#f0f0f0',
backgroundColor: '#f9f9f9',
},
};
render(<App/>);
视频Video
安装
npm install rax-video --save
引入
import Video from 'rax-video';
// demo
import {createElement, Component, render} from 'rax';
import Video from 'rax-video';
render(<Video style={{ width: 750, height: 400 }} autoPlay src="https://cloud.video.taobao.com/play/u/2780279213/p/1/e/6/t/1/d/ld/36255062.mp4" />);
Slider 轮播
安装
npm install rax-slider --save
引入
import Slider from 'rax-slider';
属性
属性说明
1、web 环境中 slider 内部默认做了节点的懒加载渲染,不再需要使用 picture 的 lazyload做懒加载
2、paginationStyle 默认样式为
{
position: 'absolute',
width: props.width,
height: '40rem',
bottom: '20rem',
left: 0,
itemColor: 'rgba(255, 255, 255, 0.5)',
itemSelectedColor: 'rgb(255, 80, 0)',
itemSize: '8rem'
}
其中 itemColor 用来定义分页原点的颜色,itemSelectedColor 用来定义分页原点激活时的颜色,itemSize 用来定义分页圆点的大小
事件
onChange
方法
slideTo
例:this.refs.Slider.slideTo(index);
onchange = (index) => {
console.log('change', index);
}
<Slider className="slider" width="750rem" height="500rem" style={styles.slider}
autoPlay={true}
loop={true}
showsPagination={true}
paginationStyle={styles.paginationStyle}
autoplayTimeout={3000}
onChange={this.onchange}>
<View style={styles.itemWrap}>
<Image style={styles.image} source={{uri: '//gw.alicdn.com/tfs/TB19NbqKFXXXXXLXVXXXXXXXXXX-750-500.png'}} />
</View>
<View style={styles.itemWrap}>
<Image style={styles.image} source={{uri: '//gw.alicdn.com/tfs/TB1tWYBKFXXXXatXpXXXXXXXXXX-750-500.png'}} />
</View>
</View>
</Slider>
轮播增强XSlider
安装
npm install rax-xslider --save
引入
import Slider from 'rax-xslider';
Slider属性-1
Slider属性-2
Slider方法
Slider.Panel
Slider.LoadMore属性
getCardTransitionSpec = () => {
return {
props: [
{
property: 'transform.scale',
inputRange: [0, 1],
outputRange: [0.8, 1]
},
{
property: 'opacity',
inputRange: [0, 1],
outputRange: [.2, 1]
}
]
};
}
<Slider ref="slider"
cardSize={600}
startGap={75}
endGap={75}
autoPlay={true}
loop={true}
cardTransitionSpec={this.getCardTransitionSpec}
>
{colors.map((color, i) => {
return (<Slider.Panel style={[styles.item, {backgroundColor: color}]}>
<Text style={styles.txt}>{i}</Text>
</Slider.Panel>);
})}
</Slider>
倒计时Countdown
安装
npm install rax-countdown --save
引入
import Countdown from 'rax-countdown';
属性
<Countdown
timeRemaining={100000000}
timeStyle={{
'color': '#007457',
'backgroundColor': 'red',
'marginLeft': '2rem',
'marginRight': '2rem'
}}
secondStyle={{'backgroundColor': 'yellow'}}
textStyle={{'backgroundColor': 'blue'}}
timewrapstyle={{
borderRadius: 6,
width: 50,
height: 60,
backgroundColor: '#333333',
}}
tpl={'{d}-{h}-{m}-{s}'}
onComplete={this.onComplete}
/>
视频播放器Player
安装
npm install rax-player --save
引入
import Player from 'rax-player';
属性
属性说明:
1、style 中必须传入宽高
2、weex环境下使用weex提供的video组件
Android设备的weex暂时不提供全屏功能
video的控制条控件由组件提供,无法控制和修改
3、关于web下控制条控件
Android下默认使用原生控制条,在UC内核中可以通过在Url中添加 hardware=true 强制开启UC内核,这种情况下播放器的控制条是定制的,使用体验好一些
iOS设备下额外实现了进度条,可以选择是否提供全屏功能
例
<Player
style={{
width: '750rem',
height: '400rem'
}}
poster="https://gw.alicdn.com/tps/TB1QsDBKFXXXXcQXpXXXXXXXXXX-750-200.png"
src="https://cloud.video.taobao.com/play/u/2780279213/p/1/e/6/t/1/d/ld/36255062.mp4"
controls
hasFullScreen
originFullscreen={false}
startBtn
autoPlay
/>
图片Picture
安装
npm install rax-picture --save
引入
import Picture from 'rax-picture';
属性-1
属性-2
resizeMode 可用值:
cover: 在保持图片宽高比的前提下缩放图片,直到宽度和高度都大于等于容器视图的尺寸(如果容器有padding内衬的话,则相应减去,仅安卓有效)。译注:这样图片完全覆盖甚至超出容器,容器中不留任何空白。
contain: 在保持图片宽高比的前提下缩放图片,直到宽度和高度都小于等于容器视图的尺寸(如果容器有padding内衬的话,则相应减去,仅安卓有效)。译注:这样图片完全被包裹在容器中,容器中可能留有空白
stretch: 拉伸图片且不维持宽高比,直到宽高都刚好填满容器。
设置 resizeMode 的前提是你设置了 style.width && style.height
例
let image = '//';
<Picture></Picture>
<Picture
source={{uri: image}}
style={{
width: 400,
height: 200,
}}
resizeMode="cover"
lazyload={true}
autoWebp={false}
autoCompress={false}
autoRemoveScheme={false}
autoReplaceDomain={false}
autoScaling={false}
highQuality={false}
/>
返回顶部Gotop
安装
npm install --save rax-gotop
引入
import GoTop from 'rax-gotop';
<GoTop />
<GoTop name="click" icon="//...xxx.png" />
注:weex 环境下必须把 GoTop 放在 ScrollView 的第一个位置
属性
<ScrollView ref={(scrollview) => {
this.scrollview = scrollview;
}}>
<GoTop name="顶部" style={{width: 100, height: 100}}
onTop={() => {
this.scrollview.scrollTo({y: 0});
}}
icon="//gtms03.alicdn.com/tps/i3/TB1rrfVJVXXXXalXXXXGEZzGpXX-40-40.png" />
{Array.from({length: 50}).map((_, idx) => (
<Text style={{fontSize: 50}}>hello world {idx}</Text>
))}
</ScrollView>
- 布局组件
栅格布局Grid
安装
npm install rax-grid --save
引用
import { Row, Col } from 'rax-grid';
Row可嵌套在Col中
均分
<Row>
<Col>列1</Col>
<Col>列2</Col>
<Col>列3</Col>
</Row>
自定义宽
const styles = {
col1: {
flex: 1
},
col2: {
flex: 2
},
}
<Row>
<Col style={styles.col1}>flex: 1</Col>
<Col style={styles.col2}>flex: 2</Col>
</Row>
例:
// demo
import { createElement, render, Component } from 'rax';
import { Row, Col } from 'rax-grid';
const styles = {
container: {
width: 750
},
row: {
height: 400
}
};
class App extends Component {
render() {
return (
<Row style={[styles.container, styles.row]}>
<Col style={{flex: 1, backgroundColor: 'red'}}>Col1</Col>
<Col style={{flex: 1, backgroundColor: 'green'}}>Col2</Col>
<Col style={{flex: 1, backgroundColor: 'blue'}}>Col3</Col>
</Row>
);
}
}
render(<App />);
多列布局MultiRow
安装
npm install rax-multirow --save
引用
import MultiRow from 'rax-multirow';
属性
例
// demo
import {createElement, Component, render} from 'rax';
import MultiRow from 'rax-multirow';
import View from 'rax-view';
class Demo extends Component {
render() {
return (
<View style={{width: 750}}>
<MultiRow datasource={['tom', 'jeck', 'lilei', 'hanmeimei']}
cells={2} renderCell={(num, index) => { return <View>{num}</View> }}
/>
</View>
);
}
}
render(<Demo />);
结果
滚动容器ScrollView
安装
npm install rax-scrollview --save
引入
import ScrollView from 'rax-scrollview';
属性
方法
// demo
import {createElement, Component, render} from 'rax';
import View from 'rax-view';
import Text from 'rax-text';
import TouchableOpacity from 'rax-touchable';
import ScrollView from 'rax-scrollview';
class Thumb extends Component {
shouldComponentUpdate(nextProps, nextState) {
return false;
}
render() {
return (
<View style={styles.button}>
<View style={styles.box} />
</View>
);
}
}
let THUMBS = [];
for (let i = 0; i < 20; i++) THUMBS.push(i);
let createThumbRow = (val, i) => <Thumb key={i} />;
class App extends Component {
state = {
horizontalScrollViewEventLog: false,
scrollViewEventLog: false,
};
render() {
return (
<View style={styles.root}>
<View style={styles.container}>
<ScrollView
ref={(scrollView) => {
this.horizontalScrollView = scrollView;
}}
style={{
height: 100,
}}
horizontal={true}
onEndReached={() => this.setState({horizontalScrollViewEventLog: true})}
>
{THUMBS.map(createThumbRow)}
</ScrollView>
<TouchableOpacity
style={styles.button}
onPress={() => this.horizontalScrollView.scrollTo({x: 0})}>
<Text>Scroll to start</Text>
</TouchableOpacity>
<View style={styles.eventLogBox}>
<Text>{this.state.horizontalScrollViewEventLog "https://upload-images.jianshu.io/upload_images/5111884-9f18501859b0f22c.png" alt="5111884-9f18501859b0f22c.png" />属性
方法
例:
如果需要悬浮head则只需在listview上方创建View
// demo
import {createElement, Component, render} from 'rax';
import View from 'rax-view';
import Text from 'rax-text';
import ListView from 'rax-listview';
let listData = [
{name1: 'tom'}, {name1: 'tom'}, {name1: 'tom'},
{name1: 'tom'}, {name1: 'tom'}, {name1: 'tom'},
{name1: 'tom'}, {name1: 'tom'}, {name1: 'tom'},
{name1: 'tom'}, {name1: 'tom'}, {name1: 'tom'},
{name1: 'tom'}, {name1: 'tom'}, {name1: 'tom'},
{name1: 'tom'}, {name1: 'tom'}, {name1: 'tom'},
{name1: 'tom'}, {name1: 'tom'}, {name1: 'tom'},
{name1: 'tom'}, {name1: 'tom'}, {name1: 'tom'},
];
// 将 item 定义成组件
class ListViewDemo extends Component {
constructor(props) {
super(props);
this.state = {
index: 0,
data: listData
};
}
listHeader = () => {
return (
<View style={styles.title}>
<Text style={styles.text}>列表头部</Text>
</View>
);
}
listLoading = () => {
if (this.state.index < 4) {
return (
<View style={styles.loading}>
<Text style={styles.text}>加载中...</Text>
</View>
);
} else {
return null;
}
}
listItem = (item, index) => {
if (index % 2 == 0) {
return (
<View style={styles.item1}>
<Text style={styles.text}>{item.name1}</Text>
</View>
);
} else {
return (
<View style={styles.item2}>
<Text style={styles.text}>{item.name1}</Text>
</View>
);
}
}
handleLoadMore = () => {
settimeout(() => {
this.state.index++;
if (this.state.index < 5) {
this.state.data.push(
{name1: 'loadmore 2'},
{name1: 'loadmore 3'},
{name1: 'loadmore 4'},
{name1: 'loadmore 5'},
{name1: 'loadmore 2'},
{name1: 'loadmore 3'},
{name1: 'loadmore 4'},
{name1: 'loadmore 5'}
);
}
this.setState(this.state);
}, 1000);
}
render() {
return (
<View style={styles.container}>
<ListView
renderHeader={this.listHeader}
renderFooter={this.listLoading}
renderRow={this.listItem}
dataSource={this.state.data}
onEndReached={this.handleLoadMore}
/>
</View>
);
}
};
const styles = {
container: {
padding: 20,
borderStyle: 'solid',
borderColor: '#dddddd',
borderWidth: 1,
marginLeft: 20,
marginRight: 20,
marginBottom: 10,
flex: 1
},
title: {
margin: 50
},
text: {
fontSize: 28,
color: '#000000',
fontSize: 28,
padding: 40
},
item1: {
height: 110,
backgroundColor: '#909090',
marginBottom: 3
},
item2: {
height: 110,
backgroundColor: '#e0e0e0',
marginBottom: 3
},
loading: {
padding: 50,
textAlign: 'center',
}
};
render(<ListViewDemo />);
RecyclerView
具有复用内部组件来提供性能的机制
安装
npm install rax-recyclerview --save
引用
import RecyclerView from 'rax-recyclerview';
属性
例:
// demo
import {createElement, Component, render} from 'rax';
import View from 'rax-view';
import Text from 'rax-text';
import RecyclerView from 'rax-recyclerview';
import Touchable from 'rax-touchable';
class Thumb extends Component {
shouldComponentUpdate(nextProps, nextState) {
return false;
}
render() {
return (
<RecyclerView.Cell>
<View style={styles.button}>
<View style={styles.box} />
</View>
</RecyclerView.Cell>
);
}
}
class Row extends Component {
handleClick = (e) => {
this.props.onClick(this.props.data);
};
render() {
return (
<Touchable onPress={this.handleClick} >
<View style={styles.row}>
<Text style={styles.text}>
{this.props.data.text + ' (' + this.props.data.clicks + ' clicks)'}
</Text>
</View>
</Touchable>
);
}
}
let THUMBS = [];
for (let i = 0; i < 20; i++) THUMBS.push(i);
let createThumbRow = (val, i) => <Thumb key={i} />;
class App extends Component {
state = {
horizontalScrollViewEventLog: false,
scrollViewEventLog: false,
};
render() {
return (
<View style={styles.root}>
<View style={styles.container}>
<RecyclerView
ref={(scrollView) => {
this.scrollView = scrollView;
}}
style={{
height: 500
}}
onEndReached={() => this.setState({scrollViewEventLog: true})}>
<RecyclerView.Header style={styles.sticky}>
<Text>Sticky view is not header</Text>
</RecyclerView.Header>
<RecyclerView.Header>
<View style={styles.sticky}>
<Text>Sticky view must in header root</Text>
</View>
</RecyclerView.Header>
{THUMBS.map(createThumbRow)}
</RecyclerView>
<Touchable
style={styles.button}
onPress={() => this.scrollView.scrollTo({y: 0})}>
<Text>Scroll to top</Text>
</Touchable>
<View style={styles.eventLogBox}>
<Text>{this.state.scrollViewEventLog "https://upload-images.jianshu.io/upload_images/5111884-dad4f409947c9c0d.png" alt="5111884-dad4f409947c9c0d.png" />属性
// demo
import {createElement, Component, render} from 'rax';
import View from 'rax-view';
import Text from 'rax-text';
import RefreshControl from 'rax-refreshcontrol';
import waterfall from 'rax-waterfall';
let dataSource = [
{ height: 550, item: {} },
{ height: 624, item: {} },
{ height: 708, item: {} },
{ height: 600, item: {} },
{ height: 300, item: {} },
{ height: 100, item: {} },
{ height: 400, item: {} },
{ height: 550, item: {} },
{ height: 624, item: {} },
{ height: 708, item: {} },
{ height: 600, item: {} },
{ height: 300, item: {} },
{ height: 100, item: {} },
{ height: 400, item: {} }
];
class App extends Component {
state = {
refreshing: false,
dataSource: dataSource
}
handlerefresh = () => {
if (this.state.refreshing) {
return;
}
this.setState({
refreshing: true,
dataSource: []
});
setTimeout(() => {
this.setState({
refreshing: false,
dataSource: dataSource
});
}, 500);
}
loadMore = () => {
setTimeout(() => {
this.setState({
dataSource: this.state.dataSource.concat(dataSource)
});
}, 1000);
}
render() {
return (<View style={{position: 'absolute', top: 0, bottom: 0, left: 0, right: 0}}>
<View>first module</View>
<Waterfall
columnWidth={150}
columnCount={4}
columnGap={50}
dataSource={this.state.dataSource}
renderHeader={() => {
return [
<RefreshControl
key="0"
refreshing={this.state.refreshing}
onRefresh={this.handleRefresh}>
<Text>下拉刷新</Text>
</RefreshControl>,
<View key="1" style={{width: 750, height: 100, backgroundColor: 'yellow', marginBottom: 20}}>header1</View>,
<View key="2" style={{width: 750, height: 100, backgroundColor: 'green', marginBottom: 20}}>header2</View>
];
}}
renderFooter={() => {
return <View key="3" style={{width: 750, height: 300, backgroundColor: 'blue', marginTop: 20}}>footer1</View>;
}}
renderItem={(item, index) => {
return (<View style={{height: item.height, backgroundColor: 'red', marginBottom: 20}}>
{index}
</View>);
}}
onEndReached={this.loadMore} />
</View>);
}
}
render(<App />);
导航切换TabHeader
安装
npm install rax-tabheader --save
引入
import TabHeader from 'rax-tabheader';
属性
注意:
1、当选择带有底部滑动边框或者背景滑块的 type 时,renderItem、renderSelect 不用传入
2、当选择 dropDown-border-scroll 类型时,必须传入 dropDownCols
type 值对应的展示类型含义
1、dropDown-border-scroll 带有下拉的展现形式,带有底边移动动画效果,样式规范遵循 MXUI
2、normal-border-scroll 无下拉的展现形式,带有底边移动动画效果,样式规范遵循 MXUI
3、icon-bg-scroll 每一项带有图标的展现形式,带有背景移动动画效果,样式规范遵循 MXUI
4、default-noAnim-scroll 默认可扩展的自定义展现,1.x.x 版本的基本功能
5、normal-border 不可滚动的 tab 选项,带有底边移动动画效果,样式规范遵循 MXUI
6、icon-bg 每一项带有图标的展现形式,不可横向滚动,带有背景移动动画效果,样式规范遵循 MXUI
7、icon-border 每一项带有图标的展现形式,不可横向滚动,带有背景移动动画效果,样式规范遵循 MXUI
方法
例:
// demo
import {createElement, Component, render} from 'rax';
import View from 'rax-view';
import Text from 'rax-text';
import TabHeader from 'rax-tabheader';
const styles = {
container: {
width: 750
}
};
class App extends Component {
componentDidMount() {
this.refs.tabHeader.select(0);
}
renderItem = (item, index) => {
return <View><Text>{item}</Text></View>;
}
renderSelect = (item, index) => {
return <View><Text>{item}</Text></View>;
}
onSelect = (index) => {
// do something
}
itemWidth = (item, index) => {
return (item.length * 50 + 50) + 'rem';
}
render() {
return (
<TabHeader
ref="tabHeader"
style={styles.container}
containerStyle={{
backgroundColor: '#9fff79'
}}
itemStyle={{
width: (750 / 3) + 'rem',
height: 112
}}
itemSelectedStyle={{
color: 'green'
}}
animBuoyStyle={{
borderColor: 'green'
}}
有图标时
dataSource={[
{text: 'tab1', icon: icon},
{text: 'tab2', icon: icon},
]}
仅文本时
dataSource={['tab1','tab2','tab3','tab4']}
renderItem={this.renderItem}
renderSelect={this.renderSelect}
onSelect={this.onSelect}
selected={0}
itemWidth={this.itemWidth}
dropDownCols={4}
type={'dropDown-border-scroll'}
/>
);
}
}
render(<App />);
底部导航Tabbar
引入
import Tabbar from 'rax-tabbar';
Tabbar属性
Tabbar.Item属性
例:
// demo
import {createElement, Component, render} from 'rax';
import View from 'rax-view';
import Text from 'rax-text';
import Image from 'rax-image';
import Tabbar from 'rax-tabbar';
let base64Icon = 'data:image/png;base64,...';
class TabBarexample extends Component {
state = {
selectedTab: 'redTab',
notifCount: 0,
presses: 0,
};
_renderContent(color, pageText, num) {
return (
<View style={[styles.tabContent, {backgroundColor: color}]}>
<Text style={styles.tabText}>{pageText}</Text>
<Text style={styles.tabText}>{num} re-renders of the {pageText}</Text>
</View>
);
}
render() {
return (
<Tabbar position="bottom">
<Tabbar.Item
title="Blue Tab"
icon={{uri: base64Icon, scale: 3}}
selected={this.state.selectedTab === 'blueTab'}
onPress={() => {
this.setState({
selectedTab: 'blueTab',
});
}}>
{this._renderContent('#414A8C', 'Blue Tab')}
</Tabbar.Item>
<Tabbar.Item
title="Red Tab"
badge={this.state.notifCount > 0 "More"
selected={this.state.selectedTab === 'greenTab'}
onPress={() => {
this.setState({
selectedTab: 'greenTab',
presses: this.state.presses + 1
});
}}>
{this._renderContent('#21551C', 'Green Tab', this.state.presses)}
</Tabbar.Item>
</Tabbar>
);
}
}
let styles = {
tabContent: {
flex: 1,
alignItems: 'center',
},
tabText: {
color: 'white',
margin: 50,
},
};
render(<TabBarExample />);
- 表单组件
文字输入TextInput
安装
npm install rax-textinput --save
引用
import TextInput from 'rax-textinput';
属性-1
属性-2
方法
focus 获取焦点方法
blur 失交方法
clear 清除文本内容
<TextInput
multiline={true}
value={this.state.value}
ref="input"
autoCapitalize="none"
placeholder="Enter text to see events"
autoCorrect={false}
onFocus={() => this.updateText('onFocus')}
onBlur={() => this.updateText('onBlur')}
onChange={(event) => this.updateText(
'onChange text: ' + event.nativeEvent.text
)}
onInput={(event) => this.updateText(
'onInput text: ' + event.nativeEvent.text
)}
style={styles.default}
/>
开关按钮Switch
安装
npm install rax-switch --save
引入
import Switch from 'rax-switch';
属性
<Switch onTintColor="green" tintColor="#ffffff" thumbTintColor="blue"
onValueChange={(value) => this.setState({falseSwitchIsOn: value})}
value={this.state.falseSwitchIsOn}/>
选择框CheckBox
安装
npm install rax-checkbox --save
引入
import CheckBox from 'rax-checkbox';
属性
<CheckBox
containerStyle={{
marginTop: 10,
}}
onChange={(checked) => {
console.log('checked', checked);
}} />
选择框Picker
安装
npm install rax-picker --save
引入
import Picker from 'rax-picker';
属性
<Picker
selectedValue={this.state.selectedValue}
onValueChange={(value, index) => {
this.setState({selectedValue: value});
}}>
<Picker.Item value={'男'} label={'男性'} />
<Picker.Item value={'女'} label={'女性'} />
</Picker>
日期选择DatePicker
安装
npm install rax-datepicker --save
引入
import DatePicker from 'rax-datepicker';
属性
<DatePicker
selectedValue={'2000-01-01'}
MinimumDate={'2000-01-01'}
maximumDate={'2001-01-01'}
onDateChange={(date) => {
console.log('组件date', date);
}} />
时间选择TimePicker
安装
npm install rax-timepicker --save
引入
import TimePicker from 'rax-timepicker';
属性
<TimePicker
selectedValue={'10:10'}
/>
数量选择Counter
安装
npm install rax-counter --save
引入
import counter from 'rax-counter';
属性
<Counter
value={1}
end={5}
start={0}
onChange={(num) => {
this.state.count = num;
}}
onComplete={(num) => {
this.state.count = num;
}} />
日历calendar
安装
npm install rax-calendar --save
引入
import Calendar from 'rax-calendar';
属性
<Calendar
ref="calendar"
eventDates={['2017-01-02', '2017-01-05', '2017-01-28', '2017-01-30']}
startDate={'2017-01-01'}
endDate={'2017-07-01'}
titleFormat={'YYYY年MM月'}
prevButtonText={'上一月'}
nextButtonText={'下一月'}
weekStart={0}
onDateSelect={(date) => this.setState({ selectedDate: date })}
onTouchPrev={() => console.log('Back TOUCH')}
onTouchNext={() => console.log('Forward TOUCH')}
/>
- 提示框
弹出框toast
安装
npm install universal-toast --save
引入
import Toast from 'universal-toast';
方法
show(message, duration = Toast.SHORT_DELAY);
message: String, toast 中展示的信息;
duration: 自定义持续的时间,SHORT 2s, LONG 3.5s;
<Touchable style={styles.text}
onPress={() => {Toast.show('Hello Short', Toast.SHORT)}}>Hello Short</Touchable>
模态框Modal
安装
npm install rax-modal --save
引入
import Modal from 'rax-modal';
属性
例:
// demo
import {Component, createElement, render} from 'rax';
import Text from 'rax-text';
import View from 'rax-view';
import Touchable from 'rax-touchable';
import Modal from 'rax-modal';
class Example extends Component {
showModal = () => {
this.refs.modal.show();
};
hideModal = () => {
this.refs.modal.hide();
};
render() {
return (
<View>
<Touchable onPress={this.showModal}>
<Text>
Open
</Text>
</Touchable>
<Modal ref="modal">
<View>
<Text>
I am a dialog
</Text>
</View>
<Touchable onPress={this.hideModal}>
<Text>
Close
</Text>
</Touchable>
</Modal>
</View>
);
}
}
render(<Example />);
下拉刷新RefreshControl
安装
npm install rax-refreshcontrol --save
引入
import RefreshControl from 'rax-refreshcontrol';
属性
例:
// demo
import {createElement, Component, render} from 'rax';
import View from 'rax-view';
import Text from 'rax-text';
import Image from 'rax-image';
import Link from 'rax-link';
import TextInput from 'rax-textinput';
import Button from 'rax-button';
import Switch from 'rax-switch';
import Video from 'rax-video';
import ScrollView from 'rax-scrollview';
import RecyclerView from 'rax-recyclerview';
import Touchable from 'rax-touchable';
import RefreshControl from 'rax-refreshcontrol';
let arrayFrom = function(arrayLike /*, mapFn, thisArg */) {
if (arrayLike == null) {
throw new TypeError('Object is null or undefined');
}
// Optional args.
var mapFn = arguments[1];
var thisArg = arguments[2];
var C = this;
var items = Object(arrayLike);
var symbolIterator = typeof Symbol === 'function'
"5">
Transition 渐变动画
安装
npm install universal-transition --save
引入
import transition from 'universal-transition';
方法
transition(box, {
transform: 'translate(10px, 20px) scale(1.5, 1.5) rotate(90deg)',
opacity: '0.5'
}, {
timingFunction: 'ease',
delay: 2000,
duration: 3000
}, () => {
console.log('animation end');
});
const box = findDOMNode(this.refs.box); // 获取元素
<View ref="box" style={styles.container} />
陀螺仪视差动画GyroscopeParallax
安装
npm install rax-gyroscope-parallax --save
引入
import GyroscopeParallax from 'rax-gyroscope-parallax';
容器(GyroscopeParallax)属性
层(Layer)属性
方法
start() 开始动画
stop() 停止动画
例:
<GyroscopeParallax onRotate={this.onRotate}
calibrationthreshold={50}
style={styles.container}>
<GyroscopeParallax.Layer depthX={1} depthY={2} style={styles.rope1}>
<Picture resizeMode="cover" style={{width:750,height:50}} source={{uri:images.rope}}></Picture>
</GyroscopeParallax.Layer>
</GyroscopeParallax>
基于bindingx的多元素帧动画工具Animation
安装
npm install universal-animation --save
引入
import animate from 'universal-animation';
方法
animate (config,callback) 返回Animation
config的props
element 元素
property 动画属性(和bindingx一致)
start 开始值
end 结束值
duration 周期(单位ms)
easing 缓动函数
delay 延迟时间(单位ms,默认0)
let easing = `cubicBezier(.25,.1,.25,1)`;
let delay = 0;
let duration = 1000;
let property = 'transform.translateX';
let start = 0;
let end = 200;
animate({
forceTransition:true,
props: [{
element: findDOMNode(this.refs.block),
property,
easing,
duration,
start,
end,
delay
}]
}, () => {
console.log('transition end')
})
手势Gestureview
安装
npm install rax-gesture-view --save
引入
import GestureView from 'rax-gesture-view';
属性
onHorizontalPan = (e) => {
console.ERROR('onHorizontalPan:' + e.state);
}
onVerticalPan = (e) => {
console.error('onVerticalPan:' + e.state);
}
<GestureView style={{width: 300, height: 300, backgroundColor: 'red'}}
onVerticalPan={this.onVerticalPan}
onHorizontalPan={this.onHorizontalPan}
>pan me</GestureView>
Rax 样式支持列表
相关阅读
室内设计3DMAX入门到精通之卧室背景墙构图教程
上篇文章我们已经一起成功创建了一个Hello World级别的微信小程序。
那么这篇文章我们将详细讲解下这个例子中的相关代码部分。
《U3D_Shader编程》##《U3D_Shader编程》发布说明:++++Shader一个高大上的领域,不管怎么样,我来了。++++立钻哥哥从2018年开始正式对
C语言实现,编译环境VS2017 附:easyx图形化(文章末尾)
效果图如下
(有一些函数kbhit,getch,在这表示为_kbhit与_getch)//不同编译器原
Wireshark(前称Ethereal)是一个网络数据包分析软件。网络数据包分析软件的功能是截取网络数据包,并尽可能显示出最为详细的网络数据