zoukankan      html  css  js  c++  java
  • React

    React

    React 版本 16.+

    1.全局安装create-react-app 创建项目

    全局安装脚手架

    $ npm install -g create-react-app
    

    如果不想全局安装,可以直接使用npx

    $ npx create-react-app your-app	也可以实现相同的效果
    

    创建一个项目

    $ create-react-app your-app 注意命名方式
    

    生成项目的目录结构如下:

    ├── README.md							使用方法的文档
    ├── node_modules					所有的依赖安装的目录
    ├── yarn-lock.json			锁定安装时的包的版本号,保证团队的依赖能保证一致。
    ├── package.json					
    ├── public								静态公共目录
    └── src									开发用的源代码目录
    

    2.react虚拟DOM 以及 16版本以后的react fiber算法

    1.react和vue一样有虚拟dom的机制,这也是react高性能的体现,虚拟dom就是一个jsx的对象模拟真实dom的结构,需要靠render函数来将虚拟dom解析成真实dom渲染到页面上

    2.在react 16版本之前比较两次虚拟dom改变的算法是diff算法,diff算法是比较两次虚拟dom 的不同,生成path文件,再通过render函数来渲染成真实的dom结构。

    在16版本中react采用了新的算法react fiber。react fible的方法其实很简单——分片,把一个耗时长的任务分成很多小片,每一个小片的运行时间很短,虽然总时间依然很长,但是在每个小片执行完之后,都给其他任务一个执行的机会,这样唯一的线程就不会被独占,其他任务依然有运行的机会。


    3.函数式组件

    import React from 'react'
    import ReactDom from 'react-dom'
    
    //const App = <h1>hello react</h1>//用一个变量存结构再传入到ReactDom.render中
    
    const app = ( a ) => {                     //也可以用一个函数来传递结构
        return (<h1>hello React 你好--{a.name}</h1>)//传入参数的时候要使用单括号 注释也要单括号
    }
    
    ReactDom.render( //ReactDom是jsx模板,用render方法将jsx模板转换成真实dom
        //app
        <App name = 'zhuxiaohang'></App>    //将方法用组件的形式使用
        ,
        document.getElementById('root')
    )
    

    4.类组件

    // React 类组件
    //组件也可以是一个类
    
    import React,{Component} from 'react'
    
    //创建类 【组件】
    class App extends Component{
        render(){   //render方法的作用就是将jsx解析成虚拟dom对象解构
            return ( 
                <div>
                    <h1>hello 这里是React 类组件的创建形式</h1>
                </div>
            )
        }
    }
    
    //导出类
    export default App
    

    当类组件要接收绑定在组件上的属性时候 需要使用props属性

    组件上的属性

    <App name='zhuxiaohang'></App>
    

    获得该属性

    class App extends Component{
        render(){   //render方法的作用就是将jsx解析成虚拟dom对象解构
    
            console.log(this)//App继承了Component里的props属性
    
            return ( 
                <div>
                    <h1>hello 这里是React 类组件的创建形式 ————{this.props.name} </h1>
                </div>
            )
        }
    }
    

    es6 class组件其实就是一个构造器,每次使用组件都相当于实例化组件


    5.组件的组合,嵌套

    将一个组件渲染到某一节点里的时候,会将这个节点里原有内容覆盖

    组件嵌套的方式就是将子组件写入到父组件的模板中,因为react没有vue中的内容分发机制(slot),所以我们在一个组件的模板中只能看到父子关系

    组件的嵌套

    子组件

    import React, {Component} from 'react'
    
    class Child extends Component{
        render(){ //jsx只有一个唯一的根元素
            return (
                <div>
                    <h3>这里是Child 类组件</h3>
                </div>
            )
        }
    }
    
    export default Child
    

    嵌套到父组件中

    //创建类 【组件】
    class App extends Component{
        render(){   //render方法的作用就是将jsx解析成虚拟dom对象解构
    
            console.log(this)
    
            return ( 
                <div>
                    <h1>hello 这里是React 类组件的创建形式 ————{this.props.name} </h1>
                    <hr/>
                    <Child></Child>	//子组件嵌套
                </div>
            )
        }
    }
    
    //导出类
    export default App
    

    但是组件中写的内容会被覆盖 如下:

    ReactDom.render( //ReactDom是jsx模板,用render方法将jsx模板转换成真实dom
        // //app
        // app({                   //一旦使用函数传递就可以设置参数
        //     name:'zhuxiaohang'
        // }),
        <App name='zhuxiaohang'>
            <Child></Child>			//这样插入子组件没有效果
        </App>,   
        document.getElementById('root')
    )
    

    解决方法:

    在父组件中写{this.props.children} 相当于vue中的插槽

    class App extends Component{
        render(){   //render方法的作用就是将jsx解析成虚拟dom对象解构
    
            console.log(this)
    
            return ( 
                <div>
                    <h1>hello 这里是React 类组件的创建形式 ————{this.props.name} </h1>
                    <hr/>
                    {this.props.children}//这样子组件就可以显示了
                </div>
            )
        }
    } 
    

    组件嵌套的写法

    1.将子组件以标签的形式写在父组件的模板中

    2.将子组件以标签的形式写在父组件的内容中,通过模板中{this.props.children}来接收


    6.jsx原理

    要明白jsx原理,需要先明白如何用js对象来表现一个dom元素的结构

    看下面的dom结构

    <div class='app' id='appRoot'>
      <h1 class='title'>欢迎进入React的世界</h1>
      <p>
        React.js 是一个帮助你构建页面 UI 的库
      </p>
    </div>
    

    上面这个 HTML 所有的信息我们都可以用 JavaScript 对象来表示:

    {
      tag: 'div',
      attrs: { className: 'app', id: 'appRoot'},
      children: [
        {
          tag: 'h1',
          attrs: { className: 'title' },
          children: ['欢迎进入React的世界']
        },
        {
          tag: 'p',
          attrs: null,
          children: ['React.js 是一个构建页面 UI 的库']
        }
      ]
    }
    

    但是用 JavaScript 写起来太长了,结构看起来又不清晰,用 HTML 的方式写起来就方便很多了。

    于是 React.js 就把 JavaScript 的语法扩展了一下,让 JavaScript 语言能够支持这种直接在 JavaScript 代码里面编写类似 HTML 标签结构的语法,这样写起来就方便很多了。编译的过程会把类似 HTML 的 JSX 结构转换成 JavaScript 的对象结构。

    下面代码:

    mport React from 'react'
    import ReactDOM from 'react-dom'
    
    class App extends React.Component {
      render () {
        return (
          <div className='app' id='appRoot'>
            <h1 className='title'>欢迎进入React的世界</h1>
            <p>
              React.js 是一个构建页面 UI 的库
            </p>
          </div>
        )
      }
    }
    
    ReactDOM.render(
    	<App />,
      document.getElementById('root')
    )
    

    编译之后将得到这样的代码:

    import React from 'react'
    import ReactDOM from 'react-dom'
    
    class App extends React.Component {
      render () {
        return (
          React.createElement(
            "div",
            {
              className: 'app',
              id: 'appRoot'
            },
            React.createElement(
              "h1",
              { className: 'title' },
              "欢迎进入React的世界"
            ),
            React.createElement(
              "p",
              null,
              "React.js 是一个构建页面 UI 的库"
            )
          )
        )
      }
    }
    
    ReactDOM.render(
    	React.createElement(App),
      document.getElementById('root')
    )
    

    React.createElement` 会构建一个 JavaScript 对象来描述你 HTML 结构的信息,包括标签名、属性、还有子元素等, 语法为

    React.createElement(
      type,
      [props],
      [...children]
    )
    

    所谓的 JSX 其实就是 JavaScript 对象,所以使用 React 和 JSX 的时候一定要经过编译的过程:

    JSX —使用react构造组件,bable进行编译—> JavaScript对象 — `ReactDOM.render()`—>DOM元素 —>插入页面
    

    7.组件中的dom样式

    1.行内样式

    // 注意这里的两个括号,第一个表示我们在要JSX里插入JS了,第二个是对象的括号
      <h3> 第一种:行内样式 </h3>
            <p style = { { '100px',height: '100px',background: 'red',color: 'white'} }> 行内样式 </p>
    
            <p style = { this.styles }> 行内样式 </p>
    

    行内样式需要写入一个样式对象,而这个样式对象的位置可以放在很多地方,例如render函数里、组件原型上、外链js文件中

    2.外部引用

    // 引用外部样式文件
    import './StyleComponent.css'
    
    
    <h3> 第二种: 外部引用 </h3>
    <p className = "size bg"></p>	//注意用的是classname不是class
      
    

    3.第三方工具classname

    安装cnpm i classname

    import classname from 'classname'
    
    <h3> 第三种: 使用classname/classnames 第三方包来定义类名 </h3>
            <p
              className = {
                classname({
                  size: true,
                  bg: true
                })
              }
            ></p>
    

    4.样式组件

    要安装第三方包``styled-components`

    // 使用样式组件
    
    import styled from 'styled-components'
    
    // 变量名称是大写
    // 这里面写的就是css样式属性了
    const Container = styled.div`
       200px;
      height: 200px;
      background: yellow;
      color: white;
    `
    
    <h3> 第四种: 样式组件 【 样式也可以是一个组件】 </h3>
            {/* 使用样式组件 */}
            <Container/>
            <Wrapper color = "pink"> 
              <p> 这是样式属性 </p>
              <span> 这是样式组件的子元素 </span>
            </Wrapper>
    

    8.组件的数据挂载方式

    React中数据分为两个部分

    1.属性

    2.状态(频繁变化的就写成状态)

    vue中数据只有状态这一种类型

    属性(props)
    1.外部传入

    1.父组件传数据给子组件

    父组件:

    class Father extends Component{
        render(){
            return (
                <div>
                    <h3>Father组件</h3>
                    <hr/>
                    <Son name='zhuxiaohang'></Son>
                </div>
            )
        }
    }
    

    子组件

    class Son extends Component{
        render(){
            return (
                <div>
                    <h4>Son组件</h4>
    
                    <p>从父组件传来一个属性 name:{this.props.name}</p>
                </div>
            )
        }
    }
    
    2.内部设置【组件自己设置】
    const Content = (props) =>{
        //函数式组件中是不需要使用this的,因为他可以通过props这个参数来接收 外部传入的属性
        //函数式组件是不能设置自己的属性的,只能接收外部传入的属性
        return <h1>{props.money}</h1>
    }
    
    
    class Father extends Component{
    
        //static 是用来定义类自己的属性
        static defaultProps = {
            zhi:'屁股上的'
        }
        //没有用static定义的属性,我们称之为实例属性
        a = 1
    
        render(){
            return (
                <div>
                    <h3>Father组件</h3>
                    <p>Father内部自己的属性:{this.props.zhi}</p>
                    <hr/>
                    <Son name='zhuxiaohang'></Son>
                    <hr/>
                    <Content money='10000'></Content>
                </div>
            )
        }
    }
    

    9.props.children

    我们知道使用组件的时候,可以嵌套。要在自定义组件的使用嵌套结构,就需要使用 props.children 。在实际的工作当中,我们几乎每天都需要用这种方式来编写组件。

    import React, { Component, Fragment } from 'react'
    import ReactDOM from 'react-dom'
    
    class Title extends Component {
      render () {
        return (
      		<h1>欢迎进入{this.props.children}的世界</h1>
      	)
      }
    }
    
    const Content = (props) => {
      return (
        <p>{props.children}</p>
      )
    }
    
    class App extends Component {
      render () {
        return (
      		<Fragment>
          	<Title>React</Title>
            <Content><i>React.js</i>是一个构建UI的库</Content>
          </Fragment>
      	)
      }
    }
    
    ReactDOM.render(
    	<App/>,
      document.getElementById('root')
    )
    

    10.使用prop-type检查props(属性验证)

    React其实是为了构建大型应用程序而生, 在一个大型应用中,根本不知道别人使用你写的组件的时候会传入什么样的参数,有可能会造成应用程序运行不了,但是不报错。为了解决这个问题,React提供了一种机制,让写组件的人可以给组件的props设定参数检查,需要安装和使用prop-types:

    $ npm i prop-types -S
    

    11.状态(state)

    状态就是组件描述某种显示情况的数据,由组件自己设置和更改,也就是说由组件自己维护,使用状态的目的就是为了在不同的状态下使组件的状态不同(自己管理)

    组件自己的状态只能自己更改

    //1.实例属性方式定义(不推荐 )
    
    class StateComponent extends Component{
        state ={					//保存属性
            msg:'hello 这是一条状态'
        }
    
        render(){
            console.log(this.state.msg) 
            return (
                <div>
                    <h4>组件的状态定义形式</h4>
                    <p>{this.state.msg}</p>
                </div>
            )
        }
    }
    
    //2.在构造函数constructor中定义 (推荐)
    
    class StateComponent extends Component{
        
            constructor(props){
                super(props)
                this.state = {
                msg:'hello 这是React组件定义的第二种形式'
            }
        
            }
        render(){
            console.log(this.state.msg)
            return (
                <div>
                    <h4>组件的状态定义形式</h4>
                    <p>{this.state.msg}</p>
                </div>
            )
        }
    }
    

    react中事件处理程序的绑定

    class StateComponent extends Component{
        
            constructor(props){
                super(props)
                this.state = {
                msg:'hello 这是React组件定义的第二种形式'
            }
        
            }
    
            //业务:点击按钮修改state
    
            //在类组件中 通过实例方法的形式来定义事件处理
            
            change(){
                console.log(this) //方法中的this是undefind
                //arg1可以是对象 也可以是函数 但是函数一定要有return
                //arg2是一个回调函数,这个回调函数一般不写
                this.setState({
                    msg:'修改后的属性值'
                })
            }
    
            //xie成箭头函数可以有效的避免this丢失的问题
            //change=()=>{this.setState({
            //msg:'箭头函数的事件处理程序'
            //})}
    
    
        render(){
            console.log(this)
            return (
                <div>
                    <h4>组件的状态定义形式</h4>
    
                    {/* react 中事件的绑定*/}
                    <button onClick = {this.change.bind(this)}> change state </button>
                    <p>{this.state.msg}</p>
                </div>
            )
        }
    }
    

  • 相关阅读:
    希望走过的路成为未来的基石
    第三次个人作业--用例图设计
    第二次结对作业
    第一次结对作业
    第二次个人编程作业
    第一次个人编程作业(更新至2020.02.07)
    Springboot vue 前后分离 跨域 Activiti6 工作流 集成代码生成器 shiro权限
    springcloud 项目源码 微服务 分布式 Activiti6 工作流 vue.js html 跨域 前后分离
    spring cloud springboot 框架源码 activiti工作流 前后分离 集成代码生成器
    java代码生成器 快速开发平台 二次开发 外包项目利器 springmvc SSM后台框架源码
  • 原文地址:https://www.cnblogs.com/xiaohanga/p/11197189.html
Copyright © 2011-2022 走看看