一、描述

rax-switch 是类似单个 checkbox 功能的内置交互(可以说表单吧)组件,有默认的样式,在 android 、ios、web 三个平台上表现可能不太一样,这是因为 weex 的原因。

TB1Nj.nRVXXXXcMXXXXXXXXXXXX-255-175.gif

因为 weex 已经废弃了 <switch> 组件,因此 rax-switch 是否应该使用也是一个问题

文档地址:

具体的使用时的 prop 等不再重复,文档写的很清楚。

二、源码

源码地址:

1、weex 环境存在的问题

rax-switch 对于 weex 容器环境和 web 环境的渲染内容也是不同的,weex 容器环境是最简单的,因为它直接返回了 weex 的组件 <switch>

    if (isWeex) {
      let nativeProps = {
        style,
        disabled,
        checked: value,
        onChange: this.handleChange
      };

      return (
        <switch {...nativeProps} />
      );
    } 

问题来了,weex 官方文档明确表示,<switch> 是被废弃的组件,不建议在业务上使用。

废弃: 本组件已不推荐业务上使用。由于各端实现不一致且端上定制能力较弱,不适合作为内置组件实现,因此建议开发者通过 weex 上层能力自行定制该组件.

所以不确定 rax 是否会对 rax-switch 进行重写(有时间会尝试自己封装一个能够在 weex 环境下运行的 switch 组件)。因为 weex 容器环境,很多 css 属性是不能用,而且本身 weex 也不支持的,比如 transition,如果要自己封装,可能代码比较多。

2、web 环境

在 web 环境下很好理解,因为很多面向 web (尤其是移动端)的 UI 框架都实现了 switch 功能。

具体实现的代码也不难,因为就两层 HTML 节点就搞定了,关键还是样式。

    let styles = this.getStyles();
      let spanStyle = value ? {...styles.span, ...styles.checkedSpan} : {...styles.span, ...styles.uncheckedSpan};
      let smallStyle = value ? {...styles.small, ...styles.checkedSmall} : {...styles.small, ...styles.uncheckedSmall};
      spanStyle = disabled ? {...spanStyle, ...styles.disabledSpan} : spanStyle;
      spanStyle = {
        ...spanStyle,
        ...style
      };

      return (
        <span onClick={this.handleClick} style={spanStyle}>
          <small style={smallStyle} />
        </span>
      );

可以看出,他把所有的样式都放在了 getStyles() {} 方法中,这个方法内容太长了, 可以去看源代码。

一般来说,在 web 端,通过 js 控制 className 或者直接操作 DOM 都可以,但是在 rax 这种 state 驱动渲染的大条件下,最终还是通过 value 去驱动 style 的变化。

因此,rax-switch 的关键在于 value 一定是 Boolean 的,因为如果不是 Boolean 类型,永远无法触发 switch 的变化,因为这个过程中,value ? {...styles.span, ...styles.checkedSpan}:{...styles.span, ...styles.uncheckedSpan} 的判断是不会生效的。

三、使用

下面代码演示了多种使用方式,value, onValueChange 是必须传递的,否则无法触发 switch 。

GIF.gif

import {createElement, Component} from 'rax';
import View from 'rax-view';
import Text from 'rax-text'; 
import Switch from 'rax-switch';
import styles from './App.css';

class App extends Component {
  state = {
    value:true
  }
  valueChangeHandle = () => {
    this.setState({
      value:!this.state.value
    });
  }
  render() {
    const {state,valueChangeHandle} = this;
    return (
      <View style={styles.app}>
      <Text>{state.value}</Text>
        <Switch  
          onTintColor="red"
          tintColor="#ffffff"
          thumbTintColor="#fff" 
          value={state.value}
          onValueChange={valueChangeHandle}
        ></Switch>
        <Switch  
          value={state.value}
          onValueChange={valueChangeHandle}
        ></Switch>
        <Switch   
          disabled={state.value ? true : false}
          value={state.value}
          onValueChange={valueChangeHandle}
        ></Switch>
      </View>
    );
  }
}
export default App;