React(Hello World)+webpack 迷南。 2022-03-02 13:20 199阅读 0赞 ### 建立文件夹 ### ![文件夹项目][20190320154901703.png] ### package.json ### 这是所有的包,直接复制使用`cnpm i`来下载就可以了 [一些包名babel的解释][babel] { "name": "03react", "version": "1.0.0", "description": "", "main": "webpack.config.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "dev": "webpack-dev-server --open --port 3000 --hot" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "babel-core": "^6.26.3", "babel-loader": "^7.1.5", "babel-plugin-transform-runtime": "^6.23.0", "babel-preset-env": "^1.7.0", "babel-preset-react": "^6.24.1", "babel-preset-stage-0": "^6.24.1", "css-loader": "^2.1.0", "file-loader": "^3.0.1", "html-webpack-plugin": "^3.2.0", "less": "^3.9.0", "less-loader": "^4.1.0", "node-sass": "^4.11.0", "sass-loader": "^7.1.0", "style-loader": "^0.23.1", "url-loader": "^1.1.2", "webpack": "^4.29.3", "webpack-cli": "^3.2.3", "webpack-dev-server": "^3.1.14" }, "dependencies": { "react": "^16.8.4", "react-dom": "^16.8.4" } } ### webpack的配置 ### [webpack配置文档][webpack] webpack主要就四个核心的概念:入口,出口,插件,loader const path = require('path') const htmlWepackPlugin = require('html-webpack-plugin') module.exports = { entry:path.join(__dirname,'/src/main.js'),//入口 output:{ //出口 path:path.join(__dirname,'/dist'), filename:'bundle.js' }, plugins:[ new htmlWepackPlugin({ template:path.join(__dirname,'/src/index.html'), filename:'index.html' }) ], module:{ rules:[ { test:/\.css$/,use:['style-loader','css-loader']}, { test:/\.less$/,use:['style-loader','css-loader','less-loader']}, { test:/\.scss$/,use:['style-loader','css-loader','sass-loader']}, { test: /\.(jpg|png|gif|bmp|jpeg)$/, use: 'url-loader?limit=5000&name=[hash:8]-[name].[ext]' }, { test: /\.(ttf|eot|svg|woff|woff2)$/, use: 'url-loader' }, { test: /\.jsx?$/, use: 'babel-loader', exclude: /node_modules/ }, ] } } 1. path:因为webpack是基于node的,所以我们引入node的核心模块path路径 2. entry规定入口文件; 3. output是规定出口文件,通过 output.filename 和 output.path 属性,来告诉 webpack bundle 的名称,以及我们想要 bundle 生成(emit)到哪里 4. plugins:是我们的插件,则可以用于执行范围更广的任务,里面配置的[htmlWebpackPlugin][]可以查看webpack官方文档,它的主要作用是在内存生成模板文件,并且主动帮我们注入bundle.js 5. loader 让 webpack 能够去处理那些非 JavaScript 文件(webpack 自身只理解 JavaScript)。loader 可以将所有类型的文件转换为 webpack 能够处理的有效模块,然后你就可以利用 webpack 的打包能力,对它们进行处理。test 属性,用于标识出应该被对应的 loader 进行转换的某个或某些文件。use 属性,表示进行转换时,应该使用哪个 loader。 6. 我们把webpack-dev-server直接在package.json里面配置了,所以不需要在配置,当然在webpack配置可以查看[devServer的配置][devServer] ### .babelrc文件的配置 ### [Babel 是一个 JavaScript 编译器。][Babel _ JavaScript] { "presets":["env","stage-0","react"], "plugins":["transform-runtime"] } 运行项目 cnpm i //如果是复制package文件的话,需要安装包 cnpm run dev //直接运行项目 ### 抽离介绍关于React的配置的 ### 上面关于react基本的配置都已经配置完成了,介绍一下react的配置 其中下载该包是使用JSX语法的 cnpm i babel-preset-react -D 而react和react-dom则是我们需要的 cnpm i react react-dom -S 需要在.babelrc进行JSX语法配置`{"presets":["react"]}` ### React学习 ### > React 是一个采用声明式,高效而且灵活的用来构建用户界面的框架。 [React官方文档][React] ##### Hello world ##### 1. react 这个包,是专门用来创建React组件、组件生命周期等这些东西的; 2. react-dom 里面主要封装了和 DOM 操作相关的包,比如,要把 组件渲染到页面上,React DOM 首先会比较元素内容先后的不同,而在渲染过程中只会更新改变了的部分。 3. 引入react import React from 'react' import ReactDom from 'react-dom' 1. 创建元素并渲染 * React.createElement(元素,属性,子节点) 方法创建虚拟DOM对象,接收三个及以上参数 * React.render(‘要渲染的虚拟dom’,要渲染到哪个位置) 1. 第一个例子 index.html里面写入一个容器:在此 div 中的所有内容都将由 React DOM 来管理,所以我们将其称之为 “根” DOM 节点;在此div里面写入的内容都会被替换 <div id="app"></div> 渲染dom var myH1 = React.createElement('h1', null, 'Hello World!') ReactDom.render(myH1, document.getElementById('app')) 使用浏览器查看我们,在开发是最好安装扩展React Developer Tools,便于我们对数据的观看 ![出现此效果代表配置基本没出现问题][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MTEwNTAzMA_size_16_color_FFFFFF_t_70] ### JSX ### > JSX 本身其实也是一种表达式,在编译之后呢,JSX 其实会被转化为普通的 JavaScript 对象。将它赋值给变量,当作参数传入,作为返回值 JSX内部在运行的时候,也是先把 类似于HTML 这样的标签代码, 转换为了 React.createElement 的形式;JSX需要注意的几个点: * 如果要直接使用 JSX 语法,需要先安装相关的 语法转换工具`babel-preset-react` * 当 编译引擎,在编译JSX代码的时候,如果遇到了<那么就把它当作 HTML代码去编译,如果遇到了 \{\} 就把 花括号内部的代码当作 普通JS代码去编译; * 在JSX语法内部书写代码,要写在\{\}内部;所以注释也需要写在或括号里面 * 如果要为元素添加class属性了,那么,必须写成className,因为 class在ES6中是一个关键字 * label标签的 for 属性需要替换为 htmlFor. * 和vue组件一样,所有的节点,必须有唯一的根元素进行包裹 通过一个代码来了解一下JSX语法,代码的括号可以去掉 let eleArr = [] for(var i = 0; i < 5; i++){ var p = <p className="myp" key={ i}>jsx语法的使用</p> eleArr.push(p) } var box = (<div> <label htmlFor="id">必须使用唯一的根元素包裹</label> { /* 这是我的注释,需要加花括号 */} { eleArr} </div>) ReactDom.render(box, document.getElementById('app')) ![结果渲染如图][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MTEwNTAzMA_size_16_color_FFFFFF_t_70 1] ##### 无状态组件 ##### 用构造函数创建出来的组件:专业的名字叫做“无状态组件”;也就是无state * 我们在main.js使用构造函数 function Hello(){ return <div> <h1>无状态组件</h1> </div> } ReactDom.render(<Hello></Hello>, document.getElementById('app')) ![这是解析的结构][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MTEwNTAzMA_size_16_color_FFFFFF_t_70 2] React在解析所有的标签,是以首字母来区分的,如果首字母大写,则按照组件的形式,如果首字母小写,则按照html去解析,这个结果解析成`<div id="app"><hello></hello></div>` ReactDom.render(<hello></hello>, document.getElementById('app')) 使用JSX独立的组件,在src新建compones文件夹,并新建一个HELLO.JSX文件,在main.js引入 import React from 'react' function Hello() { return <div> <h1>这是单独一个组件</h1> </div> } // 把创建的组件暴露出去 export default Hello import Hello from './components/Hello.jsx' ReactDom.render(<Hello></Hello>, document.getElementById('app')) ##### 有状态组件 ##### 使用有状态的组件,即使用class关键字创建出来的组件,有state属性 class Welcome extends React.Component { render() { return <h1>Hello</h1>; } } ReactDom.render(<Welcome></Welcome>, document.getElementById('app')) 使用JSX独立的组件,在src新建compones文件夹,并新建一个HELLO.JSX文件,在main.js引入;从这个例子可可以看出有状态组件和无状态组件的区别 import React from 'react' export default class List extends React.Component { constructor(props) { super(props) this.state = { login: [ { user: '1', content: '1' }, { user: '2', content: '2' }, { user: '3', content: '3' }, { user: '4', content: '4' }, { user: '5', content: '5' } ] } } render() { return <div> <h1 className="title">评论列表案例</h1> <ul> { this.state.login.map((item, i) => { return <li key={ i}><a href="#">{ item.user}</a><span>{ item.content}</span></li> })} </ul> </div> } } 1. 我们构造函数继承是改变其原型链,这里extends是实现继承;前面是子类后面是父类 2. 使用extends继承,必须有super();表示对构造器的引用 3. map是一个方法;map() 方法创建一个新数组,其结果是该数组中的每个元素都调用一个提供的函数后返回的结果。 4. 浏览器每秒钟调用tick()方法;通过调用 setState() ,React 知道状态已经改变,并再次调用 render() 方法来确定屏幕上应当显示什么。 import List from './components/Welcome1.jsx' ReactDom.render(<List></List>, document.getElementById('app')) ### 生命周期函数 ### ###### 虚拟DOM ###### DOM的本质就是用UI创建的对象;虚拟DOM(virtul DOM)就是我们程序员手动模拟实现的,在这里,虚拟DOM通过JS的Object对象模拟DOM中的真实节点对象,再通过特定的render方法将其渲染成真实的DOM节点。 ##### Diff算法 ##### React最值得称道的就是虚拟DOM与Diff算法的结合,让用户可以无所顾忌的刷新页面;Diff算法会帮助我们计算出虚拟DOM真正变化的部分;并只对DOM进行实际的操作,而非渲染整个页面。Diff算法:新旧DOM树,逐层对比的方式(tree)----在对比每一层的时候,组件之间的对比(component)----在组件中,每个元素之间也要进行对比(element) ### 对生命周期函数做基础了解 ### ![生命周期函数][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MTEwNTAzMA_size_16_color_FFFFFF_t_70 3] 1. componentsWillMount:组件将要挂载到页面上;即虚拟DOM还没有被创建,同时还没有挂载到页面上。还没有起床 2. render:就已经开始要渲染虚拟dom了,当我们的render执行完;我们的虚拟DOM在内存创建好了,但没有挂载到页面上。已经起床,执行完了刷牙,还没有上班工作 3. componentsDidMount:我们的state数据,和内存中虚拟Dom已经保持一致了。到这里组件创建的阶段已经完毕,组件已经完整挂载到页面中。上班工作 ### 总结 ### [React官方文档][React] [单双向数据流][Link 1] [更好的理解虚拟DOM][DOM] [更好了解ReactJS][ReactJS] [Diff算法][Diff] [20190320154901703.png]: /images/20220302/1f73055eff2240819c36af94f5874b50.png [babel]: https://www.webpackjs.com/loaders/babel-loader/#%E5%AE%89%E8%A3%85 [webpack]: https://www.webpackjs.com/concepts/ [htmlWebpackPlugin]: https://webpack.js.org/plugins/html-webpack-plugin/#root [devServer]: https://webpack.js.org/configuration/dev-server/#root [Babel _ JavaScript]: https://www.babeljs.cn/ [React]: https://react.docschina.org/docs/hello-world.html [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MTEwNTAzMA_size_16_color_FFFFFF_t_70]: /images/20220302/da8565b05366478c952eb37621aa7515.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MTEwNTAzMA_size_16_color_FFFFFF_t_70 1]: /images/20220302/808e587993e64fe0877b5f0f36b81c6a.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MTEwNTAzMA_size_16_color_FFFFFF_t_70 2]: /images/20220302/03e8524eac824b57a586eec7b2b7f936.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MTEwNTAzMA_size_16_color_FFFFFF_t_70 3]: /images/20220302/fddc10560f0d45d1a2961b4d93da860d.png [Link 1]: https://segmentfault.com/q/1010000005876655/a-1020000005876751 [DOM]: https://www.zhihu.com/question/29504639?sort=created [ReactJS]: http://www.cocoachina.com/webapp/20150721/12692.html [Diff]: https://infoq.cn/article/react-dom-diff?from=timeline&isappinstalled=0
还没有评论,来说两句吧...