zoukankan      html  css  js  c++  java
  • 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;
    
     }
    
  • 相关阅读:
    10. Regular Expression Matching
    9. Palindrome Number
    6. ZigZag Conversion
    5. Longest Palindromic Substring
    4. Median of Two Sorted Arrays
    3. Longest Substring Without Repeating Characters
    2. Add Two Numbers
    链式表的按序号查找
    可持久化线段树——区间更新hdu4348
    主席树——树链上第k大spoj COT
  • 原文地址:https://www.cnblogs.com/chenhaiyun/p/14815322.html
Copyright © 2011-2022 走看看