react系列---【react安装脚手架、组件、jsx语法、事件处理、state】

1.脚手架

npm i create-react-app -g //安装脚手架
create-react-app demo // 创建项目
cd demo //进入项目
npm start //启动项目

目录介绍:

my-app
    - node_modules    		--npm包
    - public            		--服务器目录
        - favicon.ico       		--页面图标
        - index.html        		--页面主入口
        - manifest.json    			--页面配置文件
    - src                  	--项目源码
        - App.css              	--根组件样式
        - App.js                	--根组件模板
        - App.test.js              	--根组件测试(删)
        - index.css               	--全局css样式(删)
        - index.js                	--脚本主入口(删)
        - logo.svg      			--图片文件(删)
        - serviceWorker.js 			--离线访问服务(删)
    - .gitignore             	--git忽略文件配置
    - package.json          	--npm配置
    - package-lock.json      	--锁定安装时的包的版本号
    - README.md           	--项目说明文档
    - yarn.lock              	--yarn配置

src/index.js

import React from 'react';
import ReactDOM from 'react-dom';

import App from './App';


ReactDOM.render(
  <App />,
  document.getElementById('root')
);

src/App.js

function App() {
  return (
    <div className="App">
      123
    </div>
  );
}

export default App;

2.JSX语法

import React from "react";

// 1.非表单元素:div span ...   {变量}
// 2.媒体元素:img     {变量}
// 3.条件渲染
// 4.列表渲染
var name = "妲己";
var name2 = "王昭君";
let price = 20;
let imgUrl =
  "https://img2.baidu.com/it/u=1376319214,2872501189&fm=26&fmt=auto&gp=0.jpg";
let status = 1;
let isshow = false;
let arr = [
  { id: 1, title: "哈哈", con: "和越南总统对话", color: "red" },
  {
    id: 2,
    title: "嘿嘿",
    con: "银行卡被盗刷,银行应该负责赔偿",
    color: "blue",
  },
  { id: 3, title: "哈哈", con: "和越南总统对话", color: "pink" },
  {
    id: 4,
    title: "嘿嘿",
    con: "银行卡被盗刷,银行应该负责赔偿",
    color: "orange",
  },
  { id: 5, title: "哈哈", con: "和越南总统对话", color: "lime" },
  {
    id: 6,
    title: "嘿嘿",
    con: "银行卡被盗刷,银行应该负责赔偿",
    color: "green",
  },
];
/*
let elArr=[
    <li>哈哈</li>,
    <li>嘿嘿</li>
]*/

let elArr = arr.map((item) => {
  return (
    <li key={item.id}>
      <h3>{item.title}</h3>
      <p>{item.con}</p>
    </li>
  );
});

function DataBind() {
  return (
    <div>
      {/* 1.{}可以绑定变量 */}
      <div>name:{name}</div>
      {/* 2.{} 可以绑定表达式 */}
      <div>{status === 1 ? name : name2}</div>
      {/* 3.{} 绑定方法    */}
      <div>price:{price.toFixed(2)}</div>
      {/* 4。属性绑定 {变量} */}
      <img src={imgUrl} alt="" />
      <div aa={name}>哈哈哈</div>

      {/* 5.条件渲染  {三元表达式} ,如果什么都不出,写null */}
      {status === 1 ? <button>是</button> : <button>否</button>}

      {isshow ? <div>弹框</div> : null}
      {/* 6.列表渲染 map */}
      <ul>{elArr}</ul>
      {/* 推荐在页面map  */}
      <ol>
        {arr.map((item) => {
          return (
            <li key={item.id}>
              <h3>{item.title}</h3>
              <p>{item.con}</p>
            </li>
          );
        })}
      </ol>
      {arr.length === 0 ? <div>暂无数据</div> : null}

      {/* 7.注释 */}

      {/* 8.如果标签比较多,就用()包一下 */}

      {/* 9. 类名使用className,而不是class */}
      <div className="red">测试样式</div>

      {/* 10.动态类名 className={三元} */}
      <ol>
        {arr.map((item, index) => {
          return (
            <li className={index % 2 === 0 ? "red" : "blue"} key={item.id}>
              {item.title}
            </li>
          );
        })}
      </ol>

      {/* 11动态行间样式 style={json} */}
      <ol>
        {arr.map((item, index) => {
          return (
            <li style={{ color: item.color }} key={item.id}>
              {item.title}
            </li>
          );
        })}
      </ol>
      <div style={{ background: "red" }}>真好</div>

      {/* 12. jsx中遇到了< 由html解析,遇到{ 由js解析 */}
    </div>
  );
}
export default DataBind;

3.组件

3.1组价注册

函数定义:
import React from "react"


function FunctionCreate(props){
    console.log(props);
    return (
        <div className="box">
            <h3>函数创建</h3>
            <div>msg:{props.msg}</div>
        </div>
        
    )
}

