我以为代码在有些程序员手里,就好像是画笔,能够创造不少东西
不要以为创意少就叫没有创意,天天进步一点点,世界更美好
首先源码地址为:https://github.com/byk04712/mobx-todos
感谢无私开源的程序员,是大家让代码更美好
先看效果
这个是一个todo的mobx小项目,咱们主要看看数据处理部分react
//根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中,咱们先来看布局
git
这个里面显示了,实际上是将布局分红了上中下三部分程序员
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年前写的呢~github
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里面却是没有什么很特别的,不太重要的是里面的小的组件,已经完成和未完成的,还有样式的处理
react-native
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); } } }
这个是筛选部分
less
@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中的所有代码dom
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: { width: contentWidth, height: 40, flexDirection: 'row', borderWidth: 1, borderColor: 'green' }, input: { flex: 1, paddingHorizontal: 10 }, button: { width: 80, backgroundColor: 'green', justifyContent: 'center', alignItems: 'center' }, buttonText: { color: 'white' }, showTodos: { borderColor: 'green', borderLeftWidth: 1, borderRightWidth: 1, width: 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, width: contentWidth - 90, overflow: 'hidden' }, done: { fontSize: 12, color: 'gray' }, del: { borderWidth: 1, borderColor: 'gray', width: 20, height: 20, borderRadius: 10 }, delText: { alignSelf: 'center' }, filter: { width: 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布局