todolist形式的搜索框,分开组件写的,点击上下键时,框内显示当前选中的内容

### 首先  安装react 脚手架

cnpm  install  create-react-app  -g      //只需要在电脑上安装一次就好了,以后不用再下载了

### 创建项目

create-react-app  项目名( todo )

### 进入项目todo  运行项目

npm start   ---------或者下载 cnpm install yarn --save   后输入yarn  start 也可以运行项目

### 创建三个文件夹分别为:App    todo    list   

将App.js  和App.css 放入到 App文件夹中------>在到index.js中 把引入App.js的路径改一下

import App from './App/App'; 
在todo list 这两个文件夹中 分别在创建一个js文件,一个css样式文件
在这里就简单的创建to.js to.css 和 list.js list.css

###在to.js 中写入代码

import React, {Component} from 'react'; //---->引入react模块
import "./to.css" //---->引入to.css样式文件
class To extends Component {
constructor(props) {
super(props);
this.state={ //--->初始化状态 ,所有添加的数据都从这里获取
tt:"",
cc:false //--->定义一个状态为false的属性,通过属性的true,false通过三目运算符来判断
}
}

ch(e){ //---->获取input框中用户当前输入的数据
this.setState({tt:e.target.value});//--->更新状态后渲染
}
add(){ //添加 子组件通过事件触发的方法,通过方法的参数,将值传递给父组件
this.props.ad(this.state.tt) //--->将当前的用户输入的数据传递给父组件
this.state.tt="" //--->让当前用户点击添加后,input框中的值为空
}
render() {
return (
<div className="zjb_box" onClick={this.props.ak}> {/* 这是通过兄弟组件传值的方法,把父组件中的方法调用过来*/}
{/* 获取用户的value 值得时候,需要加一个onChange事件 这是在react中的获取value值的方法 */}
<input className="zjb_in" type="text" value={this.state.tt}
onChange={this.ch.bind(this)} onFocus={this.props.bb}
onKeyDown={this.props.asss}/>{/* 当按键按下的时候,调用了父组件App.js中的方法*/}
<button onClick={this.add.bind(this)}>百度一下</button>
<div className="ss" onClick={this.props.as}></div>{/*这是让添加数据的ul框能在鼠标点击空白区域隐藏的一种方法,有点low,后面还有一种更好的办法*/}
</div>
);
}
}

export default To;{/*导出文件*/}

### 在to.css中的样式,简写的,样式就不注释 了

body,div,input,p{
margin: 0;
padding: 0;
}
.zjb_box{
width: 600px;
height: 600px;
border: 1px solid #000;
margin: 100px auto;
position: relative;
}
.zjb_in{

width: 400px;
height: 40px;
margin: 20px 20px;
}
button{
width: 100px;
height: 40px;
}
.ss{
width: 600px;
height: 600px;
border: 2px solid #ccc;
}

###在list.js中写入代码 

import React, {Component} from 'react';//--->引入react模块
import "./list.css"//--->引入list.css样式
class List extends Component {
constructor(props) {
super(props);
}

del(n){//删除的方法 n为当前的下标
this.props.remove(n);//--->将当前的下标传入到父组件中
}

render() {
return (
<div className="zjb_bb" style={{display:this.props.aa?"block":"none"}}>
<ul style={{display:this.props.aa?"block":"none"}}>{/*如果是true,就显示,false就隐藏*/}
{
this.props.zjb_ch.map((v,i)=>{ {/*注释this.props.zjb_ch==i?"ac":""*/}
return <li key={i} className={this.props.ac===i?"ac":""}>
{v}
{/*单行显示删除,可以num=0;this.state.num===i?"显示":"否则隐藏"*/}
<a href="#" onClick={this.del.bind(this,i)}
className={this.props.ac===i?"za":" "}>删除</a>{/*通过当前下标一样的时候,显示删除,不一样的,就为空*/}

{/*<div className="asas"></div>*/}
</li>
})
}
</ul>
</div>
);
}
}

export default List;{/*导出*/}


###在list.css中写入样式

*{
margin: 0;
padding: 0;
list-style: none;
}
.zjb_bb{
position: absolute;
width: 402px;
top: 164px;
left: 286px;
/*border: 1px solid #000;*/
}
.zjb_bb>ul{
display: none;
/*height: 400px;*/
border: 1px solid #000;
}
.ac{
background: red;
}
.za{
float: right;
color: #000;
margin-right: 20px;
}
.asas{
width: 1000px;
height: 1000px;
border: 2px solid greenyellow;
}

###最后回到主文件App.js中

import React from 'react';             //--->引入react模块
import To from "../todo/To"; //--->引入to.js文件
import List from "../list/list"; //--->引入list.js文件


class App extends React.Component {
constructor(props) {
super(props);
var arr0=localStorage.getItem("arr"); //---> 获取本地的储存
if(arr0){ //本地储存中如果有数据的话就会执行if中的true
var arr1=JSON.parse(arr0); //--->将字符串转换为对象
}else{
var arr1=[]; //--->如果本地储存中没有数据,就是null,先执行if中的else 创建一个新数组, 之后再渲染,输出本地储存,在渲染到页面上
}

this.state={
list:arr1,
cc:false,
num:0
}
}
add1(v){ //--->添加的方法 v就是to.js中传过来的input框中用户输入的值
var list=this.state.list; //获取当前的初始状态中的list
list.push(v); //将用户输入的值添加到list中
var list1=JSON.stringify(list);//--->将当前的list是拼接的对象转换为字符串
localStorage.setItem("arr",list1);//--->将数据储存到本地内存中
this.setState({list}) //--->更新状态后 页面又渲染了一次
// alert(this.state.list)
}

del1(n){//删除的方法 n为list.js中传递过来的下标
var list=this.state.list;
list.splice(n,1);
var list1=JSON.stringify(list);
localStorage.setItem("arr",list1);
this.setState({list})
}
bb1(){//通过cc的属性来判断,当点击后让cc的状态为true
this.setState({cc:true})
}
ass(){
this.setState({cc:false})
}
asa(e){//键盘事件,上下键
if(e.keyCode===38){
console.log(e.keyCode);
var n=this.state.num;//--->通过num判断,在list.js中如果num和下标i相等的话,就让ac的class样式显示
n--;
if(n<0){
n=this.state.list.length-1
}
this.setState({num:n,tt:this.state.list[n]})
}
if(e.keyCode===40){
// alert(11)
var n=this.state.num;
n++;
if(n>this.state.list.length-1){
n=0
}
this.setState({num:n,tt:this.state.list[n]})
}
}
// dcc(e){
// if(e.target.nodeName=="DIV"){--->获取当前div的节点DIV,能获取到就改变cc的boolearn值
// this.setState({cc:false})
// }
//隐藏
hide=(e)=>{//--->通过获取当前的大div的节点来改变cc的true和false
console.log(e.target.nodeName)
if(e.target.nodeName=="DIV"){
this.setState({cc:false})
}
}
// }
render() {
return (
<div>
<To ad={this.add1.bind(this)} bb={this.bb1.bind(this)}
as={this.ass.bind(this)} ak={this.hide.bind(this)}
cc={this.state.cc} asss={this.asa.bind(this)}></To>{/*这是to.js中的组件*/}
<List zjb_ch={this.state.list} remove={this.del1.bind(this)}
aa={this.state.cc} ac={this.state.num}></List>{/*这是list.js中的组件*/}
</div>
);
}
}



export default App;

###如果有喜欢研究的志同道合的朋友,欢迎一起交流!!!

猜你喜欢

转载自www.cnblogs.com/zhangMr/p/11784521.html
今日推荐