Mobx(二)实现选择商品和小星星

作者: Kris_lee | 来源:发表于2017-06-21 17:03 被阅读200次

    效果图展示

    showmobx.gif

    第一步,react-native init RN 创建一个新的项目。

    第二步,导入mobx 和 mobx-react 。

    npm install mobx --save

    npm install mobx-react --save

    第三步,导入babel组件,实现ES6修饰符的运用。

    npm install babel-plugin-syntax-decorators --save
    npm install babel-plugin-transform-decorators-legacy --save

    第四步,.babelrc文件写入babel

        {
      "presets": ["react-native"],
      "plugins": [
        "syntax-decorators",
        "transform-decorators-legacy"
      ]
    }
    

    第五补,小星星组件的导入

    "react-native-star-rating": "^1.0.7",
    "react-native-vector-icons": "^4.2.0",
    "react-native-button": "^2.0.0",
    

    小星星组件需要导入这三个必要的组件,其中 react-native-vector-icons需要react-native link react-native-vector-icons 。

    准备工作完成。现在写入代码。

    import { observable, action, computed } from 'mobx';
    import { observer } from 'mobx-react/native';
    import StarRating from 'react-native-star-rating';
    

    把刚刚引入的组件导入进来,这里注意mobx-react/native需要加上/native,否则无法识别。

    定义mobx结构。
    class CartItem {
        name="",  
        price = 0; //这里name 和 price 假设是从数据库中取出
        
        @observable 
        count=0 ; //数目。 这里的数目是被观察者,也就是每次观察者需要监视我的每个item 的count是否被改变。
        @observable
        isSelected = false; //是否被选择,同样需要观察者查看,当前的item是否被选择,如果选择,做什么操作,如果不选择做什么操作。
        
        @action   
        //这里的action,可以通过action来改变state,从而重新触发渲染视图的效果。inc是增加。如果点击增加,那么说明当前item是被选择的
        inc = () =>{
            ++this.count;
            this.isSelected = true; 
        }
        
         @action
         //同理这里dec也是减少的操作。
        dec = ()=>{
            if(this.count >1){
                --this.count;
    
    
            }else {
                this.count = 0;
                this.isSelected = false;
            }
    
        }
        
        @action
        //是否被选择的action。如果不被选择,那么当前的商品则数量是0。
         select = ()=>{
    
            this.isSelected = !this.isSelected;
            if(this.isSelected){
                ++this.count;
            }else{
                this.count = 0;
            }
        }
        
    }
    
    定义Cart 加入数据。
    class Cart{
    
        @observable
        items = [];
    
        constructor(){
            for (let i = 0; i < 150; i++) {
                this.items.push(new CartItem(
                    `商品${i}`,
                    Math.floor(Math.random() * 100000)/100,
                ));
            }
        }
    //通过计算得到的值。
        @computed
        get count(){
            return this.items.reduce((a,b)=>a+b.count, 0);
        }
    
        @computed
        get price(){
    
            return this.items.reduce((a,b)=>a + (b.price * b.count),0);
        }
    
    
    
    }
    

    这里我们定义Cart这个类,在构造函数里,初始化我们的数据。
    同时,我们不难发现。这里的定义了一个被观察者的items的数组,这个是数据源。也是用来观察的。computed是通过计算得到值,在mobx里还有autorun,套用官方文档的话来说:

    如果你想响应式的产生一个可以被其它 observer 使用的值,请使用 @computed,如果你不想产生一个新值,而想要达到一个效果,请使用 autorun。 举例来说,效果是像打印日志、发起网络请求等这样命令式的副作用。
    以上都是被观察者。我们不难发现。在mobx 的结构中,定义的是被观察者,在定义的数据源中,定义的也是被观察者。接下来,我们做观察者应该做的事,

    渲染组件
    我们定义个Item类。

    Class Item extends Component{
    //这里我们用到了小星星组件。在state定义小星星。
            constructor(props){
            super(props);
            this.state = {
                starCount: 0
            };
        }
        //处理小星星的方法。
          onStarRatingPress(rating) {
            this.setState({
                starCount: rating
            });
        }
        //渲染每个Item的内容。
        render() {
            const { data } = this.props;
            //定义个data,在之后会调用这个组件,我们把需要用到的数据源放入就好。-->const data = this.props.data.
    
            return (
    {/*给每个Item添加一个点击事件,用来判断是否被选择*/}
                <TouchableOpacity onPress = {data.select}>
                    <View>
    
                    <View style={styles.item}>
                    {/*是否被选择,展示不同的页面效果*/}
                        <Text  style = {data.isSelected ? styles.istrue :styles.isfalse}>{data.name}</Text>
                        <Text style={styles.price}>${data.price}</Text>
                        {/*加号的方法*/}
                        <Text style={styles.btn} onPress={data.inc}>+</Text>
                        <Text>{data.count}</Text>
                        {/*减号的方法*/}
                        <Text style={styles.btn} onPress={data.dec}>-</Text>
    
                    </View>
                    {/*渲染小星星的组件*/}
                        <View>
                            <StarRating
                                disabled={false}
                                maxStars={5}
                                rating={this.state.starCount}
                                selectedStar={(rating) => this.onStarRatingPress(rating)}
                            />
                        </View>
    
                    </View>
                </TouchableOpacity>
            )
    
        }
    }
    

    定义一个Info用来观察count和price

    const Info = observer(function({cart}) {
        return (
            <Text>
                Count: {`${cart.count}`} {'\n'}
                Price: {cart.price.toFixed(2)} {'\n'}
            </Text>
        );
    });
    

    定义我们需要展现的类。而这个类作为展示者,他是一个观察者。

    @observer
    export default class MobxDemo extends Component {
    实例化Cart 。
        cart = new Cart();
      //  CartItem = new CartItem();
    //定义ListView.DataSource
        ds = new ListView.DataSource({
            rowHasChanged: (v1, v2) => v1 !== v2,
        });
    //渲染组件renderRow
        renderRow = (data) => {
            return (
                <Item data={data}/>
            );
        };
    
        //返回
        render() {
            //const { data } = this.props;
            return (
                <View style={styles.container}>
    
    
        {/*实现ListView的展示。*/}
                    <ListView
                        dataSource={this.ds.cloneWithRows(this.cart.items.slice(0))}
                        renderRow={this.renderRow}
    
                    />
                    <Info cart={this.cart}/>
                </View>
            );
            }
        }
    

    总结:写的不好,如果有错误,请及时的纠正。

    相关文章

      网友评论

      • 猪猪9527:小星星 写的不好:


        export const Star = ({count = 4, max = 5, onChange, size = 10}) => {
        const currentCount = observable(count);
        const StarCom = observer(() => {
        const stars = [];
        for (let i = 0; i < max; i++) {
        stars.push(<TouchableOpacity
        activeOpacity={0.9}
        onPress={() => {
        if (onChange) {
        currentCount.set(i + 1);
        onChange(i + 1)
        }
        }}
        key={i}
        style={{padding: 2}}>
        <Ionicons name={i < currentCount ? "ios-star" : "ios-star-outline"} color="rgb(247,177,45)"
        size={size}/>
        </TouchableOpacity>)
        }
        return <View style={{flexDirection: 'row'}}>
        {stars}
        </View>
        })
        return <StarCom/>
        }

      本文标题:Mobx(二)实现选择商品和小星星

      本文链接:https://www.haomeiwen.com/subject/vdagqxtx.html