export default FunctionCreate;
类定义:
import React, { Component } from "react";

class ClassCreate extends Component {
  // 构造函数:要么不写,写了就得加super()
  constructor() {
    super();
    this.name = "妲己";
    this.state={
        num:1
    }
  }
 
  //渲染的函数
  render() {
    console.log(this);
    return (
      <div className="box">
        <h3>类定义</h3>
        
        <div>msg:{this.props.msg}</div>
      </div>
    );
  }
}
export default ClassCreate;

3.2对比两种注册方式

1.类定义组件有state,函数定义没有;
2.类定义组件有生命周期函数,函数定义没有;
3.对于父组件传递的数据,类定义通过this.props接收,函数定义通过props接收;
4.类定义组件每一次调用都会创建一个实例对象,函数只是纯计算,返回html,效率角度考虑,函数更好一些。

3.3组件注册注意点:

// 1.组件名称首字母要大写
// 2.可以使用存在的标签的大写命名
// 3.中间有大写,不需要使用烤串写法
// 4.模板只能有1个根节点

4.事件处理

import React, { Component } from "react"
// 1.如何绑定事件
// 2.事件如何传参?
// 3.event对象如何获取?
// 4.阻止默认、阻止传播
// 5.捕获如何实现?

class Event extends Component {
    fn() {
        console.log("123");
        console.log(this);
    }
    add(a, b) {
        console.log(a + b);
    }
    //获取event
    getEvent(e) {
        console.log(e);
    }

    // 获取event
    getEvent2(a, b) {
        console.log(a, b);
    }

    yj(e) {
        e.preventDefault()
        console.log("右键了");
    }

    outerClick() {
        console.log("outer click");
    }
    innerClick(e) {
        e.stopPropagation()
        console.log("inner click");
    }

    render() {

        return (
            <div className="box">
                <h3>事件处理</h3>

                {/* 1.如何绑定事件 */}
                <div className="box">
                    <h4>1.如何绑定事件</h4>
                    {/* 箭头函数绑定不需要this */}
                    {/* bind 绑定第一个参数是调用该函数的对象,一般使用this */}
                    <button onClick={(e) => this.fn()}>箭头函数:点击执行fn</button>
                    <button onClick={this.fn.bind(this)}>bind:点击执行fn</button>
                </div>

                {/* 2.事件如何传参? */}
                <div className="box">
                    <h4>2.事件如何传参?</h4>
                    {/* 箭头函数正常传 */}
                    {/* bind 的第2个实参传递给函数的第1个形参*/}
                    <button onClick={() => this.add(10, 20)}>箭头函数:10+20</button>
                    <button onClick={this.add.bind(this, 3, 10)}>bind:3+10</button>
                </div>

                {/* 3.event对象如何获取? */}
                <div className="box">
                    <h4> 3.event对象如何获取?</h4>
                    {/* 箭头函数显示传参,箭头函数形参就是event */}
                    {/* bind 隐式传参:最后一位参数就是even,但是不写*/}
                    <button onClick={(e) => this.getEvent(e)}>箭头函数:获取event</button>
                    <button onClick={this.getEvent.bind(this)}>bind:获取event</button>

                    <button onClick={(e) => this.getEvent2(10, e)}>箭头函数:获取event</button>
                    <button onClick={this.getEvent2.bind(this, 10)}>bind:获取event</button>
                </div>

                {/* 4.阻止默认  e.preventDefault() 注意:return false不行*/}
                <div className="redBox" onContextMenu={(e) => this.yj(e)}></div>

                {/* 5.阻止传播 e.stopPropagation() */}
                <div className="outer" onClick={() => this.outerClick()}>
                    <div className="inner" onClick={(e) => this.innerClick(e)}>阻止传播</div>
                </div>

                {/* 6.捕获 */}
                <div className="outer" onClickCapture={() => this.outerClick()}>
                    <div className="inner" onClickCapture={(e) => this.innerClick(e)}>捕获</div>
                </div>
            </div>
        )
    }
}


export default Event



5.state

