react测试小程序
备忘录小程序
效果:
目录结构:
详细代码:
1)入口index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>react-todolist</title>
<link rel="stylesheet" type="text/css" href="/css/semantic.css">
<style>
.active { color: red }
.line{
display: inline-block;
border-bottom: 1px solid #222222;
width:100px;
position: absolute;
left:0;
top:7px;
}
.ui.comments .comment{
padding:0;
margin:2em 0 0;
}
</style>
</head>
<body>
<div class="ui container" style="padding:30px;">
<div id="app"></div>
</div>
<script src="./bundle.js"></script>
</body>
</html>
2) main.js
'use strict'
import React from 'react'
import ReactDOM from 'react-dom'
import App from './app/component/App'
let data = [
{id: 0, text: '吃饭', complete: false},
{id: 1, text: '睡觉', complete: false},
{id: 2, text: '加班', complete: true},
{id: 3, text: '看书', complete: true},
{id: 4, text: '锻炼', complete: false}
]
ReactDOM.render(
<App data={data}/>,
document.getElementById('app')
)
3) App.js
import React from 'react'
import AppList from './AppList.js'
import AppForm from './AppForm.js'
import AppFooter from './AppFooter.js'
class App extends React.Component {
state = {
choosevalue: 1,
data: this.props.data
}
ChooseValue(id) {
this.setState({ choosevalue: id });
}
//点击修改事件状态
AllChangeComplete(id) {
let newdata = this.state.data.map((item, index) => {
if (item.id === id) {
item.complete = !item.complete;
}
return item;
})
this.setState({ data: newdata });
}
//删除事件
AllOnDeleteItem(id) {
console.log(id);
let newdata = this.state.data.map((item) => {
console.log(item);
if (item.id == id) {
item.deleteFlag = true
}
return item
})
this.setState({ data: newdata })
}
//添加事件
OnAddTodoItem(newItem) {
//concat() 方法用于连接两个或多个数组,该方法不会改变现有的数组,而仅仅会返回被连接数组的一个副本
let newdata = this.state.data.concat(newItem);
this.setState({ data: newdata });
}
render() {
return (
<div className='ui comments'>
<h1>My Todo List</h1>
<div className='ui divider'></div>
<AppForm AddTodoItem={this.OnAddTodoItem.bind(this)} />
<AppList data={this.state.data}
choosevalue={this.state.choosevalue}
ChangeCompleteTop={this.AllChangeComplete.bind(this)}
DeleteItemTop={this.AllOnDeleteItem.bind(this)} />
<AppFooter SubmitChooseValue={this.ChooseValue.bind(this)} />
</div>
)
}
}
export default App;
4)搜索表单AppForm.js
'use strict'
import React from 'react';
import uuid from 'uuid';
var styles = {
'title': {
width: 200,
display: 'inline-block',
marginRight: 10,
verticalAlign: 'top'
}
}
class AppForm extends React.Component {
handleSubmit(event) {
//preventDefault() 方法阻止元素发生默认的行为(当点击提交按钮时阻止对表单的提交)
event.preventDefault()
//this.refs获取组件的所有引用
let text = this.refs.text.value
//trim()方法删除字符串开始和末尾的空格
if (!text.trim()) {
alert("Input can't be null")
return
}
//生成唯一的id
let id = uuid();
//组件间交互方法
this.props.AddTodoItem({ id, text, complete: false });
}
render() {
return (
<form className='ui reply form' onSubmit={this.handleSubmit.bind(this)}>
<div className='field' style={styles.title}>
<input type='text' placeholder='TODO' ref='text' />
</div>
<button type='submit' className='ui blue button'>
添加
</button>
</form>
)
}
}
export default AppForm;
5) 事件列表AppList.js
'use strict'
import React from 'react'
import AppTodos from './AppTodos'
class AppList extends React.Component {
SubmitDelete (id) {
this.props.DeleteItemTop(id)
}
ChangeDone (id) {
this.props.ChangeCompleteTop(id);
}
render () {
//根据choosevalue控制显示,choosevalue:1全部;2未完成;3已完成
var value = this.props.choosevalue;
const a = this.props.data.map(({ id, text, complete, deleteFlag }, index) => {
if (value == '1' && deleteFlag !== true) {
return <AppTodos key={index} id={id} text={text} complete={complete} ChangeCompleteItem={this.ChangeDone.bind(this)} DeleteItem={this.SubmitDelete.bind(this)}/>
}
if (value == '2' && complete === false && deleteFlag !== true) {
return <AppTodos key={index} id={id} text={text} complete={complete} ChangeCompleteItem={this.ChangeDone.bind(this)} DeleteItem={this.SubmitDelete.bind(this)}/>
}
if (value == '3' && complete === true && deleteFlag !== true) {
return <AppTodos key={index} id={id} text={text} complete={complete} ChangeCompleteItem={this.ChangeDone.bind(this)} DeleteItem={this.SubmitDelete.bind(this)}/>
}
})
return (
<div> { a } </div>
)
}
}
export default AppList;
6)依赖组件AppTodos.js
'use strict'
import React from 'react'
var styles = {
'title': {
paddingLeft: '20px',
paddingRight: '50px',
position: 'relative'
},
'delete': {
marginLeft: '20px',
marginRight: '50px'
}
}
class AppTodos extends React.Component {
//点击待办事件,修改显示和状态(已完成/未完成)
handleChangeComplete() {
let newComplete = this.props;
this.props.ChangeCompleteItem(this.props.id);
}
//点击删除
handleDelete() {
this.props.DeleteItem(this.props.id);
}
render() {
return (
<div className='comment'>
<div className='content'>
<span className='author'
style={styles.title}
onClick={this.handleChangeComplete.bind(this)}>
{this.props.text}
<span className={this.props.complete ? 'line' : ''} />
</span>
<span className='author'
style={styles.title}>
{this.props.complete ? '已完成' : '未完成'}
</span>
<span className='ui blue button'
style={styles.delete}
onClick={this.handleDelete.bind(this)}>
删除
</span>
</div>
</div>
)
}
}
export default AppTodos;
7)选择组件AppFooter.js
'use strict'
import React from 'react'
var styles = {
'title': {
marginRight: 10,
fontSize: 20
},
'top': {
marginTop: 20
}
}
class AppFooter extends React.Component {
//显示全部事件
handleAll () {
let all = this.refs.all.value;
this.props.SubmitChooseValue(all);
}
//显示未完成事件
handleActive () {
let active = this.refs.active.value;
this.props.SubmitChooseValue(active);
}
//显示已完成事件
handleComplete () {
let complete = this.refs.complete.value
this.props.SubmitChooseValue(complete);
}
render () {
return (
<div>
<h2 style={styles.top}>show</h2>
<button type='submit' style={styles.top} className='ui blue button' value='1' ref='all' onClick={this.handleAll.bind(this)}> 全部 </button>
<button type='submit' style={styles.top} className='ui blue button' value='2' ref='active' onClick={this.handleActive.bind(this)}> 未完成 </button>
<button type='submit' style={styles.top} className='ui blue button' value='3' ref='complete' onClick={this.handleComplete.bind(this)}> 已完成 </button>
</div>
)
}
}
export default AppFooter;