zoukankan      html  css  js  c++  java
  • 前端笔记之React(一)初识React&组件&JSX语法

    一、React项目起步配置

    官网:https://reactjs.org/

    文档:https://reactjs.org/docs/hello-world.html

    中文:http://react.css88.com/

    2013年被开源,2014年在中国彻底火爆。

     

    ReactCMD架构,现阶段需要webpack打包

    npm install -g webpack@4.9.1

    必须安装以下三个依赖:

    npm install --save-dev babel-core babel-loader babel-preset-env

    React采用jsx语法,JSX语法是什么?

    就是全球唯一标准的JavaScriptXHTML结合开发最优雅的语法。

    浏览器不识别JSX语法,所以需要babelJSX语法翻译,babel要装一个新的preset

    npm install --save-dev babel-preset-react

    安装完依赖,修改webpack.congif.js文件中的preset配置:

    const path = require('path');
    module.exports = {
        entry: "./www/app/main",
        output : {
            path: path.resolve(__dirname, "www/dist"),
            filename : "bundle.js",
        },
        watch:true,
        mode : "development",
        module: {
            rules: [
                {
                    test: /.js?$/, 
                    include: [path.resolve(__dirname, "www/app")],
                    exclude: [path.resolve(__dirname, "node_modules")], 
                    loader : "babel-loader",
                    options: { presets: ["env","react"] }, //要翻译的语法 
                }
            ]
        }
    }

    还要安装reactreact-dom包:

    npm install --save react react-dom

     react是核心库

     react-dom提供了与DOM操作的功能库

    注意:项目文件夹名字千万不要叫react,很坑。

     

    index.html上放“挂载点”的盒子:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8" />
        <title>Document</title>
    </head>
    <body>
        <div id="app"></div>
    </body>
    <script type="text/javascript" src="dist/bundle.js"></script>
    </html>

    app/main.js

    import React from "react";
    import ReactDOM from "react-dom";
    
    ReactDOM.render(
        <div>
            <h1>你好,我是react,来自Facebook公司</h1>
        </div>,
        document.getElementById('app')
    );
    示例代码

    运行webpack,直接打开页面:

     React是所有react项目的入口

     React-dom负责react Element添加到HTML页面的挂载点上

    react-dom 这个包提供了你的app最高等级的API,提供了元素的挂载和上树的方法

    render() 接收两个参数,第一个参数是react元素,第二个参数是挂载点,用来让react元素进行挂载。

    Vue在写实例,而React在写类(构造函数)。


    二、组件

    组件叫component”,就是HTMLCSSJS行为的一个封装。

    Vue中的组件是一个.vue文件(其实是普通的JSON对象),React中,组件是一个类(构造函数)。

    2.1类式组件

    创建App.js文件,这是一个组件,必须按照要求写标准壳,这个壳我们叫rcc壳“react class component”,react的类式组件:

    import React from "react";
    // 默认暴露一个构造函数(类组件)
    export default class App extends React.Component{
        constructor(){
            super();
        }
        render(){
            return <div>
                <h1>我是App组件!</h1>
            </div>
        }
    }

    注意:

    1)这个文件的默认暴露就是一个类,这个类的类名必须和文件名相同。
    2)文件名和类名的首字母必须大写!React中组件的合法名字首字母必须是大写字母。
    3)这个类必须继承自React.Component类,也就是说,rcc壳必须是extends React.Component的写法。
    4)这个类必须有构造器constructor,构造器里面必须调用超类的构造器,super();
    5)这个类必须有render函数,render函数中必须return一个jsx对象。而且这个jsx对象必须被唯一的标签包裹。

    在main.js主文件中引入组件,然后用自定义标签:

    import React from "react";
    import ReactDOM from "react-dom";
    // 引入组件
    import App from "./App.js";
    
    ReactDOM.render(
        <div>
            <App></App>
            <h1>你好,我是react,来自Facebook公司</h1>
        </div>,
        document.getElementById("app")
    );

    注意:

    引入的组件必须路径以./开头

    组件要使用,就将这个组件的名字(类名、文件名)进行标签化即可

    原理就是这个App类在被实例化。

    因为类的名字是大写字母,所以所有的自定义组件标签名字一定是大写字母开头的

    react中,所有以大写字母开头的都是组件,而不是标签。

     

    ReactDOM.render(jsx,根的挂载点)

    ReactDOM只能出现一次,但是非常厉害,可以和HTML结合

     

    jsx,现在一律在js文件夹中开发,并不是传统放html开发

    HTMLCSSJS都被构建到bundle.js文件夹中。

    安装以下插件,输入rcc即可快速生成一个组件的语法:

     


    2.2组件可以多层嵌套

    main.js文件中引入App.js组件,App组件里面的render函数还可以引入其他组件。

    components/Child.js

    import React from "react";
    export default class Child extends React.Component {
        constructor() {
            super();
        }
        render() {
            return <div>
                <h1>我是Child子组件!</h1>
            </div>
        }
    }

    App父组件中引入:

    import React from "react";
    import Child from "./components/Child";
    // 默认暴露一个构造函数(类组件)
    export default class App extends React.Component {
        constructor() {
            super();
        }
        render() {
            return <div>
                <h1>我是App组件!</h1>
                <Child></Child>
                <Child></Child>
                <Child></Child>
            </div>
        }
    }

    简单的说:在react中做一个组件:

    第一步:创建一个类并暴露

    第二步:引入这个类,然后用这个类的类名当做组件的标签(实例化)


    2.3函数式组件

    一个函数,如果是大写字母开头,并且return一个React Element就是一个组件。

    比如App.js组件中,创建一个Child1的函数,这个函数直接返回JSX语法的React Element,此时这个函数就是组件,这个函数直接成为自定义标签,就可以用了。

    import React from "react";
    import Child from "./components/Child";
    // 默认暴露一个构造函数(类组件)
    
    //定义一个自定义的函数组件
    const Child1 = ()=> <div>
        <h1>我是Child1函数式组件!</h1>
    </div>
    
    export default class App extends React.Component {
        constructor() {
            super();
        }
        render() {
            return <div>
                <h1>我是App组件!</h1>
                <Child></Child>
                <Child1></Child1>
            </div>
        }
    }

    注意:

    1render是一个函数,所以函数里面当然可以定义另一个函数。我们用const来定义一个箭头函数,这个箭头函数的名字,必须首字母大写。react中所有标签名字是首字母大写的,将被判定为我们自己的组件。

    2)这个函数里面return了一个jsx对象,注意,不要加引号。初学者会有很多不适。

    3)这个组件也是通过“标签”的形式来上树的!

    4)函数式组件比类组件差很多功能很多,后面会说。

    5)至于什么时候用什么组件、圆括号中能不能传入参数,后面会说。

    函数式组件有个缺点,没有state,没有生命周期。


    三、JSX语法

    所有对React不适应,都是JSX语法造成的,JSX语法淡化了JSHTML之间的“边界”。

    3.1标签必须合理嵌套

    错误的:

    import React from "react";
    import ReactDOM from "react-dom";
    // 引入组件
    import App from "./App.js"
    ReactDOM.render(
        <App></App>
        <App></App>
        <App></App>
      ,
      document.getElementById('app')
    );

    有多个组件,必须有一个标签包裹所有组件:

    import React from "react";
    import ReactDOM from "react-dom";
    // 引入组件
    import App from "./App.js"
    ReactDOM.render(
      <div>
         <App></App>
         <App></App>
         <App></App>
      </div>
      ,
      document.getElementById('app')
    );

    比如table不能直接嵌套tr,必须要有tbody

    import React from "react";
    export default class App extends React.Component {
        constructor() {
            super();
        }
        render() {
            return <div>
                <table>
                    <tbody>
                        <tr>
                            <td>1</td>
                            <td>2</td>
                        </tr>
                    </tbody>
                </table>
            </div>
        }
    }

    比如这样也是错误的:

     <p><div>111</div></p>


    3.2 return不能换行

    return后面直接跟着div,不能换行

     

    如果想换行,必须加圆括号包裹。

    import React from "react";
    export default class App extends React.Component {
        constructor() {
            super();
        }
        render() {
            return (
                <div>
                    <h1>我是App组件</h1>
                </div>
            )
        }
    }

    3.3标签必须严格封闭

    因为jsx语法被babel-loader翻译(babel-perset-react),所以标签必须严格封闭,否则翻译会报错。

    错误的:
    <br>
    <hr>
    
    正确的:
    <br/>
    <hr/>
    
    错误的:
    <input type="text">
    
    正确的:
    <input type="text" />

    3.4所有的类名必须用className表示

    因为JSclass是关键字,所以类名必须用className

    错误的

    <div class="box"></div>

    正确的:

     <div className="box"></div>

    for要用htmlFor代替:

    错误的:
     <label for=""></label>
    正确的:
     <label htmlFor=""></label>

    3.5插值基础(重点)

    可以在jsx内部,用单个“{}”大括号进行一些js表达式的插入,我们叫做插值。

    {} 只能出现在React element中,简化了连字符串工作。

    import React from "react";
    export default class App extends React.Component {
        constructor() {
            super();
        }
        render() {
            const year = 10000;
            const pingfang = (n)=>{
                return n * n
            }
            const arr = [1000,2000,3000,4000]
            return <div>
                <h1>{5000 * 2}年</h1>
                <h1>{year}年</h1>
                <h1>{pingfang(100)}年</h1>
                <h1>{arr.reduce((a,b)=>a + b)}年</h1>
                <h1>{parseInt(Math.random() * 100)}年</h1>
                <h1>{3 > 8 ? 10000 : 1}年</h1>
            </div>
        }
    }

    不能出现的语法:

    不能定义变量:

    <h1>{var a = 100}</h1>

    不能定义函数:

    <h1>{function name(){}}</h1>

    应该在return之前定义:

    render() {
        const pingfang = (n)=> n * n
        return (
            <div>
                <h1>我爱你{pingfang(100)}年</h1>
            </div>
        )
    }

    不能出现for循环、if语句、whiledo语句:

    <h1>{for(var i = 0;i < 100;i++){}}</h1>

    JSX不能出现对象(JSON)。

    render() {
        const obj = {"a":100,"b":200}
        return (
            <div>
                <h1>{obj}</h1>
            </div>
        )
    }

    此时会报错,如果要在页面显示JSON,应该:

    render() {
        const obj = {"a":100,"b":200}
        return (
            <div>
                <h1>{JSON.stringify(obj)}</h1>
            </div>
        )
    }

    3.6插值高级

    JSX表达式不能出现引号中,比如有一个变量

    render() {
        const picUrl = "baby1.jpg"
        return <div>
            <img src="images/{picUrl}.jpg" />
        </div>
    }

    正确的应该先写在外层的{}

    render() {
        const picUrl = "baby1";
        const tip = '这是黄晓明老婆';
        const url = 'http://www.baidu.com/'
        return <div>
            <img src={"images/" + picUrl + ".jpg"} />
            <img src={`images/${picUrl}.jpg`} title={tip} />
            <a href={url}>去百度</a>
        </div>
    }

    内嵌样式要求这样的语法插值:

    style后面直接跟着{{}},没有引号,{{}}中是JSON,所有的属性名都是驼峰命名法:

    <div style={{"width":"100px","height":"100px","backgroundColor":"red"}}></div>

    react的程序,可以进行合理的换行

    <div style={{
        "width":"100px",
        "height":"100px",
        "backgroundColor":"red"
    }}>
    </div>

    3.7 jsx中数组内容会被自动展开(重点)

    此时你心里可能有一万个草泥马,这是什么鬼,数组怎么能不加引号呢?因为是JSX语法规定。

    import React from "react";
    export default class App extends React.Component {
        constructor() {
            super();
        }
        render() {
            const arr = [
                <li key="0">牛奶</li>,
                <li key="1">咖啡</li>,
                <li key="2">奶茶</li>,
                <li key="3">可乐</li>
            ]
            return <div>
                 <ul>
                     {arr}
                 </ul>
            </div>
        }
    }

    只要你在{}放一个数组,此时这个数组不用循环了,就会自动被展开。

    所有的数组元素,必须加上key属性,否则报错

     

    注意:

    数组有4项,每项都是jsx元素,不需要加引号

    每项必须要有不同的key属性,这是react要求的

    数组直接{arr}就可以了,也不需要写循环遍历语句。

    数据和DOM怎么进行模板的循环:

    arr数组中,没有任何的标签,只是数据:此时就要在{}中用map来映射一个新的数组

    import React from "react";
    export default class App extends React.Component {
        constructor() {
            super();
        }
        render() {
            const arr = ["牛奶","咖啡","奶茶","可乐"]
            return <div>
                 <ul>
                     {arr.map((item,index)=>{
                        return <li key={index}>{item}</li>
                     })}
                 </ul>
            </div>
        }
    }
    示例代码

    映射出一个表格:

    import React from "react";
    export default class App extends React.Component {
        constructor() {
            super();
        }
        render() {
            const arr = [
                {"id":1,"name":"小明","age":12,"sex":"男"},
                {"id":2,"name":"小红","age":13,"sex":"女"},
                {"id":3,"name":"小刚","age":14,"sex":"男"},
                {"id":4,"name":"小白","age":15,"sex":"男"}
            ]
            return <div>
                 <table>
                     <tbody>
                        {
                            arr.map(item=>{
                                return <tr key={item.id}>
                                    <td>{item.id}</td>
                                    <td>{item.name}</td>
                                    <td>{item.age}</td>
                                    <td>{item.sex}</td>
                                </tr>
                            })
                        }
                     </tbody>
                 </table>
            </div>
        }
    }
    示例代码

    3.8九九乘法表

    学习的是二维数组的展开

    我们先有一个套路,准备一个外层的数组,然后外层的循环中push内部数组:

    import React from "react";
    export default class App extends React.Component {
        //构造函数
        constructor() {
            super();
        }
        render() {
            var arr = [];
            for(var i = 1;i <= 9;i++){
                var temp = []
                for(var j = 1; j <= i; j++) {
                    temp.push(<td key={j}> {i} * {j} = {i*j} </td>)
                }
                arr.push(<tr key={i}>{temp}</tr>)
            }
            return (
                <div>
                     <table>
                        <tbody>
                            {arr}
                        </tbody>
                     </table>
                </div>
            )
        }
    };
    实力代码

    3.9日历

    日历的原理,决定一个日历的画风,有三要素:

     这个月第一天是星期几;

     这个月有几天;

     上个月有几天;

     

    要知道2018年5月5日是星期几:
    new Date(2018,5-1,5).getDay()
    
    要知道2018年5月有几天:
    new Date(2018,5,0).getDate()

     

    本月有几天,等价于下个月前一天是几号,所以下个月的0号,就是本月的最后一天。

     

    给日历加农历:

    npm install --save solarlunar
    import React from "react";
    import solarLunar from 'solarLunar';
    export default class App extends React.Component {
        //构造函数
        constructor() {
            super();
        }
        render() {
            var year = 2018;
            var month = 8; //是人类的月份,而不是计算机的
            //本月第一天是星期几
            var TheMonthFirstDay = new Date(year,month - 1,1).getDay();
            //本月共几天
            var TheMonthDays = new Date(year,month,0).getDate();
            //上个月共几天
            var prevMonthDays = new Date(year,month-1,0).getDate();
    
            var arr = [];
            
            //上个月的尾巴,本月第一天星期几就有几天上个月的尾巴
            while (TheMonthFirstDay--){
                arr.unshift(prevMonthDays--)
            }
    
            // 本月放进数组
            var count = 1;
            while(TheMonthDays--){
                arr.push(count++);
            }
            // 下个月的前有多少天,要补齐42天
            var nextCount = 1;
            while ( arr.length != 42){
                arr.push(nextCount++);
            }
            console.log(arr)
            //接下来要用这个一维数组集合JSX语法,展开为二维数组
            const showTable = ()=>{
                var domArr = [];
                for(var i = 0; i < arr.length / 7; i++){
                    domArr.push(
                        <tr key={i}>
                            {
                                arr.slice(i * 7, i * 7 + 7).map(item=>{
                                    var n = solarLunar.solar2lunar(year, month, item);
                                    return <td key={item}>
                                        {item}
                                        <br/>
                                        {n.term || n.dayCn}
                                    </td>
                                })
                            }
                        </tr>      
                    )
                }
                return domArr;
            }
    
            return (
                <div>
                     <table>
                         <thead>
                             <tr>
                                 <th>日</th>
                                 <th>一</th>
                                 <th>二</th>
                                 <th>三</th>
                                 <th>四</th>
                                 <th>五</th>
                                 <th>六</th>
                             </tr>
                         </thead>
                         <tbody>
                            {showTable()}
                         </tbody>
                     </table>
                </div>
            )
        }
    };

  • 相关阅读:
    MagicAjax简单介绍(转)
    .net中RegisterStartupScript与RegisterClientScriptBlock的区别
    改变你一生的五句话 (转)
    苏州园林年卡 办理与使用 附 苏州园林门票价格
    常见的 ASP.NET 2.0 转换问题和解决方案(转)
    .net新手须知
    AJAX开发简略 (转)
    magicajax为什么不能提交? magicajax的一个bug
    所谓:有实际开发工作经验 (转)
    解读60 70 80年代职场人
  • 原文地址:https://www.cnblogs.com/rope/p/10740792.html
Copyright © 2011-2022 走看看