代码实现
先传个代码,明天下课讲讲思路
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
/* 列表被选中的样式 */
.active{
background: pink;
}
</style>
</head>
<body>
<div id="app"></div>
<script src="./babel.min.js"></script>
<script src="./react.development.js"></script>
<script src="./react-dom.development.js"></script>
<script type="text/babel">
// 主组件
class Main extends React.Component {
constructor() {
super()
this.state = {
//在定义一个数组 用于增删查
//caozuolist
list: [
{
id: 1,
name: '吃饭',
// isActive属性控制当前自己这项是否被选中
// 如果为true对应的li要增加.active
isActive: false
},
{
id: 2,
name: '睡觉',
isActive: false
},
{
id: 3,
name: '写代码',
isActive: true
}
],
//showlist
showList:[
{
id: 1,
name: '吃饭',
isActive: false
},
{
id: 2,
name: '睡觉',
isActive: false
},
{
id: 3,
name: '写代码',
isActive: true
}
]
}
//绑定this
this.add=this.add.bind(this)
this.del=this.del.bind(this)
this.change=this.change.bind(this)
this.search=this.search.bind(this)
}
add(data){
//向list数组中追加方法 传给子组件 深拷贝 进行修改
let list =[...this.state.list]//对深拷贝的数组进行修改
list.push({
id: new Date().getTime(),//获取1970年1月1日到此刻的毫秒数,一定不会重复,保证id唯一
name:data,
isActive:false
})
this.setState({
list,
//you 新定义的list
showList:list
})
}
//父组件的删除方法 删除list数组中的某一项
del(id) {
//filter 对数组进行过滤返回满足条件的新数组
let list =this.state.list.filter(item=>{
return item.id!==id
})
this.setState({
list,
showList:list
})
}
//根据传递过来的id修改list中的数据
change(id){
let list=[...this.state.list]
//对满足条件的list元素的isActive 取反
list.forEach(item=>{
if(item.id===id){
item.isActive=!item.isActive
}
})
this.setState({
list,
showList:list
})
}
// 查询数组 查找符合条件的元素
search(value){
//list是过滤后满足条件的数组 原数组改变,导致数据丢失
let list =this.state.list.filter(item=>{
return item.name.includes(value)
})
{/*this.setState({
list
})*/}
this.setState({
showList:list
})
}
render() {
return (
<div>
<h1>To Do List</h1>
{/* 引入搜索组件 */}
<Search searchFun={this.search}/>
{/* 引入添加组件 */}
<Add addFun={this.add}/>
{/* 引入列表组件 list->showlist */}
<List list={this.state.showlist} delFun={this.del} changeFun={this.change}/>
</div>
)
}
}
// search组件
class Search extends React.Component {
constructor() {
super()
this.searchHandler=this.searchHandler.bind(this)
//定义一个ref实例
this.myInput=React.createRef()
}
//键盘在输入过程中每次抬起就去对list数组进行间接过滤,过筛显示符合条件的选项
searchHandler(){
//1.获取input的value
console.log(this.myInput.current.value)
//2.调用父组件中的search方法,传value
this.props.searchFun(this.myInput.current.value)
}
render() {
return (
<div>
搜索:
{/*onkeyup键盘抬起*/}
<input type="text" ref={this.myInput} onKeyUp={this.searchHandler}/>
</div>
)
}
}
// 添加组件
class Add extends React.Component {
constructor() {
super()
this.addHandler= this.addHandler.bind(this)
//创建一个引用实例
this.myInput=React.createRef()
}
//获取input中value的值 间接追加到list数组中
addHandler(){
//1.获取input中的value
console.log(this.myInput.current.value)
//2.调用父组件中的add方法并且传值
this.props.addFun(this.myInput.current.value)
//3.清空输入框
this.myInput.current.value=''
}
render() {
return (
<div>
添加:
{/*ref是对input的引用 newway*/}
<input type="text" ref={this.myInput}/>
<button onClick={this.addHandler}>add</button>
</div>
)
}
}
// 列表组件
class List extends React.Component {
constructor() {
super()
}
//删除 间接修改
delHandler(id){
//调用父组件删除方法
this.props.delFun(id)
}
//修改方法
changeHandler(id){
//调用父组件的修改方法并传递id
this.props.changeFun(id)
}
render() {
// this.props接收父组件传过来的所有的属性,是对象类型的
// { list } 通过解构的方式获取this.props.list
let { list } = this.props
return (
<ul>
{
// 列表渲染
list.map(obj => {
return (
// class -> className
<li key={obj.id} className={obj.isActive ? 'active' : ''}>
{/* checked -> defaultChecked 表示复选框是否被勾选 */}
<input type="checkbox" defaultChecked={obj.isActive} onChange={this.changeHandler.bind(this,obj.id)} />
<span>{obj.name}</span>
<button onClick= {this.delHandler.bind(this,obj.id)}>delete</button>
</li>
)
})
}
</ul>
)
}
}
ReactDOM.render(<Main/>, document.querySelector('#app'))
</script>
</body>
</html>