$ npm install
// webpack.config.js
var path = require('path');
module.exports = {
entry: "./src/entry.js",
output: {
path: path.join(__dirname, 'out'),
publicPath: './out/',
filename: "bundle.js"
},
externals: {
'react': 'React'
},
module: {
loaders: [
{ test: /\.js$/, loader: "jsx!babel", include: /src/},
{ test: /\.css$/, loader: "style!css"},
{ test: /\.scss$/, loader: "style!css!sass"},
{ test: /\.(jpg|png)$/, loader: "url?limit=8192"}
]
}
};
import React from "react";
import LocalDb from "localDb";
import TodoHeader from "./TodoHeader.js";
import TodoMain from "./TodoMain.js";
import TodoFooter from "./TodoFooter.js";
class App extends React.Component {
constructor(){
super();
this.db = new LocalDb('React-Todos');
this.state = {
todos: this.db.get("todos") || [],
isAllChecked: false
};
}
// 判断是否所有任务的状态都完成,同步底部的全选框
allChecked(){
let isAllChecked = false;
if(this.state.todos.every((todo)=> todo.isDone)){
isAllChecked = true;
}
this.setState({todos: this.state.todos, isAllChecked});
}
// 添加任务,是传递给Header组件的方法
addTodo(todoItem){
this.state.todos.push(todoItem);
this.allChecked();
this.db.set('todos',this.state.todos);
}
// 改变任务状态,传递给TodoItem和Footer组件的方法
changeTodoState(index, isDone, isChangeAll=false){
if(isChangeAll){
this.setState({
todos: this.state.todos.map((todo) => {
todo.isDone = isDone;
return todo;
}),
isAllChecked: isDone
})
}else{
this.state.todos[index].isDone = isDone;
this.allChecked();
}
this.db.set('todos', this.state.todos);
}
// 清除已完成的任务,传递给Footer组件的方法
clearDone(){
let todos = this.state.todos.filter(todo => !todo.isDone);
this.setState({
todos: todos,
isAllChecked: false
});
this.db.set('todos', todos);
}
// 删除当前的任务,传递给TodoItem的方法
deleteTodo(index){
this.state.todos.splice(index, 1);
this.setState({todos: this.state.todos});
this.db.set('todos', this.state.todos);
}
render(){
var props = {
todoCount: this.state.todos.length || 0,
todoDoneCount: (this.state.todos && this.state.todos.filter((todo)=>todo.isDone)).length || 0
};
return (
<div className="panel">
<TodoHeader addTodo={this.addTodo.bind(this)}/>
<TodoMain deleteTodo={this.deleteTodo.bind(this)} todos={this.state.todos} changeTodoState={this.changeTodoState.bind(this)}/>
<TodoFooter isAllChecked={this.state.isAllChecked} clearDone={this.clearDone.bind(this)} {...props} changeTodoState={this.changeTodoState.bind(this)}/>
</div>
)
}
}
React.render(<App/>, document.getElementById("app"));
constructor(){
super();
this.db = new LocalDb('React-Todos');
this.state = {
todos: this.db.get("todos") || [],
isAllChecked: false
};
}
// 判断是否所有任务的状态都完成,同步底部的全选框
allChecked()
// 添加一个任务,参数是一个todoItem的object
addTodo(todoItem)
// 改变任务的状态,index是第几个,isDone是状态,isChangeAll是控制全部状态的
changeTodoState(index, isDone, isChangeAll=false) // 参数默认位false
// 清空已完成
clearDone()
// 删除面板上第几个任务
deleteTodo(index)
// react用于渲染的函数
render(){
<div className="panel">
<TodoHeader />
<TodoMain />
<TodoFooter />
</div>
}
render(){
var props = {
todoCount: this.state.todos.length || 0,
todoDoneCount: (this.state.todos && this.state.todos.filter((todo)=>todo.isDone)).length || 0
};
return (
<div className="panel">
<TodoHeader addTodo={this.addTodo.bind(this)}/>
<TodoMain deleteTodo={this.deleteTodo.bind(this)} todos={this.state.todos} changeTodoState={this.changeTodoState.bind(this)}/>
<TodoFooter isAllChecked={this.state.isAllChecked} clearDone={this.clearDone.bind(this)} {...props} changeTodoState={this.changeTodoState.bind(this)}/>
</div>
)
}
<TodoFooter {...props} /> // spread操作符
<TodoFooter todoCount={props.todoCount} todoDoneCount={props.todoDoneCount} />
React.render(<App/>, document.getElementById("app"));
import React from "react";
class TodoHeader extends React.Component {
// 绑定键盘回车事件,添加新任务
handlerKeyUp(event){
if(event.keyCode === 13){
let value = event.target.value;
if(!value) return false;
let newTodoItem = {
text: value,
isDone: false
};
event.target.value = "";
this.props.addTodo(newTodoItem);
}
}
render(){
return (
<div className="panel-header">
<input onKeyUp={this.handlerKeyUp.bind(this)} type="text" placeholder="what's your task ?"/>
</div>
)
}
}
export default TodoHeader;
import React from "react";
export default class TodoFooter extends React.Component{
// 处理全选与全不选的状态
handlerAllState(event){
this.props.changeTodoState(null, event.target.checked, true);
}
// 绑定点击事件,清除已完成
handlerClick(){
this.props.clearDone();
}
render(){
return (
<div className="clearfix todo-footer">
<input checked={this.props.isAllChecked} onChange={this.handlerAllState.bind(this)} type="checkbox" className="fl"/>
<span className="fl">{this.props.todoDoneCount}已完成 / {this.props.todoCount}总数</span>
<button onClick={this.handlerClick.bind(this)} className="fr">清除已完成</button>
</div>
)
}
}
import React from "react";
import TodoItem from "./TodoItem.js"
export default class TodoMain extends React.Component{
// 遍历显示任务,转发props
render(){
return (
<ul className="todo-list">
{this.props.todos.map((todo, index) => {
return <TodoItem key={index} {...todo} index={index} {...this.props}/>
})}
</ul>
)
}
}
import React from "react";
export default class TodoItem extends React.Component{
// 处理任务是否完成状态
handlerChange(){
let isDone = !this.props.isDone;
this.props.changeTodoState(this.props.index, isDone);
}
// 鼠标移入
handlerMouseOver(){
React.findDOMNode(this.refs.deleteBtn).style.display = "inline";
}
// 鼠标移出
handlerMouseOut(){
React.findDOMNode(this.refs.deleteBtn).style.display = "none";
}
// 删除当前任务
handlerDelete(){
this.props.deleteTodo(this.props.index);
}
render(){
let doneStyle = this.props.isDone ? {textDecoration: 'line-through'} : {textDecoration: 'none'};
return (
<li
onMouseOver={this.handlerMouseOver.bind(this)}
onMouseOut={this.handlerMouseOut.bind(this)}
>
<input type="checkbox" checked={this.props.isDone} onChange={this.handlerChange.bind(this)}/>
<span style={doneStyle}>{this.props.text}</span>
<button style={{'display': 'none'}} ref="deleteBtn" onClick={this.handlerDelete.bind(this)} className="fr">删除</button>
</li>
)
}
}
机械节能产品生产企业官网模板...
大气智能家居家具装修装饰类企业通用网站模板...
礼品公司网站模板
宽屏简约大气婚纱摄影影楼模板...
蓝白WAP手机综合医院类整站源码(独立后台)...苏ICP备2024110244号-2 苏公网安备32050702011978号 增值电信业务经营许可证编号:苏B2-20251499 | Copyright 2018 - 2025 源码网商城 (www.ymwmall.com) 版权所有