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

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

首先源码地址为: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. github 访问加速

    http://nullpointer.pw/github%E4%BB%A3%E7%A0%81clone%E5%8A%A0%E9%80%9F.html hosts:https://raw.githubu ...

  2. error LNK2005:"private:__thiscall编译错误

    对于这种编译错误,网上给出了很多解决办法,大部分都是忽略特定库,或者改变多线程调试DLL,但是均没有效果. 这里记录下自己的解决方法,首先按照下图,取消从父级或项目默认设置继承,避免与其他库中的定义冲 ...

  3. Django项目:CRM(客户关系管理系统)--61--51PerfectCRM实现CRM客户报名流程学生合同上传照片

    # sales_views.py # ————————47PerfectCRM实现CRM客户报名流程———————— from django.db import IntegrityError # 主动 ...

  4. Filter - 过滤敏感词汇(动态代理)

    /** * 敏感词汇过滤器 */ @WebFilter("/*") public class SensitiveWordsFilter implements Filter { pu ...

  5. Maven中央仓库地址大全,Maven中央仓库配置示例

    < Maven 中央仓库地址大全 > 在上一篇文章中完成了 < Maven镜像地址大全 >,后来又花了时间又去收集并整理了关于 maven 远程仓库地址,并整理于此,关于 Ma ...

  6. mavenjar 一些拉取不下来问题

    http://search.maven.org/这里找相近版本替换试试.拉取不下来是因为官方版本不足或者网络问题.

  7. java代理概念

    代理的概念 动态代理技术是整个java技术中最重要的一个技术,它是学习java框架的基础,不会动态代理技术,那么在学习Spring这些框架时是学不明白的. 动态代理技术就是用来产生一个对象的代理对象的 ...

  8. grep与find命令的区别

    grep与find命令的区别:grep搜索的是文本,find搜索的是文件,换句话说就是grep是查找匹配条件的行,find是搜索匹配条件的文件. grep文本搜索/过滤 用法:grep[参数]搜索字符 ...

  9. 跟我一起做一个vue的小项目(三)

    接下来我们进行轮播的开发 安装插件,选用2.6.7的稳定版本 npm install vue-awesome-swiper@2.6.7 --save 根据其github上面的用法,我们在全局引用,在m ...

  10. openldap 2.4 centos7 常用配置

    新版的openldap弃用了sldap.conf配置文件,引入一种动态配置,所以尽量不要直接修改配文件 如果直接修改了配置文件可以用slaptest -u命令检查 1.安装openldap,可能需要e ...