【水滴石穿】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: {
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的更多相关文章
- mobx @computed的解读
写在前面:我一开始看不懂官网的@computed的作用,因为即使我把@computed去掉,依然能正确的report,然后我百度谷歌都找不到答案,下面都是我自己的理解,如果是有问题的,不对的,请务必留 ...
- 十分钟介绍mobx与react
原文地址:https://mobxjs.github.io/mobx/getting-started.html 写在前面:本人英语水平有限,主要是写给自己看的,若有哪位同学看到了有问题的地方,请为我指 ...
- mobx react
目录结构: Model/index.js 'use strict'; import { action, autorun, observable, computed } from "mobx& ...
- 你需要Mobx还是Redux?
在过去一年,越来越多的项目继续或者开始使用React和Redux开发,这是目前前端业内很普遍的一种前端项目解决方案,但是随着开发项目越来越多,越来越多样化时,个人又有了不同的感受和想法.是不是因为已经 ...
- React使用Mobx管理数据
React 和 Vue一样都属于单向数据流,为了更好的进行状态和数据管理官方和第三方也有配套的Redux等插件,本文介绍一个个人觉得更易用使用的组件 Mobx 核心概念 MobX 处理你的应用程序状态 ...
- [Web 前端] mobx教程(二)-mobx主要概念
cp from : https://blog.csdn.net/smk108/article/details/84960159 通过<Mobx教程(一)-Mobx简介>我们简单理解了Mob ...
- 初见mobX
先看如下的代码 const {observable}= mobox; const {observer}=mobxReact; const {Component}=React; const appSta ...
- 1-2 Mobx 入门实践之TodoList(官方Demo)
第一步:导入模块 import React, { Component } from 'react'; import { observable, autorun,computed } from 'mob ...
- Vuex、Flux、Redux、Redux-saga、Dva、MobX
https://www.jqhtml.com/23003.html 这篇文章试着聊明白这一堆看起来挺复杂的东西.在聊之前,大家要始终记得一句话:一切前端概念,都是纸老虎. 不管是Vue,还是 Reac ...
- [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 ...
随机推荐
- pycharm 汉化补丁
找了很久,找到了这个比较好的pycharm汉化补丁包,就分享出来 1. 将解压包解压出来 2 . 复制对应的汉化补丁包到 x:\xxx\JetBrains\PyCharm Community Edit ...
- Jmeter设置中文汉化
下载汉化包logkit-2.0.jar 将汉化包copy至 jmeter文件的lib目录下 打开Jmeter软件,设置汉化包 Options -> ChooseLanguage -> ...
- Linux下ps -ef和ps aux的区别及格式详解-转
原文:https://www.linuxidc.com/Linux/2016-07/133515.htm Linux下显示系统进程的命令ps,最常用的有ps -ef 和ps aux.这两个到底有什么区 ...
- 2019-8-31-C++-驱动开发-error-LNK2019-unresolved-external-symbol-__CheckForDebuggerJustMyCode-referenced-...
title author date CreateTime categories C++ 驱动开发 error LNK2019 unresolved external symbol __CheckFor ...
- qq邮箱html邮件,图片不显示的问题
测试无论是站外的图片还是站内的图片,qq邮箱都会过滤图片,导致显示不出来. 解决办法:图片base64编码.效果图: 代码: <div class="container"&g ...
- 全景还原报错现场 | 应用实时监控 ARMS 上线用户行为回溯功能
随着前端技术日新月异迅猛发展,为了实现更好的前端性能,最大程度提高用户体验,支持单页应用的框架逐渐占领市场,如众所周知的React,Vue等等.但是在单页应用的趋势下,快速定位并解决JS错误却成为一大 ...
- Django项目:CRM(客户关系管理系统)--32--24PerfectCRM实现King_admin自定义操作数据
#admin.py # ————————01PerfectCRM基本配置ADMIN———————— from django.contrib import admin # Register your m ...
- Mac 安装package control
参考网址:https://packagecontrol.io/installation 复制命令就不说明了. 主要阐述下第二种,下载安装包覆盖的方法,下面不说话,依次截图.步骤可以查看参考网址 啰嗦一 ...
- Oracle基础知识:DECODE、NVL
select 1 from PMADW.GET_WX_DATAPUSH_NEW_CHECK A INNER JOIN PMADW.V_EXCEPTION_QTY_MAIN B on DECODE( A ...
- H5C3--transform实现任何元素居中对齐
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...