我觉得代码在有些程序员手里,就好像是画笔,可以创造很多东西

不要觉得创意少就叫没有创意,每天进步一点点,世界更美好

首先源码地址为: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: {
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

【水滴石穿】mobx-todos的更多相关文章

  1. mobx @computed的解读

    写在前面:我一开始看不懂官网的@computed的作用,因为即使我把@computed去掉,依然能正确的report,然后我百度谷歌都找不到答案,下面都是我自己的理解,如果是有问题的,不对的,请务必留 ...

  2. 十分钟介绍mobx与react

    原文地址:https://mobxjs.github.io/mobx/getting-started.html 写在前面:本人英语水平有限,主要是写给自己看的,若有哪位同学看到了有问题的地方,请为我指 ...

  3. mobx react

    目录结构: Model/index.js 'use strict'; import { action, autorun, observable, computed } from "mobx& ...

  4. 你需要Mobx还是Redux?

    在过去一年,越来越多的项目继续或者开始使用React和Redux开发,这是目前前端业内很普遍的一种前端项目解决方案,但是随着开发项目越来越多,越来越多样化时,个人又有了不同的感受和想法.是不是因为已经 ...

  5. React使用Mobx管理数据

    React 和 Vue一样都属于单向数据流,为了更好的进行状态和数据管理官方和第三方也有配套的Redux等插件,本文介绍一个个人觉得更易用使用的组件 Mobx 核心概念 MobX 处理你的应用程序状态 ...

  6. [Web 前端] mobx教程(二)-mobx主要概念

    cp from : https://blog.csdn.net/smk108/article/details/84960159 通过<Mobx教程(一)-Mobx简介>我们简单理解了Mob ...

  7. 初见mobX

    先看如下的代码 const {observable}= mobox; const {observer}=mobxReact; const {Component}=React; const appSta ...

  8. 1-2 Mobx 入门实践之TodoList(官方Demo)

    第一步:导入模块 import React, { Component } from 'react'; import { observable, autorun,computed } from 'mob ...

  9. Vuex、Flux、Redux、Redux-saga、Dva、MobX

    https://www.jqhtml.com/23003.html 这篇文章试着聊明白这一堆看起来挺复杂的东西.在聊之前,大家要始终记得一句话:一切前端概念,都是纸老虎. 不管是Vue,还是 Reac ...

  10. [Web] How to Test React and MobX with Jest

    转载自: https://semaphoreci.com/community/tutorials/how-to-test-react-and-mobx-with-jest?utm_content=bu ...

随机推荐

  1. CAS企业级单点登录原理

    https://blog.csdn.net/anumbrella/article/details/80821486 1. 单点登录概述 1.1. 什么是单点登录? 单点登录:Single Sign O ...

  2. 数据库连接客户端 dbeaver 程序包以及使用说明

    dbeaver 是一个基于 Eclipse 的数据库客户端,支持几乎所有常见的数据库.分为商业版和社区版,社区版可以免费使用. 官网和 GitHub https://dbeaver.io/ https ...

  3. 【深度学习】CNN 中 1x1 卷积核的作用

    [深度学习]CNN 中 1x1 卷积核的作用 最近研究 GoogLeNet 和 VGG 神经网络结构的时候,都看见了它们在某些层有采取 1x1 作为卷积核,起初的时候,对这个做法很是迷惑,这是因为之前 ...

  4. 6.Spring【AOP】XML方式

    1.AOP术语 1. Joinpoint(连接点):所谓连接点是指那些被拦截到的点.在spring中,这些点指的是方法,因为spring只支持方法类型的连接点 2. Pointcut(切入点):所谓切 ...

  5. 安装配置git服务

    创建git用户和组 groupadd -g git useradd -md /home/git -g -u git 安装依赖包 yum install curl-devel expat-devel g ...

  6. 模板:KD-Tree

    KD-Tree,用来解决多维空间中的问题,其实就是优化暴力(逃 一般cdq能做的它都能做,而且...既然是优化暴力,那就学习一下了 对与几个n维点,我们将它每一维分割,建立一颗二叉树,方便我们搜索剪枝 ...

  7. git 命令行(一)-版本回退

    1. 版本回退 在实际工作中,我们脑子里怎么可能记得一个几千行的文件每次都改了什么内容,不然要版本控制系统干什么.版本控制系统肯定有某个命令可以告诉我们历史记录,在Git中,我们用 git log 命 ...

  8. jmeter设置代理

    JMeter设置Http代理对web或者app进行录制 一.录制web 1.首先保证JMeter的安装环境都正确.启动JMeter:在安装路径的bin目录下双击jmeter.bat (例如:D:\ap ...

  9. 机器学习实战之k-近邻算法(3)---如何可视化数据

    关于可视化: <机器学习实战>书中的一个小错误,P22的datingTestSet.txt这个文件,根据网上的源代码,应该选择datingTestSet2.txt这个文件.主要的区别是最后 ...

  10. 常见问题:MongoDB基础知识

    常见问题:MongoDB基础知识 ·MongoDB支持哪些平台? ·MongoDB作为托管服务提供吗? ·集合(collection)与表(table)有何不同? ·如何创建数据库(database) ...