美文网首页
React学习笔记一--基本概念和webpack项目配置

React学习笔记一--基本概念和webpack项目配置

作者: AizawaSayo | 来源:发表于2019-09-17 11:47 被阅读0次
    ReactJS简介
    • React 起源于 Facebook 的内部项目,因为该公司对市场上所有 JavaScript MVC(Model View Controller) 框架都不满意,就决定自己写一套,用来架设 Instagram 的网站。做出来以后,发现这套东西很好用,就在2013年5月开源了
    • 由于 React 的设计思想极其独特,属于革命性创新,性能出众,代码逻辑却非常简单。所以,越来越多的人开始关注和使用,认为它可能是将来 Web 开发的主流工具。
    库(library)和框架(FrameWork):

    库:小而轻巧,只提供特定Api;优点是船小好调头,可以很方便地从一个库切换到另一个库(如jQuery到Zepto),代码几乎不需要怎么改动。
    框架:大而全,提供一整套解决方案。项目从一个框架切换到另一个是比较困难的。

    三大主流框架

    Angluar:最早(出来得最早),在印度用得比较多

    • 出来最早的前端框架,学习曲线比较陡,NG1学起来比较麻烦,NG2开始,进行了一系列的改革,也开始启用组件化了;在NG中,也支持使用TS(TypeScript)进行编程;

    Vue:最火(关注的人多),在中国用得比较多。对我我们来说,文档要友好一些。
    React:最流行(用的人多)在国外用得比较多,因为它的设计很优秀。

    React和Vue的对比

    组件化方面:

    1. 什么是模块化:是从代码的角度来进行分析的;把编程时候的业务逻辑,分割抽离到不同的模块中来进行开发,这样能够方便代码的重用,便于项目的维护和开发;
    2. 什么是组件化: 是从 UI 界面的角度来进行分析的;把一些可复用的UI元素,抽离为单独的组件;随着我们项目的开发,我们手里的组件会越来越多,到后面我们如果要实现一个页面,可能直接把现有的组件拿过来进行拼接,就能快速得到一个完整的页面, 这样方便了UI元素的重用组件是元素的集合体
    3. 组件化的好处:随着项目规模的增大,手里的组件越来越多;很方便就能把现有的组件,拼接为一个完整的页面;
    4. Vue是如何实现组件化的: 通过 .vue 文件,来创建对应的组件,一个包含以下三个部分;
      • template 结构
      • script 行为
      • style 样式
        导入使用: import Home from './Home.vue'
        浏览器不识别这样的.vue文件,所以在运行前,会把 .vue 预先编译成真正的组件;
    5. React如何实现组件化:React实现组件化的时候,并没有像.vue这样的组件模板文件;而是直接使用JS代码的形式,去创建任何你想要的组件。
    • React全部使用JS来实现一个组件,也就是说:结构、样式、业务逻辑是混合在JS里面一起编写出来的。
    • 要学习React,JS要合格;ES6 和 ES7 (async 和 await) 要会用
    移动APP开发体验比较:
    • Vue,结合 Weex 这门技术,提供了迁移到移动端App开发的体验(Weex,目前只是一个小的玩具, 并没有很成功的大案例;都是阿里自己的项目在用)
    • React,结合 ReactNative,也提供了无缝迁移到移动App的开发体验(RN用的最多,也是最火最流行的,大公司用得多);
    为什么要学习React
    1. 和Angular1相比,React设计很优秀,一切基于JS并且基于组件化开发的思想;
    2. 开发团队实力强悍,不必担心断更的情况;
    3. 社区强大,很多问题都能找到对应的解决方案;
    4. 提供了无缝转到 ReactNative 上的开发体验,让我们技术能力得到了拓展;增强了我们的核心竞争力;
    5. 很多企业中,前端项目的技术选型采用的是React.js
    React中几个核心的概念
    虚拟DOM(Virtual Document Object Model)
    • DOM的本质是什么:就是用JS表示的UI元素。浏览器中的概念,用JS对象来表示页面上的UI元素,并提供了操作 DOM 对象的API;
    • 什么是React中的虚拟DOM:是框架中的概念,是程序员用JS对象来模拟页面上的 DOM 和 DOM嵌套;
    • 为什么要实现虚拟DOM(虚拟DOM的目的):为了实现页面中, DOM 元素的高效更新
    • DOM和虚拟DOM的区别
      • DOM:由浏览器中的JS提供功能,所以我们只能人为的使用浏览器提供的固定的API来操作DOM对象;
      • 虚拟DOM:是框架中的概念,不是由浏览器提供的,而是程序员手动模拟实现的,类似于浏览器中的DOM,但是有着本质的区别。
        • 本质: 用JS对象,来模拟DOM元素和嵌套关系;
        • 目的:就是为了实现页面元素的高效更新;


          虚拟DOM的概念

    Diff算法

    • tree diff:新旧两棵DOM树,逐层对比的过程,就是Tree Diff; 每当我们从前到后,把整颗DOM逐层的节点对比完毕,必然能够找到所有需要被按需更新的元素;
    • component diff:在进行Tree Diff的时候,每一层中,组件级别的对比,叫做 Component Diff;当对比组件的时候,如果两个组件的类型相同,则暂时认为这个组件不需要被更新,如果组件的类型不同,则立即将旧组件移除,新建一个组件,替换到被移除的位置;
    • element diff:在进行组件对比的时候,如果两个组件类型相同,则需要进行元素级别的对比,如果元素内容不同,则进行相应的替换修改;
      -key:key这个属性,可以把 页面上的 DOM节点 和 虚拟DOM中的对象,做一层关联关系;
      Diff算法图
    创建基本的webpack4.x项目
    1. 运行npm init -y 快速初始化项目
    2. 在项目根目录创建src源代码目录和dist产品目录(发布的产品所在目录)
    3. 在 src 目录下创建 index.html
    4. 使用 cnpm 安装 webpack ,运行cnpm i webpack -Dcnpm i webpack-cli -D(开发依赖)
      • 如何安装 cnpm: 全局运行 npm i cnpm -g
    5. webpack.config.js配置:webpack 4.x 提供了 约定大于配置的概念;目的是为了尽量减少配置文件的体积;
      • 默认约定了:打包的入口是src -> index.js(新建一个index.js)
      • 打包的输出文件是dist -> main.js
      • 4.x 中 新增了 mode 选项(必选项),可选的值为:developmentproduction; production模式会压缩打包文件的格式。如果另外写了配置,如指定entry:''(入口路径),那么就会覆盖默认的约定
    6. 执行打包webpack,注意,如果执行后报了Cannot find module 'webpack-cli'的提示,说明需要全局安装webpack-cli,命令行运行npm i webpack-cli -g
    7. 打包完毕后dist下自动生成了打包文件main.js,将它手动引入到index.html中<script src="../dist/main.js"></script>
    8. 安装webpack-dev-server,npm i webpack-dev-server -D,快速搭建本地运行环境的工具。执行它的命令即是webpack-dev-server,在package.json里做了如下配置后,可直接执行npm run dev来替代
    "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1",
        "dev": "webpack-dev-server"
      },
    

    9.重新配置打包文件路径,webpack-dev-server会帮助我们自动编译
    webpack-dev-server打包好的main.js托管到了内存中,所在在项目根目录中看不到;出于性能上的考虑,不用反复读取物理磁盘
    但是我们可以认为,在项目根目录中,有一个不可见的main.js,然后直接在index.html中引入<script src="/main.js"></script>

    执行入口文件自动编译
    webpack-dev-server几个配置项:
    • --open是重新编译后自动打开浏览器 --open firefox(浏览器名称) 则自动用火狐浏览器打开
    • --port 3000 是自定义端口
    • --hot 热更新
    • --host 127.0.0.1 指定域名
    • --progress 显示打包的进度
    • --compress 开启gzip压缩
    "dev": "webpack-dev-server --open --port 3000 --hot --host 127.0.0.1 --progress --compress"
    

    配置完执行npm run dev,会用chorme自动打开http://127.0.0.1:3000/(注意:cnpm只能用来安装包,其他操作都需要用npm来执行)

    1. 安装html-webpack-plugin来把页面托管生成到内存中 npm i html-webpack-plugin -D
      在webpack-config.js中配置:
    const path = require('path')
    const HtmlWebPackPlugin = require('html-webpack-plugin');//导入在内存中自动生成index页面的插件
    
    //创建一个html-webpack-plugin插件的实例对象
    const htmlPlugin = new HtmlWebPackPlugin({
        template: path.join(__dirname,'./src/index.html'),//源文件
        filename: 'index.html' //生成在内存中首页的名字
    })
    
    module.exports = {
        mode:'development',//development production
        plugins:[
            htmlPlugin
        ]
    }
    

    运行后就打开的http://127.0.0.1:3000/就显示index.html的内容了

    在项目中使用 react
    1. 运行 cnpm i react react-dom -S 安装包(生产依赖)
      • react: 专门用于创建组件和虚拟DOM的,同时组件的生命周期都在这个包中
      • react-dom: 专门进行DOM操作的,最主要的应用场景,就是ReactDOM.render()
    2. index.html页面中,创建容器:
    <!--创建一个容器,将来用来渲染的虚拟DOM,将放到这个容器内显示-->
    <div id="app"></div>
    
    1. index.js中,导入包:
    import React from 'react'
    import ReactDOM from 'react-dom'
    
    1. 创建虚拟DOM元素:
    // 这是 创建虚拟DOM元素的 API    <h1 title="啊,五环" id="myh1">你比四环多一环</h1>
    //参数1:创建的元素类型,格式为字符串,表示元素的名称
    //参数2:是一个对象或null,表示当前这个DOM元素的属性
    //参数3:子节点(包括其他虚拟DOM 或 文本子节点)
    //参数n:其他子节点,即多个子节点就一直往后排,用‘,’隔开
    const myh1 = React.createElement('h1', { title: '啊,五环', id: 'myh1' }, '你比四环多一环')
    
    1. 渲染:
    // 使用ReactDOM把虚拟DOM渲染到页面上
    //参数1:要渲染的虚拟DOM元素(React.createElement创建出来的)
    //参数2:指定渲染到页面上哪个容器,是DOM元素而不是选择器,因此这里不能直接放容器元素的Id字符串,需要放一个容器的DOM对象
    ReactDOM.render(myh1, document.getElementById('app'))
    

    8. JSX语法

    什么是JSX语法:就是符合 xml 规范的 JS 语法;(语法格式相对来说,要比HTML严谨很多)

    1. 如何启用 jsx 语法?

      • 安装 babel 插件

        • 运行npm i babel-loaderbabel-loader:负责转换
          npm i @babel/core -D
          npm i @babel/plugin-proposal-object-rest-spread -D
          npm i @babel/plugin-transform-runtime -D
          npm i @babel/runtime -S
          注意:这边有个版本对应问题,否则npm run dev后会失败
          现在最新的babel-loader 是8.x版本的,要使用@babel/core,而不是babel-core了。而babel-loader 7.x对应安装babel-core 6.x。
          下面同理:
      • 安装能够识别转换jsx语法的包npm i @babel/preset-react -D

      • 根目录下添加 .babelrc 配置文件

        {
          "presets": ["@babel/preset-env", "@babel/preset-react", "mobx"],
          "plugins": [
               "@babel/plugin-proposal-object-rest-spread",
               "@babel/plugin-transform-runtime"
           ]
        }
        
      • 添加babel-loader配置项:

        module: { //要打包的第三方模块
            rules: [
              //{ test: /\.js|jsx$/, use: 'babel-loader', exclude: /node_modules/ } 等价于下面,?表示'x'是0个或者1个
              { test: /\.jsx?$/, use: 'babel-loader', exclude: /node_modules/ } 
            ]
        }
        
    2. jsx 语法的本质:并不是直接把 jsx 渲染到页面上,而是 内部先转换成了 createElement 形式,再渲染的;

    3. 在 jsx 中写入 js 表达式:在 jsx 语法中,要把 JS代码写到 { } 中。当编译引擎,在编译jsx代码的时候,如果遇到了<那么就把它当作 HTML代码去编译,如果遇到了 {} 就把 花括号内部的代码当作普通JS代码去编译;

    let a = 10;//渲染数字
    let str = '你好,中国';//渲染字符串
    let boo = true;//布尔值加入表达式
    let title = 'lala';//为属性绑定值
    const h1 = <h1>你真可爱</h1>//渲染jsx元素
    const arr =[
        <h2>这是h2</h2>,//这是js对象,不是html标签
        <h3>这是h3</h3>
    ]//渲染jsx元素数组
    //将普通字符串数组,转为jsx数组并渲染到页面上【两种方案】
    const arrStr =['毛利兰','柯南','灰原哀'];
    //方案一
    const nameArr= [];
    arrStr.forEach(item=>{//forEach没有返回值
        const temp = <h5>{item}</h5>
        nameArr.push(temp);
    })
    //数组的map方法,对数组的每一项做一个指定的操作,并返回一个新的数组,必须写return
    const resultArr = arrStr.map(item=>{
        return item +'~~'
    })
    
    //当我们需要在JSX控制的区域内写js表达式,则需要把JS代码写到{}中
    ReactDOM.render(<div>
        {a+2}<hr/>
        {str}<hr/>
        {boo?'条件为真':'条件为假'}<hr/>
        <p title={title}></p>
        {h1}
        {arr}
        <hr/>
        {nameArr}
        <hr/>
        {arrStr.map(item=>{
            return <h3>{item}</h3>
        })}
        <hr/>
        {arrStr.map(item => <h3>{item+'1'}</h3>)}
        </div>,document.getElementById('app'))
    
    1. 在 jsx 中 写注释:推荐使用{ /* 这是注释 */ };因为如果写单行注释//``,}`要换行
    2. 为 jsx 中的元素添加class类名:必须使用className 替代 class,因为 class在ES6中是一个关键字;同样,必须用htmlFor替换label的for属性
    3. 给元素绑定属性的时候用{变量}即可,如<p title={title}></p>
    4. 在JSX创建DOM的时候,所有的节点,必须有唯一的根元素进行包裹;
    5. 在 jsx 语法中,标签必须成对出现,如果是单标签,则必须自闭合!

    当 编译引擎,在编译JSX代码的时候,如果遇到了<那么就把它当作 HTML代码去编译,如果遇到了 {} 就把 花括号内部的代码当作 普通JS代码去编译;

    安装 React Developer Tools 调试工具

    React Developer Tools - Chrome 扩展下载安装地址

    相关文章

      网友评论

          本文标题:React学习笔记一--基本概念和webpack项目配置

          本文链接:https://www.haomeiwen.com/subject/bhloectx.html