• 【水滴石穿】mobx-todos


    我觉得代码在有些程序员手里,就好像是画笔,可以创造很多东西
    不要觉得创意少就叫没有创意,每天进步一点点,世界更美好
    首先源码地址为:https://github.com/byk04712/mobx-todos
    感谢无私开源的程序员,是你们让代码更美好
    先看效果

    这个是一个todo的mobx小项目,我们主要看看数据处理部分

    //根App.js文件中,主要是渲染组件main
    //App.js
    import React from 'react';
    import {
        AppRegistry
    } from 'react-native';
    import Main from './Main';
    
    
    AppRegistry.registerComponent('mobx_todos', () => Main);
    
    

    在main.js中,我们先来看布局

    这个里面显示了,其实是将布局分成了上中下三部分

    class App extends Component {
    
        todoList = new TodoList();
    
        render() {
            return (
                <View style={styles.container}>
                    <Header data={this.todoList}/>
                    <ShowTodos data={this.todoList}/>
                    <Filter data={this.todoList}/>
                </View>
            );
        }
    
    }
    
    
    
    export default App;
    

    先看header部分代码,看这个代码写的多美丽啊,这个还是该作者2年前写的呢~

    class Header extends Component {
    
        static propTypes = {
            data: PropTypes.instanceOf(TodoList)
        };
    
        addItem = () => {
            const { data } = this.props;
            if (this.inputValue === undefined || this.inputValue.replace(/s+/g, '') === '') {
                return alert('请输入任务名称');
            }
            data.addItem(this.inputValue);
    
            // clear input & reset input value
            this.input.clear();
            this.inputValue = '';
            //还处理了黄色预警
            Keyboard.dismiss();
        };
    
        render() {
            return (
                <View style={styles.header}>
                    <TextInput
                        style={styles.input}
                        ref={input => this.input = input}
                        underlineColorAndroid='transparent'
                        placeholder='在此输入新增的任务'
                        onChangeText={text => this.inputValue = text}
                        maxLength={10}
                    />
                    <TouchableOpacity onPress={this.addItem} style={styles.button}>
                        <Text style={styles.buttonText}>Add Todo</Text>
                    </TouchableOpacity>
                </View>
            );
        }
    }
    

    showtodos里面倒是没有什么很特别的,不过重要的是里面的小的组件,已经完成和未完成的,还有样式的处理

    class ShowTodos extends Component {
    
        static propTypes = {
            data: PropTypes.instanceOf(TodoList)
        };
    
        renderRow = (data) => {
            return (<TodoItem data={data}/>)
        };
    
        render() {
            const { data } = this.props;
            return (
                <View style={styles.showTodos}>
                    <ListView
                        style={styles.listView}
                        enableEmptySections
                        initialListSize={data.items.length}
                        dataSource={ds.cloneWithRows(data.items.slice())}
                        renderRow={this.renderRow}
                    />
                </View>
            );
        }
    
    }
    
    @observer
    class TodoItem extends Component {
    
        static propTypes = {
            data: PropTypes.instanceOf(Todo)
        };
    
        render() {
            const { data } = this.props;
            //这个的处理有意思
            let flag;
            if (data.done) {
                flag = { textDecorationLine: 'line-through' };
            } else {
                flag = { textDecorationLine: 'none' };
            }
            return (
                <TouchableOpacity onPress={data.switchDone}>
                    <View style={styles.item}>
                        <Text style={[styles.name, flag]} numberOfLines={1}>{data.name}</Text>
                        <Text style={[styles.done, flag]}>{data.done ? '已完成' : '未完成'}</Text>
                        <TouchableOpacity style={styles.del} onPress={data.remove}>
                            <Text style={styles.delText}>x</Text>
                        </TouchableOpacity>
                    </View>
                </TouchableOpacity>
            );
        }
    }
    
    class Todo {
    
        id = `${Date.now()}${Math.floor(Math.random()*1000)}`;
    
        @observable
        name = '';
    
        @observable
        done = false;
    
        todos = null;
    
        constructor(name, done, todos) {
            this.name = name;
            this.done = done;
            this.todos = todos;
        }
    
        @action('任务 已完成/未完成 状态切换')
        switchDone = () => {
            this.done = !this.done;
        };
    
        @action('删除当前项')
        remove = () => {
            if (this.todos) {
                this.todos._items.remove(this);
            }
        }
    }
    

    这个是筛选部分

    @observer
    class Filter extends Component {
    
        static propTypes = {
            data: PropTypes.instanceOf(TodoList)
        };
    
        render() {
            const { data } = this.props;
            return (
                <View style={styles.filter}>
                    <Text>筛选:</Text>
                    <FilterButton size={data.countAll} active={data.filter === ALL} onPress={data.filterAll}>全部</FilterButton>
                    <FilterButton size={data.countCompleted} active={data.filter === COMPLETED} onPress={data.filterCompleted}>已完成</FilterButton>
                    <FilterButton size={data.countUncompleted} active={data.filter === UNCOMPLETED} onPress={data.filterUncompleted}>未完成</FilterButton>
                </View>
            );
        }
    }
    

    看main.js中的全部代码

    import React,{
        Component,
        PropTypes
    } from 'react';
    import {
        TouchableOpacity,
        Dimensions,
        StyleSheet,
        TextInput,
        ListView,
        Keyboard,
        View,
        Text
    } from 'react-native';
    import {
        observable,
        computed,
        action,
        useStrict
    } from 'mobx';
    import {
        observer
    } from 'mobx-react/native';
    
    
    // 开启严格模式,建议开启。开启后所有修改 observable 的操作都必须放在 action 里完成
    useStrict(true);
    
    
    const { width, height } = Dimensions.get('window');
    const contentWidth = width - 60;
    const [ALL, COMPLETED, UNCOMPLETED] = ['ALL', 'COMPLETED', 'UNCOMPLETED'];
    const ds = new ListView.DataSource({
        rowHasChanged: (r1, r2) => r1 !== r2
    });
    
    
    const styles = StyleSheet.create({
        container: {
            flex: 1,
            backgroundColor: '#F7F7F7',
            alignItems: 'center',
            paddingVertical: 80
        },
        header: {
             contentWidth,
            height: 40,
            flexDirection: 'row',
            borderWidth: 1,
            borderColor: 'green'
        },
        input: {
            flex: 1,
            paddingHorizontal: 10
        },
        button: {
             80,
            backgroundColor: 'green',
            justifyContent: 'center',
            alignItems: 'center'
        },
        buttonText: {
            color: 'white'
        },
        showTodos: {
            borderColor: 'green',
            borderLeftWidth: 1,
            borderRightWidth: 1,
             contentWidth,
            height: height - 300
        },
        listView: {
            paddingHorizontal: 10
        },
        item: {
            flexDirection: 'row',
            height: 50,
            borderBottomColor: '#CCC',
            borderBottomWidth: StyleSheet.hairlineWidth,
            justifyContent: 'space-between',
            alignItems: 'center',
        },
        name: {
            fontSize: 16,
             contentWidth - 90,
            overflow: 'hidden'
        },
        done: {
            fontSize: 12,
            color: 'gray'
        },
        del: {
            borderWidth: 1,
            borderColor: 'gray',
             20,
            height: 20,
            borderRadius: 10
        },
        delText: {
            alignSelf: 'center'
        },
        filter: {
             contentWidth,
            height: 50,
            borderWidth: 1,
            borderColor: 'green',
            flexDirection: 'row',
            alignItems: 'center',
            paddingHorizontal: 5
        },
        condition: {
            paddingHorizontal: 5,
            paddingVertical: 7,
            marginHorizontal: 4,
            borderWidth: StyleSheet.hairlineWidth,
            borderColor: 'gray'
        },
        conditionText: {
            fontSize: 14,
            letterSpacing: 2
        }
    });
    
    
    class TodoList {
    
        @observable
        _items = [];
    
        @observable
        filter = ALL;
    
        // 初始化3条测试数据
        constructor() {
            this._items.push(new Todo('Travel', true, this));
            this._items.push(new Todo('Metting', false, this));
            this._items.push(new Todo('Conversation', true, this));
        }
    
        @computed
        get items() {
            return this._items.filter(item => {
                if (this.filter === ALL) {
                    return item;
                } else if (this.filter === COMPLETED) {
                    return item.done;
                } else if (this.filter === UNCOMPLETED) {
                    return !item.done
                }
            });
        }
    
        @computed
        get countAll() {
            return this._items.length;
        }
    
        @computed
        get countCompleted() {
            return this._items.filter(item => item.done).length;
        }
    
        @computed
        get countUncompleted() {
            return this._items.filter(item => !item.done).length;
        }
    
        @action('添加任务')
        addItem = (name) => {
            if (name) {
                this._items.push(new Todo(name, false, this));
            }
        };
    
        @action('筛选全部')
        filterAll = () => {
            this.filter = ALL;
        };
    
        @action('筛选已完成的')
        filterCompleted = () => {
            this.filter = COMPLETED;
        };
    
        @action('筛选未完成的')
        filterUncompleted = () => {
            this.filter = UNCOMPLETED;
        }
    
    }
    
    
    class Todo {
    
        id = `${Date.now()}${Math.floor(Math.random()*1000)}`;
    
        @observable
        name = '';
    
        @observable
        done = false;
    
        todos = null;
    
        constructor(name, done, todos) {
            this.name = name;
            this.done = done;
            this.todos = todos;
        }
    
        @action('任务 已完成/未完成 状态切换')
        switchDone = () => {
            this.done = !this.done;
        };
    
        @action('删除当前项')
        remove = () => {
            if (this.todos) {
                this.todos._items.remove(this);
            }
        }
    }
    
    
    // Stateless Functional Component (无状态的功能组件)
    const FilterButton = function(props) {
    
        const { onPress, children, active, size } = props;
    
        let buttnStyle, buttonTextStyle;
        if (active) {
            buttnStyle = {backgroundColor: 'green'};
            buttonTextStyle = {color: 'white'};
        } else {
            buttnStyle = {backgroundColor: '#F7F7F7'};
            buttonTextStyle = {color: '#666'};
        }
    
        return (
            <TouchableOpacity onPress={onPress} disabled={active}>
                <View style={[styles.condition, buttnStyle]}>
                    <Text style={[styles.conditionText, buttonTextStyle]}>{children}({size})</Text>
                </View>
            </TouchableOpacity>
        );
    };
    
    
    class Header extends Component {
    
        static propTypes = {
            data: PropTypes.instanceOf(TodoList)
        };
    
        addItem = () => {
            const { data } = this.props;
            if (this.inputValue === undefined || this.inputValue.replace(/s+/g, '') === '') {
                return alert('请输入任务名称');
            }
            data.addItem(this.inputValue);
    
            // clear input & reset input value
            this.input.clear();
            this.inputValue = '';
            //还处理了黄色预警
            Keyboard.dismiss();
        };
    
        render() {
            return (
                <View style={styles.header}>
                    <TextInput
                        style={styles.input}
                        ref={input => this.input = input}
                        underlineColorAndroid='transparent'
                        placeholder='在此输入新增的任务'
                        onChangeText={text => this.inputValue = text}
                        maxLength={10}
                    />
                    <TouchableOpacity onPress={this.addItem} style={styles.button}>
                        <Text style={styles.buttonText}>Add Todo</Text>
                    </TouchableOpacity>
                </View>
            );
        }
    }
    
    
    @observer
    class ShowTodos extends Component {
    
        static propTypes = {
            data: PropTypes.instanceOf(TodoList)
        };
    
        renderRow = (data) => {
            return (<TodoItem data={data}/>)
        };
    
        render() {
            const { data } = this.props;
            return (
                <View style={styles.showTodos}>
                    <ListView
                        style={styles.listView}
                        enableEmptySections
                        initialListSize={data.items.length}
                        dataSource={ds.cloneWithRows(data.items.slice())}
                        renderRow={this.renderRow}
                    />
                </View>
            );
        }
    
    }
    
    
    @observer
    class Filter extends Component {
    
        static propTypes = {
            data: PropTypes.instanceOf(TodoList)
        };
    
        render() {
            const { data } = this.props;
            return (
                <View style={styles.filter}>
                    <Text>筛选:</Text>
                    <FilterButton size={data.countAll} active={data.filter === ALL} onPress={data.filterAll}>全部</FilterButton>
                    <FilterButton size={data.countCompleted} active={data.filter === COMPLETED} onPress={data.filterCompleted}>已完成</FilterButton>
                    <FilterButton size={data.countUncompleted} active={data.filter === UNCOMPLETED} onPress={data.filterUncompleted}>未完成</FilterButton>
                </View>
            );
        }
    }
    
    
    @observer
    class TodoItem extends Component {
    
        static propTypes = {
            data: PropTypes.instanceOf(Todo)
        };
    
        render() {
            const { data } = this.props;
            //这个的处理有意思
            let flag;
            if (data.done) {
                flag = { textDecorationLine: 'line-through' };
            } else {
                flag = { textDecorationLine: 'none' };
            }
            return (
                <TouchableOpacity onPress={data.switchDone}>
                    <View style={styles.item}>
                        <Text style={[styles.name, flag]} numberOfLines={1}>{data.name}</Text>
                        <Text style={[styles.done, flag]}>{data.done ? '已完成' : '未完成'}</Text>
                        <TouchableOpacity style={styles.del} onPress={data.remove}>
                            <Text style={styles.delText}>x</Text>
                        </TouchableOpacity>
                    </View>
                </TouchableOpacity>
            );
        }
    }
    
    
    class App extends Component {
    
        todoList = new TodoList();
    
        render() {
            return (
                <View style={styles.container}>
                    <Header data={this.todoList}/>
                    <ShowTodos data={this.todoList}/>
                    <Filter data={this.todoList}/>
                </View>
            );
        }
    
    }
    
    
    
    export default App;
    

    是这个博客代码写的很好,还是我的mobx很差啊,喜欢这个demo

  • 相关阅读:
    [PHP] Layui + jquery 实现 实用的文章自定义标签
    个人总结第五周
    个人总结第四周
    个人总结第三周
    个人总结第二周
    个人总结第一周
    用户体验评价
    第二阶段scrum冲刺
    单词统计
    用户模块和用户场景
  • 原文地址:https://www.cnblogs.com/smart-girl/p/10912489.html
Copyright © 2020-2023  润新知