import React, { Component } from "react";
import Child from "./Child";
class State extends Component {
  // 0.state是最小的UI状态集合
  // 1.初始化state 在constructor中
  // 2.取值  let { name, age, sex } = this.state;
  // 3.如果state全部要传递给子组件,可以使用{...this.state}  {...props}
  /* 4.修改state:setState({新值})
    4.1 直接修改state,数据会变,页面不会渲染
    4.2 修改state应该使用setState(),setState()的调用会引起render的重新执行
    4.3 render中千万不要调用setState(),否则陷入死循环
    4.4 修改数组: 1取 2做 3放
    4.5 修改json (1) 取 做 放 (2)...
    4.6 this.setState()是异步的,如果想要使用setState()之后的新值,需要在回调函数中处理
  */
  //   5.json和数组不能直接通过{}展示在页面,需要先JSON.stringify()
  constructor() {
    super();
    this.state = {
      name: "妲己",
      age: 20,
      sex: "女",
      arr: [
        { id: 1, name: "哈哈" },
        { id: 2, name: "嘻嘻" },
        { id: 3, name: "嘿嘿" },
      ],
      json: {
        name: "赵丽颖",
        sex: "女",
      },

      arr3:["赵丽颖","女","演员"],
      num: 10,
      num2: 11,
    };
  }
  changeName(name) {
    //   直接修改state,数据会变,页面不会渲染
    // this.state.name = name;

    // 修改state应该使用setState(),setState()的调用会引起render的重新执行
    // render中千万不要调用setState(),否则陷入死循环
    this.setState({
      name: name,
    });
  }
  //修改数组 1取 2做 3放
  del(index) {
    let { arr } = this.state;
    arr.splice(index, 1);

    this.setState({
      arr: arr,
    });
  }
  // 修改json (1) 取 做 放 (2)...
  changeJsonName(name) {
    /*
    let { json } = this.state;
    json.name = name;
    this.setState({
      json: json,
    });*/

    this.setState({
      json: {
        ...this.state.json,
        name,
      },
    });
  }
  //   num++
  add() {
    //  this.setState()是异步的,如果想要使用setState()之后的新值,需要在回调函数中处理
    this.setState(
      {
        num: this.state.num + 1, //11
      },
      () => {
        this.setState({
          num2: this.state.num * this.state.num, //11*11
        });
      }
    );
      /*
      axios().then(res=>{
          this.setState({
              arr:res.data.list
          },()=>{
            console.log(this.state.arr);
          })
      })*/

  }
  render() {
    console.log("render is running ...");

    /*
    let name=this.state.name
    let age=this.state.age
    let sex=this.state.sex*/
    let { name, age, sex, arr, json, num, num2,arr3 } = this.state;

    return (
      <div className="box">
        <h3>state</h3>
        <div>num:{num}</div>
        <button onClick={() => this.add()}>++</button>
        <div>num2:{num2}</div>

        <hr />

        <div>name:{this.state.name}</div>
        <div>age:{this.state.age}</div>
        <div>sex:{this.state.sex}</div>

        <hr />
        <div>name:{name}</div>
        <div>age:{age}</div>
        <div>sex:{sex}</div>
        {/* 如果state全部要传递给子组件,可以使用{...this.state} */}
        <Child {...this.state}></Child>
        <button onClick={() => this.changeName("貂蝉")}>貂蝉</button>
        <ul>
          {arr.map((item, index) => (
            <li key={item.id}>
              {item.name} <button onClick={() => this.del(index)}>删除</button>
            </li>
          ))}
        </ul>
        {/* <h3>{JSON.stringify(json)}</h3> */}
        {/* <h3>{json}</h3> */}
        <button onClick={() => this.changeJsonName("赵露思")}>赵露思</button>

        ================================================================
        {/* 可以展示页面*********** */}
        <h3>{arr3}</h3>

        {/* arr数值套json不展示页面,需要转换{JSON.stringify(arr)}***************** */}
        <h3>{arr}</h3>
        <h3>{JSON.stringify(arr)}</h3>

        <button onClick={() => this.changeJsonName("赵露思")}>赵露思</button>
      </div>
    );
  }
}
export default State;

6.补充关于js 冒泡、阻止默认行为、事件的兼容性写法

冒泡的兼容性写法

  可以用event.stopPropagation();方法来阻止冒泡,但是在IE下不支持此方法,但可以利用其event.cancelBubble属性设置为true阻止。

 if(event.stopPropagation){

     //ie不支持

           event.stopPropagation();
    
        }else{

     //ie支持

           event.cancelBubble = true;

   }
阻止默认行为的兼容性写法
  1. w3C标准的阻止默认行为的方法是preventDefualt()

  2. IE中阻止事件的默认行为的属性是returnValue,为:true不阻止,false:阻止事件的默认行为

 if (e.preventDefault) {

  //w3c  

     e.preventDefault();  

  } else{  

  //ie  

    e.returnValue = false;

  }  

如果我们未通过addEventListener()函数来绑定事件的话,若要禁止默认事件,可以用return false; 但如果要用addEventListener()或者attachEvent()来绑定,就要用preventDefault()方法或者设置事件对象的returnValue属性。

注意:如果在jQuery中return false;相当于同时调用了event.stopPropagation()和event.preventDefault(),事件的默认行为不会被执行,事件也不会冒泡向上传递。

事件的兼容写法:
function getEvent(event){   

//获取事件对象的兼容性写法

  return event || window.event;

 }

posted on 2021-05-26 22:32  码农小小海  阅读(82)  评论(0编辑  收藏  举报

导航